From 780a7df760d45b8bd386be425ab5c2da0b1a48f6 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Thu, 23 Oct 2025 04:25:23 -0700 Subject: [PATCH 001/189] Fix warnings in more examples. (#5292) --- examples/core/core_text_file_loading.c | 16 ++++++++-------- examples/shapes/shapes_clock_of_clocks.c | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/core/core_text_file_loading.c b/examples/core/core_text_file_loading.c index 033fd4dc6..ed48f7d36 100644 --- a/examples/core/core_text_file_loading.c +++ b/examples/core/core_text_file_loading.c @@ -88,16 +88,16 @@ int main(void) for (int i = 0; i < lineCount; i++) { - Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], fontSize, 2); - textHeight += size.y + 10; + Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2); + textHeight += (int)size.y + 10; } // A simple scrollbar on the side to show how far we have red into the file Rectangle scrollBar = { - .x = screenWidth - 5, + .x = (float)screenWidth - 5, .y = 0, .width = 5, - .height = screenHeight*100/(textHeight - screenHeight) // Scrollbar height is just a percentage + .height = screenHeight*100.0f/(textHeight - screenHeight) // Scrollbar height is just a percentage }; SetTargetFPS(60); @@ -115,10 +115,10 @@ int main(void) // Ensuring that the camera does not scroll past all text if (cam.target.y > textHeight - screenHeight + textTop) - cam.target.y = textHeight - screenHeight + textTop; + cam.target.y = (float)textHeight - screenHeight + textTop; // Computing the position of the scrollBar depending on the percentage of text covered - scrollBar.y = Lerp(textTop, screenHeight - scrollBar.height, (cam.target.y - textTop)/(textHeight - screenHeight)); + scrollBar.y = Lerp((float)textTop, (float)screenHeight - scrollBar.height, (float)(cam.target.y - textTop)/(textHeight - screenHeight)); //---------------------------------------------------------------------------------- // Draw @@ -132,13 +132,13 @@ int main(void) for (int i = 0, t = textTop; i < lineCount; i++) { // Each time we go through and calculate the height of the text to move the cursor appropriately - Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], fontSize, 2); + Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2); DrawText(lines[i], 10, t, fontSize, RED); // Inserting extra space for real newlines, // wrapped lines are rendered closer together - t += size.y + 10; + t += (int)size.y + 10; } EndMode2D(); diff --git a/examples/shapes/shapes_clock_of_clocks.c b/examples/shapes/shapes_clock_of_clocks.c index 493e53b5e..3fc24aa92 100644 --- a/examples/shapes/shapes_clock_of_clocks.c +++ b/examples/shapes/shapes_clock_of_clocks.c @@ -14,6 +14,9 @@ * Copyright (c) 2025 JP Mortiboys (@themushroompirates) * ********************************************************************************************/ +#if defined(WIN32) +#define _CRT_SECURE_NO_WARNINGS +#endif #include "raylib.h" From 04930c5132f900be39b21a6b89685f0f75f2d0e5 Mon Sep 17 00:00:00 2001 From: Diogo Hartuiq Debarba <35925088+diogohartuiqdebarba@users.noreply.github.com> Date: Thu, 23 Oct 2025 08:27:28 -0300 Subject: [PATCH 002/189] Fix typo in RPI cross-compiler variable name (#5295) --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 0d4ca9ac7..4369d8084 100644 --- a/src/Makefile +++ b/src/Makefile @@ -283,7 +283,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) endif endif ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) - ifeq ($(USE_RPI_CROSS_COMPILER),TRUE) + ifeq ($(USE_RPI_CROSSCOMPILER),TRUE) # Define RPI cross-compiler #CC = armv6j-hardfloat-linux-gnueabi-gcc CC = $(RPI_TOOLCHAIN)/bin/$(RPI_TOOLCHAIN_NAME)-gcc From 93c5dc3b5f67b5c221cd93f379f9b31ba15b8c94 Mon Sep 17 00:00:00 2001 From: alexgb0 Date: Thu, 23 Oct 2025 17:28:00 +0200 Subject: [PATCH 003/189] [rlsw] c++ support (#5291) * rlsw c++ support * rslw formatting fixes --- src/external/rlsw.h | 141 ++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 64 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 904bf1210..aa4803265 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -156,6 +156,12 @@ #define SW_CLIP_EPSILON 1e-4f #endif +#ifdef __cplusplus + #define CURLY_INIT(name) name +#else + #define CURLY_INIT(name) (name) +#endif + //---------------------------------------------------------------------------------- // OpenGL Compatibility Types //---------------------------------------------------------------------------------- @@ -1699,7 +1705,7 @@ static inline void sw_framebuffer_blit_to_##name( int xSrc, int ySrc, int wSrc, int hSrc, \ DST_PTR_T *dst) \ { \ - const uint8_t *srcBase = RLSW.framebuffer.color; \ + const uint8_t *srcBase = (uint8_t*)RLSW.framebuffer.color; \ int fbWidth = RLSW.framebuffer.width; \ \ uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ @@ -1722,7 +1728,7 @@ static inline void sw_framebuffer_blit_to_##name( int xSrc, int ySrc, int wSrc, int hSrc, \ DST_PTR_T *dst) \ { \ - const uint8_t *srcBase = RLSW.framebuffer.color; \ + const uint8_t *srcBase = (uint8_t *)RLSW.framebuffer.color; \ int fbWidth = RLSW.framebuffer.width; \ \ uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ @@ -2583,6 +2589,15 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, /* Scanline rasterization */ \ for (int x = xStart; x < xEnd; x++) \ { \ + /* Pixel color computation */ \ + float wRcp = 1.0f/w; \ + float srcColor[4] = { \ + color[0]*wRcp, \ + color[1]*wRcp, \ + color[2]*wRcp, \ + color[3]*wRcp \ + }; \ + \ /* Test and write depth */ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -2593,15 +2608,6 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, \ sw_framebuffer_write_depth(dptr, z); \ \ - /* Pixel color computation */ \ - float wRcp = 1.0f/w; \ - float srcColor[4] = { \ - color[0]*wRcp, \ - color[1]*wRcp, \ - color[2]*wRcp, \ - color[3]*wRcp \ - }; \ - \ if (ENABLE_TEXTURE) \ { \ float texColor[4]; \ @@ -3063,6 +3069,14 @@ static inline void FUNC_NAME(void) /* Scanline rasterization */ \ for (int x = xMin; x < xMax; x++) \ { \ + /* Pixel color computation */ \ + float srcColor[4] = { \ + color[0], \ + color[1], \ + color[2], \ + color[3] \ + }; \ + \ /* Test and write depth */ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -3073,14 +3087,6 @@ static inline void FUNC_NAME(void) \ sw_framebuffer_write_depth(dptr, z); \ \ - /* Pixel color computation */ \ - float srcColor[4] = { \ - color[0], \ - color[1], \ - color[2], \ - color[3] \ - }; \ - \ if (ENABLE_TEXTURE) \ { \ float texColor[4]; \ @@ -3361,6 +3367,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ { \ int offset = (y1 + i)*fbWidth + (x1 + (j >> 16)); \ void *dptr = sw_framebuffer_get_depth_addr(dBuffer, offset); \ + void *cptr; \ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -3370,7 +3377,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ \ sw_framebuffer_write_depth(dptr, z); \ \ - void *cptr = sw_framebuffer_get_color_addr(cBuffer, offset); \ + cptr = sw_framebuffer_get_color_addr(cBuffer, offset); \ \ if (ENABLE_COLOR_BLEND) \ { \ @@ -3397,6 +3404,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ { \ int offset = (y1 + (j >> 16))*fbWidth + (x1 + i); \ void *dptr = sw_framebuffer_get_depth_addr(dBuffer, offset); \ + void *cptr; \ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -3406,7 +3414,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ \ sw_framebuffer_write_depth(dptr, z); \ \ - void *cptr = sw_framebuffer_get_color_addr(cBuffer, offset); \ + cptr = sw_framebuffer_get_color_addr(cBuffer, offset); \ \ if (ENABLE_COLOR_BLEND) \ { \ @@ -3687,9 +3695,14 @@ static inline void sw_poly_line_render(void) const sw_vertex_t *vertices = RLSW.vertexBuffer; int cm1 = RLSW.vertexCounter - 1; - for (int i = 0; i < cm1; i++) sw_line_render((sw_vertex_t[2]){ vertices[i], vertices[i + 1] }); + for (int i = 0; i < cm1; i++) + { + sw_vertex_t verts[2] = { vertices[i], vertices[i + 1] }; + sw_line_render(verts); + } - sw_line_render((sw_vertex_t[2]){ vertices[cm1], vertices[0] }); + sw_vertex_t verts[2] = { vertices[cm1], vertices[0] }; + sw_line_render(verts); } static inline void sw_poly_fill_render(void) @@ -3817,10 +3830,10 @@ bool swInit(int w, int h) swViewport(0, 0, w, h); swScissor(0, 0, w, h); - RLSW.loadedTextures = SW_MALLOC(SW_MAX_TEXTURES*sizeof(sw_texture_t)); + RLSW.loadedTextures = (sw_texture_t *)SW_MALLOC(SW_MAX_TEXTURES*sizeof(sw_texture_t)); if (RLSW.loadedTextures == NULL) { swClose(); return false; } - RLSW.freeTextureIds = SW_MALLOC(SW_MAX_TEXTURES*sizeof(uint32_t)); + RLSW.freeTextureIds = (uint32_t *)SW_MALLOC(SW_MAX_TEXTURES*sizeof(uint32_t)); if (RLSW.loadedTextures == NULL) { swClose(); return false; } RLSW.clearColor[0] = 0.0f; @@ -3898,7 +3911,7 @@ void swClose(void) SW_FREE(RLSW.loadedTextures); SW_FREE(RLSW.freeTextureIds); - RLSW = (sw_context_t) { 0 }; + RLSW = CURLY_INIT(sw_context_t) { 0 }; } bool swResizeFramebuffer(int w, int h) @@ -3908,7 +3921,7 @@ bool swResizeFramebuffer(int w, int h) void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, void *pixels) { - sw_pixelformat_t pFormat = sw_get_pixel_format(format, type); + sw_pixelformat_t pFormat = (sw_pixelformat_t)sw_get_pixel_format(format, type); if (w <= 0) { @@ -3930,26 +3943,26 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, switch (pFormat) { - case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_framebuffer_copy_to_GRAYALPHA(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: sw_framebuffer_copy_to_GRAYALPHA(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5: sw_framebuffer_copy_to_R5G6B5(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: sw_framebuffer_copy_to_R8G8B8(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_copy_to_R5G5B5A1(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_copy_to_R4G4B4A4(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_copy_to_R8G8B8A8(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_framebuffer_copy_to_R32(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_framebuffer_copy_to_R32G32B32(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_framebuffer_copy_to_R32G32B32A32(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_framebuffer_copy_to_R16(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_framebuffer_copy_to_R16G16B16(x, y, w, h, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_framebuffer_copy_to_R16G16B16A16(x, y, w, h, pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_framebuffer_copy_to_GRAYALPHA(x, y, w, h, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: sw_framebuffer_copy_to_GRAYALPHA(x, y, w, h, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5: sw_framebuffer_copy_to_R5G6B5(x, y, w, h, (uint16_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: sw_framebuffer_copy_to_R8G8B8(x, y, w, h, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_copy_to_R5G5B5A1(x, y, w, h, (uint16_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_copy_to_R4G4B4A4(x, y, w, h, (uint16_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_copy_to_R8G8B8A8(x, y, w, h, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_framebuffer_copy_to_R32(x, y, w, h, (float *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_framebuffer_copy_to_R32G32B32(x, y, w, h, (float *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_framebuffer_copy_to_R32G32B32A32(x, y, w, h, (float *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_framebuffer_copy_to_R16(x, y, w, h, (sw_half_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_framebuffer_copy_to_R16G16B16(x, y, w, h, (sw_half_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_framebuffer_copy_to_R16G16B16A16(x, y, w, h, (sw_half_t *)pixels); break; default: RLSW.errCode = SW_INVALID_ENUM; break; } } void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySrc, int wSrc, int hSrc, SWformat format, SWtype type, void *pixels) { - sw_pixelformat_t pFormat = sw_get_pixel_format(format, type); + sw_pixelformat_t pFormat = (sw_pixelformat_t)sw_get_pixel_format(format, type); if (wSrc <= 0) { @@ -3971,19 +3984,19 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr switch (pFormat) { - case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_framebuffer_blit_to_GRAYALPHA(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: sw_framebuffer_blit_to_GRAYALPHA(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5: sw_framebuffer_blit_to_R5G6B5(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: sw_framebuffer_blit_to_R8G8B8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_blit_to_R5G5B5A1(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_blit_to_R4G4B4A4(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_blit_to_R8G8B8A8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_framebuffer_blit_to_R32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_framebuffer_blit_to_R32G32B32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_framebuffer_blit_to_R32G32B32A32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_framebuffer_blit_to_R16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_framebuffer_blit_to_R16G16B16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_framebuffer_blit_to_R16G16B16A16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_framebuffer_blit_to_GRAYALPHA(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: sw_framebuffer_blit_to_GRAYALPHA(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5: sw_framebuffer_blit_to_R5G6B5(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: sw_framebuffer_blit_to_R8G8B8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_blit_to_R5G5B5A1(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_blit_to_R4G4B4A4(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_blit_to_R8G8B8A8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_framebuffer_blit_to_R32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_framebuffer_blit_to_R32G32B32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (float *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_framebuffer_blit_to_R32G32B32A32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (float*)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_framebuffer_blit_to_R16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (sw_half_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_framebuffer_blit_to_R16G16B16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (sw_half_t *)pixels); break; + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_framebuffer_blit_to_R16G16B16A16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (sw_half_t *)pixels); break; default: RLSW.errCode = SW_INVALID_ENUM; break; } } @@ -4553,7 +4566,7 @@ void swBegin(SWdraw mode) void swEnd(void) { - RLSW.drawMode = 0; + RLSW.drawMode = (SWdraw)0; } void swVertex2i(int x, int y) @@ -4738,9 +4751,9 @@ void swBindArray(SWarray type, void *buffer) { switch (type) { - case SW_VERTEX_ARRAY: RLSW.array.positions = buffer; break; - case SW_TEXTURE_COORD_ARRAY: RLSW.array.texcoords = buffer; break; - case SW_COLOR_ARRAY: RLSW.array.colors = buffer; break; + case SW_VERTEX_ARRAY: RLSW.array.positions = (float *)buffer; break; + case SW_TEXTURE_COORD_ARRAY: RLSW.array.texcoords = (float *)buffer; break; + case SW_COLOR_ARRAY: RLSW.array.colors = (uint8_t *)buffer; break; default: break; } } @@ -4833,7 +4846,7 @@ void swTexImage2D(int width, int height, SWformat format, SWtype type, bool copy if (copy) { - int bytes = sw_get_pixel_bytes(pixelFormat); + int bytes = sw_get_pixel_bytes((sw_pixelformat_t)pixelFormat); int size = bytes*width*height; texture->pixels.ptr = SW_MALLOC(size); @@ -4854,7 +4867,7 @@ void swTexImage2D(int width, int height, SWformat format, SWtype type, bool copy texture->height = height; texture->wMinus1 = width - 1; texture->hMinus1 = height - 1; - texture->format = pixelFormat; + texture->format = (sw_pixelformat_t)pixelFormat; texture->tx = 1.0f/width; texture->ty = 1.0f/height; texture->copy = copy; @@ -4882,7 +4895,7 @@ void swTexParameteri(int param, int value) return; } - texture->minFilter = value; + texture->minFilter = (SWfilter)value; } break; case SW_TEXTURE_MAG_FILTER: { @@ -4892,7 +4905,7 @@ void swTexParameteri(int param, int value) return; } - texture->magFilter = value; + texture->magFilter = (SWfilter)value; } break; case SW_TEXTURE_WRAP_S: { @@ -4902,7 +4915,7 @@ void swTexParameteri(int param, int value) return; } - texture->sWrap = value; + texture->sWrap = (SWwrap)value; } break; case SW_TEXTURE_WRAP_T: { @@ -4912,7 +4925,7 @@ void swTexParameteri(int param, int value) return; } - texture->tWrap = value; + texture->tWrap = (SWwrap)value; } break; default: RLSW.errCode = SW_INVALID_ENUM; break; } From 12dc0d66758970212eaa323c2e398d8645a229e4 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Thu, 23 Oct 2025 08:45:33 -0700 Subject: [PATCH 004/189] Revert undesired change to rcore and restore correct win32 ifdef and max path (#5297) Fixes #5293 also add comment for win32 platform. --- src/rcore.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 350490ad1..e4628e77c 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -26,7 +26,8 @@ * - Linux DRM subsystem (KMS mode) * > PLATFORM_ANDROID: * - Android (ARM, ARM64) -* +* > PLATFORM_DESKTOP_WIN32 (Native Win32): +* - Windows (Win32, Win64) * CONFIGURATION: * #define SUPPORT_DEFAULT_FONT (default) * Default font is loaded on window initialization to be available for the user to render simple text. @@ -161,7 +162,10 @@ #endif // Platform specific defines to handle GetApplicationDirectory() -#if (defined(_WIN32) && !defined(PLATFORM_DESKTOP_RGFW)) || (defined(_MSC_VER) && defined(PLATFORM_DESKTOP_RGFW)) +#if defined(_WIN32) + #if !defined(MAX_PATH) + #define MAX_PATH 260 + #endif struct HINSTANCE__; #if defined(__cplusplus) From 39242dba2303cd321e594908c814e08f976d31b4 Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Fri, 24 Oct 2025 18:29:01 +0200 Subject: [PATCH 005/189] [rlsw] Smarter texture management (#5296) * simplified framebuffer management * convert texture to rgba32 * remove float copy/blit * adding SIMD framebuffer read/write This adds SIMD framebuffer read/write, and also texel fetch. This supports SSE2/SSE41 and SISD fallback (also includes ARM NEON support, conceptually identical but still needs testing). * consistency * tweaks * review of `sw_texture_sample_linear` * better quad sorting unrelated to the PR, but at least it's done * ignore some pipeline state in certains context * convention tweaks --------- Co-authored-by: Ray --- src/external/rlsw.h | 1721 ++++++++++++++++++------------------------- 1 file changed, 723 insertions(+), 998 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index aa4803265..626cb2cc5 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -115,16 +115,12 @@ #define SW_GL_FRAMEBUFFER_COPY_BGRA true #endif -#ifndef SW_GL_BINDING_COPY_TEXTURE - #define SW_GL_BINDING_COPY_TEXTURE true -#endif - #ifndef SW_COLOR_BUFFER_BITS - #define SW_COLOR_BUFFER_BITS 24 + #define SW_COLOR_BUFFER_BITS 32 //< 32 (rgba), 16 (rgb packed) or 8 (rgb packed) #endif #ifndef SW_DEPTH_BUFFER_BITS - #define SW_DEPTH_BUFFER_BITS 16 + #define SW_DEPTH_BUFFER_BITS 16 //< 24, 16 or 8 #endif #ifndef SW_MAX_PROJECTION_STACK_SIZE @@ -382,7 +378,7 @@ typedef double GLclampd; #define glDrawArrays(m, o, c) swDrawArrays((m), (o), (c)) #define glGenTextures(c, v) swGenTextures((c), (v)) #define glDeleteTextures(c, v) swDeleteTextures((c), (v)) -#define glTexImage2D(tr, l, if, w, h, b, f, t, p) swTexImage2D((w), (h), (f), (t), SW_GL_BINDING_COPY_TEXTURE, (p)) +#define glTexImage2D(tr, l, if, w, h, b, f, t, p) swTexImage2D((w), (h), (f), (t), (p)) #define glTexParameteri(tr, pname, param) swTexParameteri((pname), (param)) #define glBindTexture(tr, id) swBindTexture((id)) @@ -597,7 +593,7 @@ SWAPI void swDrawArrays(SWdraw mode, int offset, int count); SWAPI void swGenTextures(int count, uint32_t *textures); SWAPI void swDeleteTextures(int count, uint32_t *textures); -SWAPI void swTexImage2D(int width, int height, SWformat format, SWtype type, bool copy, const void *data); +SWAPI void swTexImage2D(int width, int height, SWformat format, SWtype type, const void *data); SWAPI void swTexParameteri(int param, int value); SWAPI void swBindTexture(uint32_t id); @@ -615,6 +611,65 @@ SWAPI void swBindTexture(uint32_t id); #include #include // Required for: floorf(), fabsf() +#if defined(__FMA__) && defined(__AVX2__) +# define SW_HAS_FMA_AVX2 +# include +#endif + +#if defined(__FMA__) && defined(__AVX__) +# define SW_HAS_FMA_AVX +# include +#endif + +#if defined(__AVX2__) +# define SW_HAS_AVX2 +# include +#endif + +#if defined(__AVX__) +# define SW_HAS_AVX +# include +#endif + +#if defined(__SSE4_2__) +# define SW_HAS_SSE42 +# include +#endif + +#if defined(__SSE4_1__) +# define SW_HAS_SSE41 +# include +#endif + +#if defined(__SSSE3__) +# define SW_HAS_SSSE3 +# include +#endif + +#if defined(__SSE3__) +# define SW_HAS_SSE3 +# include +#endif + +#if defined(__SSE2__) +# define SW_HAS_SSE2 +# include +#endif + +#if defined(__SSE__) +# define SW_HAS_SSE +# include +#endif + +#if defined(__ARM_NEON) || defined(__aarch64__) +# if defined(__ARM_FEATURE_FMA) +# define SW_HAS_NEON_FMA +# else +# define SW_HAS_NEON +# endif +# include +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -625,7 +680,69 @@ SWAPI void swBindTexture(uint32_t id); #define SW_COLOR_PIXEL_SIZE (SW_COLOR_BUFFER_BITS/8) #define SW_DEPTH_PIXEL_SIZE (SW_DEPTH_BUFFER_BITS/8) -#define SW_STATE_CHECK(flags) ((RLSW.stateFlags & (flags)) == (flags)) +#if (SW_COLOR_BUFFER_BITS == 8) + #define COLOR_TYPE uint8_t + #define COLOR_IS_PACKED 1 + #define PACK_COLOR(r,g,b) ((((uint8_t)((r)*7+0.5f))&0x07)<<5 | (((uint8_t)((g)*7+0.5f))&0x07)<<2 | ((uint8_t)((b)*3+0.5f))&0x03) + #define UNPACK_R(p) (((p)>>5)&0x07) + #define UNPACK_G(p) (((p)>>2)&0x07) + #define UNPACK_B(p) ((p)&0x03) + #define SCALE_R(v) ((v)*255+3)/7 + #define SCALE_G(v) ((v)*255+3)/7 + #define SCALE_B(v) ((v)*255+1)/3 + #define TO_FLOAT_R(v) ((v)*(1.0f/7.0f)) + #define TO_FLOAT_G(v) ((v)*(1.0f/7.0f)) + #define TO_FLOAT_B(v) ((v)*(1.0f/3.0f)) +#elif (SW_COLOR_BUFFER_BITS == 16) + #define COLOR_TYPE uint16_t + #define COLOR_IS_PACKED 1 + #define PACK_COLOR(r,g,b) ((((uint16_t)((r)*31+0.5f))&0x1F)<<11 | (((uint16_t)((g)*63+0.5f))&0x3F)<<5 | ((uint16_t)((b)*31+0.5f))&0x1F) + #define UNPACK_R(p) (((p)>>11)&0x1F) + #define UNPACK_G(p) (((p)>>5)&0x3F) + #define UNPACK_B(p) ((p)&0x1F) + #define SCALE_R(v) ((v)*255+15)/31 + #define SCALE_G(v) ((v)*255+31)/63 + #define SCALE_B(v) ((v)*255+15)/31 + #define TO_FLOAT_R(v) ((v)*(1.0f/31.0f)) + #define TO_FLOAT_G(v) ((v)*(1.0f/63.0f)) + #define TO_FLOAT_B(v) ((v)*(1.0f/31.0f)) +#else // 32 bits + #define COLOR_TYPE uint8_t + #define COLOR_IS_PACKED 0 +#endif + +#if (SW_DEPTH_BUFFER_BITS == 8) + #define DEPTH_TYPE uint8_t + #define DEPTH_IS_PACKED 1 + #define DEPTH_MAX UINT8_MAX + #define DEPTH_SCALE (1.0f/UINT8_MAX) + #define PACK_DEPTH(d) ((DEPTH_TYPE)((d)*DEPTH_MAX)) + #define UNPACK_DEPTH(p) (p) +#elif (SW_DEPTH_BUFFER_BITS == 16) + #define DEPTH_TYPE uint16_t + #define DEPTH_IS_PACKED 1 + #define DEPTH_MAX UINT16_MAX + #define DEPTH_SCALE (1.0f/UINT16_MAX) + #define PACK_DEPTH(d) ((DEPTH_TYPE)((d)*DEPTH_MAX)) + #define UNPACK_DEPTH(p) (p) +#else // 24 bits + #define DEPTH_TYPE uint8_t + #define DEPTH_IS_PACKED 0 + #define DEPTH_MAX 0xFFFFFF + #define DEPTH_SCALE (1.0f/0xFFFFFF) + #define PACK_DEPTH_0(d) (((uint32_t)((d)*DEPTH_MAX)>>16)&0xFF) + #define PACK_DEPTH_1(d) (((uint32_t)((d)*DEPTH_MAX)>>8)&0xFF) + #define PACK_DEPTH_2(d) ((uint32_t)((d)*DEPTH_MAX)&0xFF) + #define UNPACK_DEPTH(p) (((p)[0]<<16)|((p)[1]<<8)|(p)[2]) +#endif + +#define GET_COLOR_PTR(ptr, offset) ((void*)((uint8_t*)(ptr) + (offset)*SW_COLOR_PIXEL_SIZE)) +#define GET_DEPTH_PTR(ptr, offset) ((void*)((uint8_t*)(ptr) + (offset)*SW_DEPTH_PIXEL_SIZE)) +#define INC_COLOR_PTR(ptr) ((ptr) = (void*)((uint8_t*)(ptr) + SW_COLOR_PIXEL_SIZE)) +#define INC_DEPTH_PTR(ptr) ((ptr) = (void*)((uint8_t*)(ptr) + SW_DEPTH_PIXEL_SIZE)) + +#define SW_STATE_CHECK(flags) (SW_STATE_CHECK_EX(RLSW.stateFlags, (flags))) +#define SW_STATE_CHECK_EX(state, flags) (((state) & (flags)) == (flags)) #define SW_STATE_SCISSOR_TEST (1 << 0) #define SW_STATE_TEXTURE_2D (1 << 1) @@ -674,16 +791,11 @@ typedef struct { } sw_vertex_t; typedef struct { - // Dirty hack for copied data - // TODO: Rework copied image handling - union { - const void *cptr; // NOTE: Is used for all data reads - void *ptr; // WARNING: Should only be used to allocate and free data - } pixels; + + uint8_t* pixels; // Texture pixels (RGBA32) int width, height; // Dimensions of the texture int wMinus1, hMinus1; // Dimensions minus one - sw_pixelformat_t format; // Pixel format (internal representation) SWfilter minFilter; // Minification filter SWfilter magFilter; // Magnification filter @@ -694,8 +806,6 @@ typedef struct { float tx; // Texel width float ty; // Texel height - bool copy; // Flag indicating whether memory has been allocated - } sw_texture_t; typedef struct { @@ -943,8 +1053,89 @@ static inline void sw_add_vertex_grad_PTCH( out->homogeneous[3] += gradients->homogeneous[3]; } -// Half floating point management functions -static inline uint32_t sw_f16_to_f32_ui(uint16_t h) +static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) +{ +#if defined(SW_HAS_NEON) + float32x4_t values = vld1q_f32(src); + float32x4_t scaled = vmulq_n_f32(values, 255.0f); + scaled = vminq_f32(vmaxq_f32(scaled, vdupq_n_f32(0.0f)), vdupq_n_f32(255.0f)); + uint32x4_t clamped = vcvtq_u32_f32(scaled); + + uint16x4_t narrow16 = vmovn_u32(clamped); + uint8x8_t narrow8 = vmovn_u16(vcombine_u16(narrow16, narrow16)); + + vst1_lane_u32((uint32_t*)dst, vreinterpret_u32_u8(narrow8), 0); + +#elif defined(SW_HAS_SSE41) + __m128 values = _mm_loadu_ps(src); + __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); + scaled = _mm_max_ps(_mm_min_ps(scaled, _mm_set1_ps(255.0f)), _mm_setzero_ps()); + __m128i clamped = _mm_cvtps_epi32(scaled); + + clamped = _mm_packus_epi32(clamped, clamped); + clamped = _mm_packus_epi16(clamped, clamped); + *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); + +#elif defined(SW_HAS_SSE2) + __m128 values = _mm_loadu_ps(src); + __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); + scaled = _mm_max_ps(_mm_min_ps(scaled, _mm_set1_ps(255.0f)), _mm_setzero_ps()); + __m128i clamped = _mm_cvtps_epi32(scaled); + + clamped = _mm_packs_epi32(clamped, clamped); + clamped = _mm_packus_epi16(clamped, clamped); + *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); + +#else + for (int i = 0; i < 4; i++) + { + float val = src[i]*255.0f; + val = (val > 255.0f)? 255.0f : val; + val = (val < 0.0f)? 0.0f : val; + dst[i] = (uint8_t)(val + 0.5f); + } +#endif +} + +static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) +{ +#if defined(SW_HAS_NEON) + uint32x4_t bytes = vdupq_n_u32(0); + bytes = vld1q_lane_u32((const uint32_t*)src, bytes, 0); + + uint8x8_t bytes8 = vreinterpret_u8_u32(vget_low_u32(bytes)); + uint16x8_t bytes16 = vmovl_u8(bytes8); + uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16)); + + float32x4_t floats = vcvtq_f32_u32(ints); + floats = vmulq_n_f32(floats, 1.0f/255.0f); + vst1q_f32(dst, floats); + +#elif defined(SW_HAS_SSE41) + __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); + __m128i ints = _mm_cvtepu8_epi32(bytes); + __m128 floats = _mm_cvtepi32_ps(ints); + floats = _mm_mul_ps(floats, _mm_set1_ps(1.0f/255.0f)); + _mm_storeu_ps(dst, floats); + +#elif defined(SW_HAS_SSE2) + __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); + bytes = _mm_unpacklo_epi8(bytes, _mm_setzero_si128()); + __m128i ints = _mm_unpacklo_epi16(bytes, _mm_setzero_si128()); + __m128 floats = _mm_cvtepi32_ps(ints); + floats = _mm_mul_ps(floats, _mm_set1_ps(1.0f/255.0f)); + _mm_storeu_ps(dst, floats); + +#else + dst[0] = (float)src[0]/255.0f; + dst[1] = (float)src[1]/255.0f; + dst[2] = (float)src[2]/255.0f; + dst[3] = (float)src[3]/255.0f; +#endif +} + +// Half conversion functions +static inline uint32_t sw_half_to_float_ui(uint16_t h) { uint32_t s = (uint32_t)(h & 0x8000) << 16; int32_t em = h & 0x7fff; @@ -962,14 +1153,14 @@ static inline uint32_t sw_f16_to_f32_ui(uint16_t h) return s | r; } -static inline float sw_f16_to_f32(sw_half_t y) +static inline float sw_half_to_float(sw_half_t y) { - union { float f; uint32_t i; } v = { .i = sw_f16_to_f32_ui(y) }; + union { float f; uint32_t i; } v = { .i = sw_half_to_float_ui(y) }; return v.f; } -static inline uint16_t sw_f16_from_f32_ui(uint32_t ui) +static inline uint16_t sw_half_from_float_ui(uint32_t ui) { int32_t s = (ui >> 16) & 0x8000; int32_t em = ui & 0x7fffffff; @@ -989,14 +1180,15 @@ static inline uint16_t sw_f16_from_f32_ui(uint32_t ui) return (uint16_t)(s | h); } -static inline sw_half_t sw_f16_from_f32(float i) +static inline sw_half_t sw_half_from_float(float i) { union { float f; uint32_t i; } v; v.f = i; - return sw_f16_from_f32_ui(v.i); + return sw_half_from_float_ui(v.i); } // Framebuffer management functions + static inline bool sw_framebuffer_load(int w, int h) { int size = w*h; @@ -1005,7 +1197,11 @@ static inline bool sw_framebuffer_load(int w, int h) if (RLSW.framebuffer.color == NULL) return false; RLSW.framebuffer.depth = SW_MALLOC(SW_DEPTH_PIXEL_SIZE*size); - if (RLSW.framebuffer.depth == NULL) return false; + if (RLSW.framebuffer.depth == NULL) + { + SW_FREE(RLSW.framebuffer.color); + return false; + } RLSW.framebuffer.width = w; RLSW.framebuffer.height = h; @@ -1025,11 +1221,15 @@ static inline bool sw_framebuffer_resize(int w, int h) return true; } - void *newColor = SW_REALLOC(RLSW.framebuffer.color, newSize); + void *newColor = SW_REALLOC(RLSW.framebuffer.color, SW_COLOR_PIXEL_SIZE*newSize); if (newColor == NULL) return false; - void *newDepth = SW_REALLOC(RLSW.framebuffer.depth, newSize); - if (newDepth == NULL) return false; + void *newDepth = SW_REALLOC(RLSW.framebuffer.depth, SW_DEPTH_PIXEL_SIZE*newSize); + if (newDepth == NULL) + { + SW_FREE(newColor); + return false; + } RLSW.framebuffer.color = newColor; RLSW.framebuffer.depth = newDepth; @@ -1041,314 +1241,221 @@ static inline bool sw_framebuffer_resize(int w, int h) return true; } -static inline void *sw_framebuffer_get_color_addr(const void *ptr, uint32_t offset) -{ - return (uint8_t *)ptr + offset*SW_COLOR_PIXEL_SIZE; -} - -static inline void sw_framebuffer_inc_color_addr(void **ptr) -{ - *ptr = (void *)(((uint8_t *)*ptr) + SW_COLOR_PIXEL_SIZE); -} - -static inline void sw_framebuffer_inc_const_color_addr(const void **ptr) -{ - *ptr = (const void *)(((const uint8_t *)*ptr) + SW_COLOR_PIXEL_SIZE); -} - -static inline void *sw_framebuffer_get_depth_addr(const void *ptr, uint32_t offset) -{ - return (uint8_t *)ptr + offset*SW_DEPTH_PIXEL_SIZE; -} - -static inline void sw_framebuffer_inc_depth_addr(void* *ptr) -{ - *ptr = (void*)(((uint8_t *)*ptr) + SW_DEPTH_PIXEL_SIZE); -} - -#if (SW_COLOR_BUFFER_BITS == 8) // RGB - (3:3:2) static inline void sw_framebuffer_read_color(float dst[4], const void *src) { - uint8_t pixel = ((uint8_t *)src)[0]; - - dst[0] = ((pixel >> 5) & 0x07)*(1.0f/7.0f); - dst[1] = ((pixel >> 2) & 0x07)*(1.0f/7.0f); - dst[2] = (pixel & 0x03)*(1.0f/3.0f); +#if COLOR_IS_PACKED + COLOR_TYPE pixel = ((COLOR_TYPE*)src)[0]; + dst[0] = TO_FLOAT_R(UNPACK_R(pixel)); + dst[1] = TO_FLOAT_G(UNPACK_G(pixel)); + dst[2] = TO_FLOAT_B(UNPACK_B(pixel)); dst[3] = 1.0f; +#else + sw_float_from_unorm8_simd(dst, src); +#endif } static inline void sw_framebuffer_read_color8(uint8_t dst[4], const void *src) { - uint8_t pixel = ((const uint8_t *)src)[0]; - - uint8_t r = (pixel >> 5) & 0x07; - uint8_t g = (pixel >> 2) & 0x07; - uint8_t b = pixel & 0x03; - - dst[0] = (r*255 + 3)/7; - dst[1] = (g*255 + 3)/7; - dst[2] = (b*255 + 1)/3; +#if COLOR_IS_PACKED + COLOR_TYPE pixel = ((COLOR_TYPE*)src)[0]; + dst[0] = SCALE_R(UNPACK_R(pixel)); + dst[1] = SCALE_G(UNPACK_G(pixel)); + dst[2] = SCALE_B(UNPACK_B(pixel)); dst[3] = 255; +#else + const COLOR_TYPE *p = (const COLOR_TYPE*)src; + dst[0] = p[0]; + dst[1] = p[1]; + dst[2] = p[2]; + dst[3] = p[3]; +#endif } -static inline void sw_framebuffer_write_color(void *dst, const float color[3]) +static inline void sw_framebuffer_write_color(void *dst, const float src[4]) { - uint8_t r = ((uint8_t)(color[0]*UINT8_MAX) >> 5) & 0x07; - uint8_t g = ((uint8_t)(color[1]*UINT8_MAX) >> 5) & 0x07; - uint8_t b = ((uint8_t)(color[2]*UINT8_MAX) >> 6) & 0x03; - - ((uint8_t *)dst)[0] = (r << 5) | (g << 2) | b; +#if COLOR_IS_PACKED + ((COLOR_TYPE*)dst)[0] = PACK_COLOR(src[0], src[1], src[2]); +#else + sw_float_to_unorm8_simd(dst, src); +#endif } -static inline void sw_framebuffer_fill_color(void *ptr, int size, const float color[3]) +static inline void sw_framebuffer_fill_color(void *ptr, int size, const float color[4]) { - uint8_t r8 = (uint8_t)(color[0]*7.0f + 0.5f); - uint8_t g8 = (uint8_t)(color[1]*7.0f + 0.5f); - uint8_t b8 = (uint8_t)(color[2]*3.0f + 0.5f); - - uint8_t packedColor = ((r8 & 0x07) << 5) | ((g8 & 0x07) << 2) | (b8 & 0x03); - - uint8_t *p = (uint8_t *)ptr; - +#if COLOR_IS_PACKED + COLOR_TYPE packed = PACK_COLOR(color[0], color[1], color[2]); + COLOR_TYPE *p = (COLOR_TYPE*)ptr; +#else + COLOR_TYPE r = sw_clampi(color[0]*255, 0, 255); + COLOR_TYPE g = sw_clampi(color[1]*255, 0, 255); + COLOR_TYPE b = sw_clampi(color[2]*255, 0, 255); + COLOR_TYPE a = sw_clampi(color[3]*255, 0, 255); + COLOR_TYPE *p = (COLOR_TYPE*)ptr; +#endif + if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; + int w = RLSW.scMax[0] - RLSW.scMin[0] + 1; for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) { - uint8_t *curPtr = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; - for (int xCount = 0; xCount < wScissor; xCount++) *curPtr++ = packedColor; - } - } - else - { - for (int i = 0; i < size; i++) *p++ = packedColor; - } -} - -#elif (SW_COLOR_BUFFER_BITS == 16) // RGB - (5:6:5) - -static inline void sw_framebuffer_read_color(float dst[4], const void *src) -{ - uint16_t pixel = ((uint16_t *)src)[0]; - - dst[0] = ((pixel >> 11) & 0x1F)*(1.0f/31.0f); - dst[1] = ((pixel >> 5) & 0x3F)*(1.0f/63.0f); - dst[2] = (pixel & 0x1F)*(1.0f/31.0f); - dst[3] = 1.0f; -} - -static inline void sw_framebuffer_read_color8(uint8_t dst[4], const void *src) -{ - uint16_t pixel = ((const uint16_t *)src)[0]; - - uint8_t r = (pixel >> 11) & 0x1F; - uint8_t g = (pixel >> 5) & 0x3F; - uint8_t b = pixel & 0x1F; - - dst[0] = (r*255 + 15)/31; - dst[1] = (g*255 + 31)/63; - dst[2] = (b*255 + 15)/31; - dst[3] = 255; -} - -static inline void sw_framebuffer_write_color(void *dst, const float color[3]) -{ - uint8_t r = (uint8_t)(color[0]*31.0f + 0.5f) & 0x1F; - uint8_t g = (uint8_t)(color[1]*63.0f + 0.5f) & 0x3F; - uint8_t b = (uint8_t)(color[2]*31.0f + 0.5f) & 0x1F; - - ((uint16_t *)dst)[0] = (r << 11) | (g << 5) | b; -} - -static inline void sw_framebuffer_fill_color(void *ptr, int size, const float color[3]) -{ - uint16_t r16 = (uint16_t)(color[0]*31.0f + 0.5f); - uint16_t g_16 = (uint16_t)(color[1]*63.0f + 0.5f); - uint16_t b_16 = (uint16_t)(color[2]*31.0f + 0.5f); - - uint16_t packedColor = ((r16 & 0x1F) << 11) | ((g_16 & 0x3F) << 5) | (b_16 & 0x1F); - - uint16_t *p = (uint16_t *)ptr; - - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) - { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; - for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) - { - uint16_t *curPtr = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; - for (int xCount = 0; xCount < wScissor; xCount++) *curPtr++ = packedColor; - } - } - else - { - for (int i = 0; i < size; i++) *p++ = packedColor; - } -} - -#elif (SW_COLOR_BUFFER_BITS == 24) // RGB - (8:8:8) - -static inline void sw_framebuffer_read_color(float dst[4], const void *src) -{ - dst[0] = ((uint8_t *)src)[0]*(1.0f/255.0f); - dst[1] = ((uint8_t *)src)[1]*(1.0f/255.0f); - dst[2] = ((uint8_t *)src)[2]*(1.0f/255.0f); - dst[3] = 1.0f; -} - -static inline void sw_framebuffer_read_color8(uint8_t dst[4], const void *src) -{ - dst[0] = ((uint8_t *)src)[0]; - dst[1] = ((uint8_t *)src)[1]; - dst[2] = ((uint8_t *)src)[2]; - dst[3] = 255; -} - -static inline void sw_framebuffer_write_color(void *dst, const float color[3]) -{ - ((uint8_t *)dst)[0] = (uint8_t)(color[0]*UINT8_MAX); - ((uint8_t *)dst)[1] = (uint8_t)(color[1]*UINT8_MAX); - ((uint8_t *)dst)[2] = (uint8_t)(color[2]*UINT8_MAX); -} - -static inline void sw_framebuffer_fill_color(void *ptr, int size, const float color[3]) -{ - uint8_t r = (uint8_t)(color[0]*255.0f); - uint8_t g = (uint8_t)(color[1]*255.0f); - uint8_t b = (uint8_t)(color[2]*255.0f); - - uint8_t *p = (uint8_t *)ptr; - - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) - { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; - for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) - { - uint8_t *curPtr = p + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); - for (int xCount = 0; xCount < wScissor; xCount++) +#if COLOR_IS_PACKED + COLOR_TYPE *row = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; + for (int x = 0; x < w; x++) *row++ = packed; +#else + COLOR_TYPE *row = p + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); + for (int x = 0; x < w; x++) { - *curPtr++ = r; - *curPtr++ = g; - *curPtr++ = b; + *row++ = r; + *row++ = g; + *row++ = b; + *row++ = a; } +#endif } } else { +#if COLOR_IS_PACKED + for (int i = 0; i < size; i++) *p++ = packed; +#else for (int i = 0; i < size; i++) { *p++ = r; *p++ = g; *p++ = b; + *p++ = a; } +#endif } } -#endif // SW_COLOR_BUFFER_BITS - -#if (SW_DEPTH_BUFFER_BITS == 8) - static inline float sw_framebuffer_read_depth(const void *src) { - return (float)((uint8_t *)src)[0]*(1.0f/UINT8_MAX); +#if DEPTH_IS_PACKED + return ((DEPTH_TYPE*)src)[0]*DEPTH_SCALE; +#else + const DEPTH_TYPE *p = (const DEPTH_TYPE*)src; + uint32_t d = UNPACK_DEPTH(p); + return d*DEPTH_SCALE; +#endif } static inline void sw_framebuffer_write_depth(void *dst, float depth) { - ((uint8_t *)dst)[0] = (uint8_t)(depth*UINT8_MAX); +#if DEPTH_IS_PACKED + ((DEPTH_TYPE*)dst)[0] = PACK_DEPTH(depth); +#else + DEPTH_TYPE *p = (DEPTH_TYPE*)dst; + p[0] = PACK_DEPTH_0(depth); + p[1] = PACK_DEPTH_1(depth); + p[2] = PACK_DEPTH_2(depth); +#endif } static inline void sw_framebuffer_fill_depth(void *ptr, int size, float value) { - uint8_t d8 = (uint8_t)(value*UINT8_MAX); - uint8_t *p = (uint8_t *)ptr; - +#if DEPTH_IS_PACKED + DEPTH_TYPE d = PACK_DEPTH(value); + DEPTH_TYPE *p = (DEPTH_TYPE*)ptr; +#else + DEPTH_TYPE d0 = PACK_DEPTH_0(value); + DEPTH_TYPE d1 = PACK_DEPTH_1(value); + DEPTH_TYPE d2 = PACK_DEPTH_2(value); + DEPTH_TYPE *p = (DEPTH_TYPE*)ptr; +#endif + if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; + int w = RLSW.scMax[0] - RLSW.scMin[0] + 1; for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) { - uint8_t *curPtr = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; - for (int xCount = 0; xCount < wScissor; xCount++) *curPtr++ = d8; - } - } - else - { - for (int i = 0; i < size; i++) *p++ = d8; - } -} - -#elif (SW_DEPTH_BUFFER_BITS == 16) - -static inline float sw_framebuffer_read_depth(const void *src) -{ - return (float)((uint16_t *)src)[0]*(1.0f/UINT16_MAX); -} - -static inline void sw_framebuffer_write_depth(void *dst, float depth) -{ - ((uint16_t *)dst)[0] = (uint16_t)(depth*UINT16_MAX); -} - -static inline void sw_framebuffer_fill_depth(void *ptr, int size, float value) -{ - uint16_t d16 = (uint16_t)(value*UINT16_MAX); - uint16_t *p = (uint16_t *)ptr; - - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) - { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; - for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) - { - uint16_t *curPtr = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; - for (int xCount = 0; xCount < wScissor; xCount++) *curPtr++ = d16; - } - } - else - { - for (int i = 0; i < size; i++) *p++ = d16; - } -} - -#elif (SW_DEPTH_BUFFER_BITS == 24) - -static inline float sw_framebuffer_read_depth(const void *src) -{ - uint32_t depth24 = (((uint8_t *)src)[0] << 16) | - (((uint8_t *)src)[1] << 8) | - ((uint8_t *)src)[2]; - - return depth24/(float)0xFFFFFF; -} - -static inline void sw_framebuffer_write_depth(void *dst, float depth) -{ - uint32_t depth24 = (uint32_t)(depth*0xFFFFFF); - - ((uint8_t *)dst)[0] = (depth24 >> 16) & 0xFF; - ((uint8_t *)dst)[1] = (depth24 >> 8) & 0xFF; - ((uint8_t *)dst)[2] = depth24 & 0xFF; -} - -static inline void sw_framebuffer_fill_depth(void *ptr, int size, float value) -{ - uint32_t d32 = (uint32_t)(value*UINT32_MAX); - uint8_t d_byte0 = (uint8_t)((d32 >> 16) & 0xFF); - uint8_t d_byte1 = (uint8_t)((d32 >> 8) & 0xFF); - uint8_t d_byte2 = (uint8_t)(d32 & 0xFF); - - uint8_t *p = (uint8_t *)ptr; - - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) - { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; - for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) - { - uint8_t *curPtr = p + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); - for (int xCount = 0; xCount < wScissor; xCount++) +#if DEPTH_IS_PACKED + DEPTH_TYPE *row = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; + for (int x = 0; x < w; x++) *row++ = d; +#else + DEPTH_TYPE *row = p + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); + for (int x = 0; x < w; x++) { - *curPtr++ = d_byte0; - *curPtr++ = d_byte1; - *curPtr++ = d_byte2; + *row++ = d0; + *row++ = d1; + *row++ = d2; + } +#endif + } + } + else + { +#if DEPTH_IS_PACKED + for (int i = 0; i < size; i++) *p++ = d; +#else + for (int i = 0; i < size; i++) + { + *p++ = d0; + *p++ = d1; + *p++ = d2; + } +#endif + } +} + +static inline void sw_framebuffer_fill(void *colorPtr, void *depthPtr, int size, float color[4], float depth) +{ +#if COLOR_IS_PACKED + COLOR_TYPE packedColor = PACK_COLOR(color[0], color[1], color[2]); + COLOR_TYPE *pColor = (COLOR_TYPE*)colorPtr; +#else + COLOR_TYPE r = sw_clampi(color[0]*255, 0, 255); + COLOR_TYPE g = sw_clampi(color[1]*255, 0, 255); + COLOR_TYPE b = sw_clampi(color[2]*255, 0, 255); + COLOR_TYPE a = sw_clampi(color[3]*255, 0, 255); + COLOR_TYPE *pColor = (COLOR_TYPE*)colorPtr; +#endif + +#if DEPTH_IS_PACKED + DEPTH_TYPE d = PACK_DEPTH(depth); + DEPTH_TYPE *pDepth = (DEPTH_TYPE*)depthPtr; +#else + DEPTH_TYPE d0 = PACK_DEPTH_0(depth); + DEPTH_TYPE d1 = PACK_DEPTH_1(depth); + DEPTH_TYPE d2 = PACK_DEPTH_2(depth); + DEPTH_TYPE *pDepth = (DEPTH_TYPE*)depthPtr; +#endif + + if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) + { + int w = RLSW.scMax[0] - RLSW.scMin[0] + 1; + for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) + { +#if COLOR_IS_PACKED + COLOR_TYPE *rowColor = pColor + y*RLSW.framebuffer.width + RLSW.scMin[0]; +#else + COLOR_TYPE *rowColor = pColor + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); +#endif + +#if DEPTH_IS_PACKED + DEPTH_TYPE *rowDepth = pDepth + y*RLSW.framebuffer.width + RLSW.scMin[0]; +#else + DEPTH_TYPE *rowDepth = pDepth + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); +#endif + + for (int x = 0; x < w; x++) + { +#if COLOR_IS_PACKED + *rowColor++ = packedColor; +#else + *rowColor++ = r; + *rowColor++ = g; + *rowColor++ = b; + *rowColor++ = a; +#endif + +#if DEPTH_IS_PACKED + *rowDepth++ = d; +#else + *rowDepth++ = d0; + *rowDepth++ = d1; + *rowDepth++ = d2; +#endif } } } @@ -1356,140 +1463,27 @@ static inline void sw_framebuffer_fill_depth(void *ptr, int size, float value) { for (int i = 0; i < size; i++) { - *p++ = d_byte0; - *p++ = d_byte1; - *p++ = d_byte2; +#if COLOR_IS_PACKED + *pColor++ = packedColor; +#else + *pColor++ = r; + *pColor++ = g; + *pColor++ = b; + *pColor++ = a; +#endif + +#if DEPTH_IS_PACKED + *pDepth++ = d; +#else + *pDepth++ = d0; + *pDepth++ = d1; + *pDepth++ = d2; +#endif } } } -#endif // SW_DEPTH_BUFFER_BITS - -static inline void sw_framebuffer_fill(void *colorPtr, void *depthPtr, int size, float color[4], float depth_value) -{ -#if (SW_COLOR_BUFFER_BITS == 8) - // Calculate and pack 3:3:2 color - // Scale color components to the max value for each bit depth and round - uint8_t r8 = (uint8_t)(color[0]*7.0f + 0.5f); - uint8_t g8 = (uint8_t)(color[1]*7.0f + 0.5f); - uint8_t b8 = (uint8_t)(color[2]*3.0f + 0.5f); - // Pack the components into a single byte - uint8_t packedColor = ((r8 & 0x07) << 5) | ((g8 & 0x07) << 2) | (b8 & 0x03); - uint8_t *cptr = (uint8_t *)colorPtr; -#elif (SW_COLOR_BUFFER_BITS == 16) - // Calculate and pack 5:6:5 color - // Scale color components to the max value for each bit depth and round - uint16_t r16 = (uint16_t)(color[0]*31.0f + 0.5f); - uint16_t g16 = (uint16_t)(color[1]*63.0f + 0.5f); - uint16_t b16 = (uint16_t)(color[2]*31.0f + 0.5f); - // Pack the components into a 16-bit value - uint16_t packedColor = ((r16 & 0x1F) << 11) | ((g16 & 0x3F) << 5) | (b16 & 0x1F); - uint16_t *cptr = (uint16_t *)colorPtr; -#elif (SW_COLOR_BUFFER_BITS == 24) - // Calculate 8:8:8 color components - uint8_t r24 = (uint8_t)(color[0]*255.0f); - uint8_t g24 = (uint8_t)(color[1]*255.0f); - uint8_t b24 = (uint8_t)(color[2]*255.0f); - uint8_t *cptr = (uint8_t *)colorPtr; -#endif - -#if (SW_DEPTH_BUFFER_BITS == 8) - // Calculate 8-bit depth - uint8_t d8 = (uint8_t)(depth_value*UINT8_MAX); - uint8_t *dptr = (uint8_t *)depthPtr; -#elif (SW_DEPTH_BUFFER_BITS == 16) - // Calculate 16-bit depth - uint16_t d16 = (uint16_t)(depth_value*UINT16_MAX); - uint16_t *dptr = (uint16_t *)depthPtr; -#elif (SW_DEPTH_BUFFER_BITS == 24) - // Calculate 24-bit depth and pre-calculate bytes - uint32_t d32 = (uint32_t)(depth_value*UINT32_MAX); - uint8_t dByte0 = (uint8_t)((d32 >> 16) & 0xFF); - uint8_t dByte1 = (uint8_t)((d32 >> 8) & 0xFF); - uint8_t dByte2 = (uint8_t)(d32 & 0xFF); - uint8_t *dptr = (uint8_t *)depthPtr; -#endif - - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) - { - int wScissor = RLSW.scMax[0] - RLSW.scMin[0] + 1; - for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) - { - int rowStartIdx = y*RLSW.framebuffer.width + RLSW.scMin[0]; - - // Calculate starting pointers for the current row within the scissor rectangle - #if (SW_COLOR_BUFFER_BITS == 8) - uint8_t *curCPtr = cptr + rowStartIdx; - #elif (SW_COLOR_BUFFER_BITS == 16) - uint16_t *curCPtr = cptr + rowStartIdx; - #elif (SW_COLOR_BUFFER_BITS == 24) - uint8_t *curCPtr = cptr + 3*rowStartIdx; - #endif - - #if (SW_DEPTH_BUFFER_BITS == 8) - uint8_t *curDPtr = dptr + rowStartIdx; - #elif (SW_DEPTH_BUFFER_BITS == 16) - uint16_t *curDPtr = dptr + rowStartIdx; - #elif (SW_DEPTH_BUFFER_BITS == 24) - uint8_t *curDPtr = dptr + 3*rowStartIdx; - #endif - - // Fill the current row within the scissor rectangle - for (int xCount = 0; xCount < wScissor; xCount++) - { - // Write color - #if (SW_COLOR_BUFFER_BITS == 8) - *curCPtr++ = packedColor; - #elif (SW_COLOR_BUFFER_BITS == 16) - *curCPtr++ = packedColor; - #elif (SW_COLOR_BUFFER_BITS == 24) - *curCPtr++ = r24; - *curCPtr++ = g24; - *curCPtr++ = b24; - #endif - - // Write depth - #if (SW_DEPTH_BUFFER_BITS == 8) - *curDPtr++ = d8; - #elif (SW_DEPTH_BUFFER_BITS == 16) - *curDPtr++ = d16; - #elif (SW_DEPTH_BUFFER_BITS == 24) - *curDPtr++ = dByte0; - *curDPtr++ = dByte1; - *curDPtr++ = dByte2; - #endif - } - } - return; - } - - for (int i = 0; i < size; i++) - { - // Write color - #if (SW_COLOR_BUFFER_BITS == 8) - *cptr++ = packedColor; - #elif (SW_COLOR_BUFFER_BITS == 16) - *cptr++ = packedColor; - #elif (SW_COLOR_BUFFER_BITS == 24) - *cptr++ = r24; - *cptr++ = g24; - *cptr++ = b24; - #endif - - // Write depth - #if (SW_DEPTH_BUFFER_BITS == 8) - *dptr++ = d8; - #elif (SW_DEPTH_BUFFER_BITS == 16) - *dptr++ = d16; - #elif (SW_DEPTH_BUFFER_BITS == 24) - *dptr++ = dByte0; - *dptr++ = dByte1; - *dptr++ = dByte2; - #endif - } -} - -#define DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(name, DST_PTR_T) \ +#define DEFINE_FRAMEBUFFER_COPY_BEGIN(name, DST_PTR_T) \ static inline void sw_framebuffer_copy_to_##name(int x, int y, int w, int h, DST_PTR_T *dst) \ { \ const void *src = RLSW.framebuffer.color; \ @@ -1499,23 +1493,13 @@ static inline void sw_framebuffer_copy_to_##name(int x, int y, int w, int h, DST uint8_t color[4]; \ sw_framebuffer_read_color8(color, src); \ -#define DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(name, DST_PTR_T) \ -static inline void sw_framebuffer_copy_to_##name(int x, int y, int w, int h, DST_PTR_T *dst) \ -{ \ - const void *src = RLSW.framebuffer.color; \ - \ - for (int iy = y; iy < h; iy++) { \ - for (int ix = x; ix < w; ix++) { \ - float color[4]; \ - sw_framebuffer_read_color(color, src); \ - #define DEFINE_FRAMEBUFFER_COPY_END() \ - sw_framebuffer_inc_const_color_addr(&src); \ + INC_COLOR_PTR(src); \ } \ } \ } -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(GRAYSCALE, uint8_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(GRAYSCALE, uint8_t) { // NTSC grayscale conversion: Y = 0.299R + 0.587G + 0.114B uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000); @@ -1523,7 +1507,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(GRAYSCALE, uint8_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(GRAYALPHA, uint8_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(GRAYALPHA, uint8_t) { // Convert RGB to grayscale using NTSC formula uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000); @@ -1535,7 +1519,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(GRAYALPHA, uint8_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R5G6B5, uint16_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(R5G6B5, uint16_t) { // Convert 8-bit RGB to 5:6:5 format uint8_t r5 = (color[0]*31 + 127)/255; @@ -1552,7 +1536,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R5G6B5, uint16_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R8G8B8, uint8_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(R8G8B8, uint8_t) { #if SW_GL_FRAMEBUFFER_COPY_BGRA dst[0] = color[2]; @@ -1568,7 +1552,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R8G8B8, uint8_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R5G5B5A1, uint16_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(R5G5B5A1, uint16_t) { uint8_t r5 = (color[0]*31 + 127)/255; uint8_t g5 = (color[1]*31 + 127)/255; @@ -1585,7 +1569,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R5G5B5A1, uint16_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R4G4B4A4, uint16_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(R4G4B4A4, uint16_t) { uint8_t r4 = (color[0]*15 + 127)/255; uint8_t g4 = (color[1]*15 + 127)/255; @@ -1602,7 +1586,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R4G4B4A4, uint16_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R8G8B8A8, uint8_t) +DEFINE_FRAMEBUFFER_COPY_BEGIN(R8G8B8A8, uint8_t) { #if SW_GL_FRAMEBUFFER_COPY_BGRA dst[0] = color[2]; @@ -1619,87 +1603,7 @@ DEFINE_FRAMEBUFFER_COPY_U32_BEGIN(R8G8B8A8, uint8_t) } DEFINE_FRAMEBUFFER_COPY_END() -DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(R32, float) -{ - dst[0] = color[0]; - dst++; -} -DEFINE_FRAMEBUFFER_COPY_END() - -DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(R32G32B32, float) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = color[2]; - dst[1] = color[1]; - dst[2] = color[0]; -#else // RGBA - dst[0] = color[0]; - dst[1] = color[1]; - dst[2] = color[2]; -#endif - - dst += 3; -} -DEFINE_FRAMEBUFFER_COPY_END() - -DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(R32G32B32A32, float) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = color[2]; - dst[1] = color[1]; - dst[2] = color[0]; -#else // RGBA - dst[0] = color[0]; - dst[1] = color[1]; - dst[2] = color[2]; -#endif - dst[3] = color[3]; - - dst += 4; -} -DEFINE_FRAMEBUFFER_COPY_END() - -DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(R16, sw_half_t) -{ - dst[0] = sw_f16_from_f32(color[0]); - dst++; -} -DEFINE_FRAMEBUFFER_COPY_END() - -DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(R16G16B16, sw_half_t) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = sw_f16_from_f32(color[2]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[0]); -#else // RGBA - dst[0] = sw_f16_from_f32(color[0]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[2]); -#endif - - dst += 3; -} -DEFINE_FRAMEBUFFER_COPY_END() - -DEFINE_FRAMEBUFFER_COPY_F32_BEGIN(R16G16B16A16, sw_half_t) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = sw_f16_from_f32(color[2]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[0]); -#else // RGBA - dst[0] = sw_f16_from_f32(color[0]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[2]); -#endif - dst[3] = sw_f16_from_f32(color[3]); - - dst += 4; -} -DEFINE_FRAMEBUFFER_COPY_END() - -#define DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(name, DST_PTR_T) \ +#define DEFINE_FRAMEBUFFER_BLIT_BEGIN(name, DST_PTR_T) \ static inline void sw_framebuffer_blit_to_##name( \ int xDst, int yDst, int wDst, int hDst, \ int xSrc, int ySrc, int wSrc, int hSrc, \ @@ -1708,56 +1612,33 @@ static inline void sw_framebuffer_blit_to_##name( const uint8_t *srcBase = (uint8_t*)RLSW.framebuffer.color; \ int fbWidth = RLSW.framebuffer.width; \ \ - uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ - uint32_t yScale = ((uint32_t)hSrc << 16)/(uint32_t)hDst; \ + uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ + uint32_t yScale = ((uint32_t)hSrc << 16)/(uint32_t)hDst; \ \ for (int dy = 0; dy < hDst; dy++) { \ - uint32_t yFix = ((uint32_t)ySrc << 16) + dy*yScale; \ + uint32_t yFix = ((uint32_t)ySrc << 16) + dy*yScale; \ int sy = yFix >> 16; \ \ for (int dx = 0; dx < wDst; dx++) { \ - uint32_t xFix = dx*xScale; \ + uint32_t xFix = dx*xScale; \ int sx = xFix >> 16; \ - const void *srcPtr = sw_framebuffer_get_color_addr(srcBase, sy*fbWidth + sx); \ + const void *srcPtr = GET_COLOR_PTR(srcBase, sy*fbWidth + sx); \ uint8_t color[4]; \ sw_framebuffer_read_color8(color, srcPtr); \ -#define DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(name, DST_PTR_T) \ -static inline void sw_framebuffer_blit_to_##name( \ - int xDst, int yDst, int wDst, int hDst, \ - int xSrc, int ySrc, int wSrc, int hSrc, \ - DST_PTR_T *dst) \ -{ \ - const uint8_t *srcBase = (uint8_t *)RLSW.framebuffer.color; \ - int fbWidth = RLSW.framebuffer.width; \ - \ - uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ - uint32_t yScale = ((uint32_t)hSrc << 16)/(uint32_t)hDst; \ - \ - for (int dy = 0; dy < hDst; dy++) { \ - uint32_t yFix = ((uint32_t)ySrc << 16) + dy*yScale; \ - int sy = yFix >> 16; \ - \ - for (int dx = 0; dx < wDst; dx++) { \ - uint32_t xFix = dx*xScale; \ - int sx = xFix >> 16; \ - const void *srcPtr = sw_framebuffer_get_color_addr(srcBase, sy*fbWidth + sx); \ - float color[4]; \ - sw_framebuffer_read_color(color, srcPtr); \ - #define DEFINE_FRAMEBUFFER_BLIT_END() \ } \ } \ } -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(GRAYSCALE, uint8_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(GRAYSCALE, uint8_t) { uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000); *dst++ = gray; } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(GRAYALPHA, uint8_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(GRAYALPHA, uint8_t) { uint8_t gray = (uint8_t)((color[0]*299 + color[1]*587 + color[2]*114 + 500)/1000); @@ -1768,7 +1649,7 @@ DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(GRAYALPHA, uint8_t) } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R5G6B5, uint16_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(R5G6B5, uint16_t) { uint8_t r5 = (color[0]*31 + 127)/255; uint8_t g6 = (color[1]*63 + 127)/255; @@ -1784,7 +1665,7 @@ DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R5G6B5, uint16_t) } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R8G8B8, uint8_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(R8G8B8, uint8_t) { #if SW_GL_FRAMEBUFFER_COPY_BGRA dst[0] = color[2]; @@ -1800,7 +1681,7 @@ DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R8G8B8, uint8_t) } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R5G5B5A1, uint16_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(R5G5B5A1, uint16_t) { uint8_t r5 = (color[0]*31 + 127)/255; uint8_t g5 = (color[1]*31 + 127)/255; @@ -1817,7 +1698,7 @@ DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R5G5B5A1, uint16_t) } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R4G4B4A4, uint16_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(R4G4B4A4, uint16_t) { uint8_t r4 = (color[0]*15 + 127)/255; uint8_t g4 = (color[1]*15 + 127)/255; @@ -1834,7 +1715,7 @@ DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R4G4B4A4, uint16_t) } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R8G8B8A8, uint8_t) +DEFINE_FRAMEBUFFER_BLIT_BEGIN(R8G8B8A8, uint8_t) { #if SW_GL_FRAMEBUFFER_COPY_BGRA dst[0] = color[2]; @@ -1851,86 +1732,6 @@ DEFINE_FRAMEBUFFER_BLIT_U32_BEGIN(R8G8B8A8, uint8_t) } DEFINE_FRAMEBUFFER_BLIT_END() -DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(R32, uint8_t) -{ - dst[0] = color[0]; - dst++; -} -DEFINE_FRAMEBUFFER_BLIT_END() - -DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(R32G32B32, float) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = color[2]; - dst[1] = color[1]; - dst[2] = color[0]; -#else // RGBA - dst[0] = color[0]; - dst[1] = color[1]; - dst[2] = color[2]; -#endif - - dst += 3; -} -DEFINE_FRAMEBUFFER_BLIT_END() - -DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(R32G32B32A32, float) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = color[2]; - dst[1] = color[1]; - dst[2] = color[0]; -#else // RGBA - dst[0] = color[0]; - dst[1] = color[1]; - dst[2] = color[2]; -#endif - dst[3] = color[3]; - - dst += 4; -} -DEFINE_FRAMEBUFFER_BLIT_END() - -DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(R16, sw_half_t) -{ - dst[0] = sw_f16_from_f32(color[0]); - dst++; -} -DEFINE_FRAMEBUFFER_BLIT_END() - -DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(R16G16B16, sw_half_t) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = sw_f16_from_f32(color[2]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[0]); -#else // RGBA - dst[0] = sw_f16_from_f32(color[0]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[2]); -#endif - - dst += 3; -} -DEFINE_FRAMEBUFFER_BLIT_END() - -DEFINE_FRAMEBUFFER_BLIT_F32_BEGIN(R16G16B16A16, sw_half_t) -{ -#if SW_GL_FRAMEBUFFER_COPY_BGRA - dst[0] = sw_f16_from_f32(color[2]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[0]); -#else // RGBA - dst[0] = sw_f16_from_f32(color[0]); - dst[1] = sw_f16_from_f32(color[1]); - dst[2] = sw_f16_from_f32(color[2]); -#endif - dst[3] = sw_f16_from_f32(color[3]); - - dst += 4; -} -DEFINE_FRAMEBUFFER_BLIT_END() - // Pixel format management functions static inline int sw_get_pixel_format(SWformat format, SWtype type) @@ -1985,210 +1786,178 @@ static inline int sw_get_pixel_format(SWformat format, SWtype type) return SW_PIXELFORMAT_UNKNOWN; } -int sw_get_pixel_bytes(sw_pixelformat_t format) +static inline void sw_get_pixel(uint8_t *color, const void *pixels, uint32_t offset, sw_pixelformat_t format) { - int bpp = 0; - switch (format) { - case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 1; break; + case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: + { + uint8_t gray = ((const uint8_t*)pixels)[offset]; + color[0] = gray; + color[1] = gray; + color[2] = gray; + color[3] = 255; + break; + } case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: + { + const uint8_t *src = &((const uint8_t*)pixels)[offset*2]; + color[0] = src[0]; + color[1] = src[0]; + color[2] = src[0]; + color[3] = src[1]; + break; + } case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5: + { + uint16_t pixel = ((const uint16_t*)pixels)[offset]; + color[0] = ((pixel >> 11) & 0x1F)*255/31; // R (5 bits) + color[1] = ((pixel >> 5) & 0x3F)*255/63; // G (6 bits) + color[2] = (pixel & 0x1F)*255/31; // B (5 bits) + color[3] = 255; + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: + { + const uint8_t *src = &((const uint8_t*)pixels)[offset*3]; + color[0] = src[0]; + color[1] = src[1]; + color[2] = src[2]; + color[3] = 255; + break; + } case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: - case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 2; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 4; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 3; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32: bpp = 4; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 4*3; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 4*4; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16: bpp = 2; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: bpp = 2*3; break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: bpp = 2*4; break; - default: break; - } - - return bpp; -} - -static inline void sw_get_pixel_grayscale(float *color, const void *pixels, uint32_t offset) -{ - float gray = (float)((uint8_t *)pixels)[offset]*(1.0f/255); - - color[0] = gray; - color[1] = gray; - color[2] = gray; - color[3] = 1.0f; -} - -static inline void sw_get_pixel_red_16(float *color, const void *pixels, uint32_t offset) -{ - float value = sw_f16_to_f32(((sw_half_t *)pixels)[offset]); - - color[0] = value; - color[1] = value; - color[2] = value; - color[3] = 1.0f; -} - -static inline void sw_get_pixel_red_32(float *color, const void *pixels, uint32_t offset) -{ - float value = ((float *)pixels)[offset]; - - color[0] = value; - color[1] = value; - color[2] = value; - color[3] = 1.0f; -} - -static inline void sw_get_pixel_grayscale_alpha(float *color, const void *pixels, uint32_t offset) -{ - const uint8_t *pixelData = (const uint8_t *)pixels + 2*offset; - - color[0] = color[1] = color[2] = (float)pixelData[0]*(1.0f/255); - color[3] = (float)pixelData[1]*(1.0f/255); -} - -static inline void sw_get_pixel_rgb_565(float *color, const void *pixels, uint32_t offset) -{ - uint16_t pixel = ((uint16_t *)pixels)[offset]; - - color[0] = (float)((pixel & 0xF800) >> 11)/31; - color[1] = (float)((pixel & 0x7E0) >> 5)/63; - color[2] = (float)(pixel & 0x1F)/31; - color[3] = 1.0f; -} - -static inline void sw_get_pixel_rgb_888(float *color, const void *pixels, uint32_t offset) -{ - const uint8_t *pixel = (const uint8_t *)pixels + 3*offset; - - color[0] = (float)pixel[0]*(1.0f/255); - color[1] = (float)pixel[1]*(1.0f/255); - color[2] = (float)pixel[2]*(1.0f/255); - color[3] = 1.0f; -} - -static inline void sw_get_pixel_rgb_161616(float *color, const void *pixels, uint32_t offset) -{ - const sw_half_t *pixel = (sw_half_t *)pixels + 3*offset; - - color[0] = sw_f16_to_f32(pixel[0]); - color[1] = sw_f16_to_f32(pixel[1]); - color[2] = sw_f16_to_f32(pixel[2]); - color[3] = 1.0f; -} - -static inline void sw_get_pixel_rgb_323232(float *color, const void *pixels, uint32_t offset) -{ - const float *pixel = (float *)pixels + 3*offset; - - color[0] = pixel[0]; - color[1] = pixel[1]; - color[2] = pixel[2]; - color[3] = 1.0f; -} - -static inline void sw_get_pixel_rgba_5551(float *color, const void *pixels, uint32_t offset) -{ - uint16_t pixel = ((uint16_t *)pixels)[offset]; - - color[0] = (float)((pixel & 0xF800) >> 11)/31; - color[1] = (float)((pixel & 0x7C0) >> 6)/31; - color[2] = (float)((pixel & 0x3E) >> 1)/31; - color[3] = (float)(pixel & 0x1); -} - -static inline void sw_get_pixel_rgba_4444(float *color, const void *pixels, uint32_t offset) -{ - uint16_t pixel = ((uint16_t *)pixels)[offset]; - - color[0] = (float)((pixel & 0xF000) >> 12)/15; - color[1] = (float)((pixel & 0xF00) >> 8)/15; - color[2] = (float)((pixel & 0xF0) >> 4)/15; - color[3] = (float)(pixel & 0xF)/15; -} - -static inline void sw_get_pixel_rgba_8888(float *color, const void *pixels, uint32_t offset) -{ - const uint8_t *pixel = (uint8_t *)pixels + 4*offset; - - color[0] = (float)pixel[0]*(1.0f/255); - color[1] = (float)pixel[1]*(1.0f/255); - color[2] = (float)pixel[2]*(1.0f/255); - color[3] = (float)pixel[3]*(1.0f/255); -} - -static inline void sw_get_pixel_rgba_16161616(float *color, const void *pixels, uint32_t offset) -{ - const sw_half_t *pixel = (sw_half_t *)pixels + 4*offset; - - color[0] = sw_f16_to_f32(pixel[0]); - color[1] = sw_f16_to_f32(pixel[1]); - color[2] = sw_f16_to_f32(pixel[2]); - color[3] = sw_f16_to_f32(pixel[3]); -} - -static inline void sw_get_pixel_rgba_32323232(float *color, const void *pixels, uint32_t offset) -{ - const float *pixel = (float *)pixels + 4*offset; - - color[0] = pixel[0]; - color[1] = pixel[1]; - color[2] = pixel[2]; - color[3] = pixel[3]; -} - -static inline void sw_get_pixel(float *color, const void *pixels, uint32_t offset, sw_pixelformat_t format) -{ - switch (format) - { - case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_get_pixel_grayscale(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: sw_get_pixel_grayscale_alpha(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5: sw_get_pixel_rgb_565(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: sw_get_pixel_rgb_888(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_get_pixel_rgba_5551(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_get_pixel_rgba_4444(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_get_pixel_rgba_8888(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_get_pixel_red_32(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_get_pixel_rgb_323232(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_get_pixel_rgba_32323232(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_get_pixel_red_16(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_get_pixel_rgb_161616(color, pixels, offset); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_get_pixel_rgba_16161616(color, pixels, offset); break; - case SW_PIXELFORMAT_UNKNOWN: break; - default: break; + { + uint16_t pixel = ((const uint16_t*)pixels)[offset]; + color[0] = ((pixel >> 11) & 0x1F)*255/31; // R (5 bits) + color[1] = ((pixel >> 6) & 0x1F)*255/31; // G (5 bits) + color[2] = ((pixel >> 1) & 0x1F)*255/31; // B (5 bits) + color[3] = (pixel & 0x01)*255; // A (1 bit) + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: + { + uint16_t pixel = ((const uint16_t*)pixels)[offset]; + color[0] = ((pixel >> 12) & 0x0F)*255/15; // R (4 bits) + color[1] = ((pixel >> 8) & 0x0F)*255/15; // G (4 bits) + color[2] = ((pixel >> 4) & 0x0F)*255/15; // B (4 bits) + color[3] = (pixel & 0x0F)*255/15; // A (4 bits) + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: + { + const uint8_t *src = &((const uint8_t*)pixels)[offset*4]; + color[0] = src[0]; + color[1] = src[1]; + color[2] = src[2]; + color[3] = src[3]; + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R32: + { + float val = ((const float*)pixels)[offset]; + uint8_t gray = (uint8_t)(val*255.0f); + color[0] = gray; + color[1] = gray; + color[2] = gray; + color[3] = 255; + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: + { + const float *src = &((const float*)pixels)[offset*3]; + color[0] = (uint8_t)(src[0]*255.0f); + color[1] = (uint8_t)(src[1]*255.0f); + color[2] = (uint8_t)(src[2]*255.0f); + color[3] = 255; + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: + { + const float *src = &((const float*)pixels)[offset*4]; + color[0] = (uint8_t)(src[0]*255.0f); + color[1] = (uint8_t)(src[1]*255.0f); + color[2] = (uint8_t)(src[2]*255.0f); + color[3] = (uint8_t)(src[3]*255.0f); + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R16: + { + uint16_t val = ((const uint16_t*)pixels)[offset]; + uint8_t gray = sw_half_to_float(val)/255.0f; + color[0] = gray; + color[1] = gray; + color[2] = gray; + color[3] = 255; + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: + { + const uint16_t *src = &((const uint16_t*)pixels)[offset*3]; + color[0] = sw_half_to_float(src[0])/255.0f; + color[1] = sw_half_to_float(src[1])/255.0f; + color[2] = sw_half_to_float(src[2])/255.0f; + color[3] = 255; + break; + } + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: + { + const uint16_t *src = &((const uint16_t*)pixels)[offset*4]; + color[0] = sw_half_to_float(src[0])/255.0f; + color[1] = sw_half_to_float(src[1])/255.0f; + color[2] = sw_half_to_float(src[2])/255.0f; + color[3] = sw_half_to_float(src[3])/255.0f; + break; + } + case SW_PIXELFORMAT_UNKNOWN: + default: + { + color[0] = 0; + color[1] = 0; + color[2] = 0; + color[3] = 0; + break; + } } } // Texture sampling functionality +static inline void sw_texture_fetch(float* color, const sw_texture_t* tex, int x, int y) +{ + sw_float_from_unorm8_simd(color, &tex->pixels[4*(y*tex->width + x)]); +} + static inline void sw_texture_sample_nearest(float *color, const sw_texture_t *tex, float u, float v) { u = (tex->sWrap == SW_REPEAT)? sw_fract(u) : sw_saturate(u); v = (tex->tWrap == SW_REPEAT)? sw_fract(v) : sw_saturate(v); - int x = u*tex->width, y = v*tex->height; + int x = u*tex->width; + int y = v*tex->height; - sw_get_pixel(color, tex->pixels.cptr, y*tex->width + x, tex->format); + sw_texture_fetch(color, tex, x, y); } static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v) { - // TODO: REVIEW: With a bit more cleverness we could clearly reduce the + // TODO: With a bit more cleverness we could clearly reduce the // number of operations here, but for now it works fine. - float xf = u*tex->width - 0.5f; - float yf = v*tex->height - 0.5f; + float xf = (u*tex->width) - 0.5f; + float yf = (v*tex->height) - 0.5f; - int x0 = (int)floorf(xf); - int y0 = (int)floorf(yf); + float fx = sw_fract(xf); + float fy = sw_fract(yf); - float fx = xf - x0; - float fy = yf - y0; + int x0 = (int)xf; + int y0 = (int)yf; int x1 = x0 + 1; int y1 = y0 + 1; + // NOTE: If the textures are POT we could avoid the division for SW_REPEAT + if (tex->sWrap == SW_CLAMP) { x0 = (x0 > tex->wMinus1)? tex->wMinus1 : x0; @@ -2212,10 +1981,10 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te } float c00[4], c10[4], c01[4], c11[4]; - sw_get_pixel(c00, tex->pixels.cptr, y0*tex->width + x0, tex->format); - sw_get_pixel(c10, tex->pixels.cptr, y0*tex->width + x1, tex->format); - sw_get_pixel(c01, tex->pixels.cptr, y1*tex->width + x0, tex->format); - sw_get_pixel(c11, tex->pixels.cptr, y1*tex->width + x1, tex->format); + sw_texture_fetch(c00, tex, x0, y0); + sw_texture_fetch(c10, tex, x1, y0); + sw_texture_fetch(c01, tex, x0, y1); + sw_texture_fetch(c11, tex, x1, y1); for (int i = 0; i < 4; i++) { @@ -2512,23 +2281,23 @@ static inline void sw_triangle_clip_and_project(void) // Calculation of the reciprocal of W for normalization // as well as perspective-correct attributes - const float invW = 1.0f/v->homogeneous[3]; - v->homogeneous[3] = invW; + const float wRcp = 1.0f/v->homogeneous[3]; + v->homogeneous[3] = wRcp; // Division of XYZ coordinates by weight - v->homogeneous[0] *= invW; - v->homogeneous[1] *= invW; - v->homogeneous[2] *= invW; + v->homogeneous[0] *= wRcp; + v->homogeneous[1] *= wRcp; + v->homogeneous[2] *= wRcp; // Division of texture coordinates (perspective-correct) - v->texcoord[0] *= invW; - v->texcoord[1] *= invW; + v->texcoord[0] *= wRcp; + v->texcoord[1] *= wRcp; // Division of colors (perspective-correct) - v->color[0] *= invW; - v->color[1] *= invW; - v->color[2] *= invW; - v->color[3] *= invW; + v->color[0] *= wRcp; + v->color[1] *= wRcp; + v->color[2] *= wRcp; + v->color[3] *= wRcp; // Transformation to screen space sw_project_ndc_to_screen(v->screen, v->homogeneous); @@ -2583,8 +2352,8 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, } \ \ /* Pre-calculate the starting pointers for the framebuffer row */ \ - void *cptr = sw_framebuffer_get_color_addr(RLSW.framebuffer.color, y*RLSW.framebuffer.width + xStart); \ - void *dptr = sw_framebuffer_get_depth_addr(RLSW.framebuffer.depth, y*RLSW.framebuffer.width + xStart); \ + void *cptr = GET_COLOR_PTR(RLSW.framebuffer.color, y*RLSW.framebuffer.width + xStart); \ + void *dptr = GET_DEPTH_PTR(RLSW.framebuffer.depth, y*RLSW.framebuffer.width + xStart); \ \ /* Scanline rasterization */ \ for (int x = xStart; x < xEnd; x++) \ @@ -2624,12 +2393,7 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, { \ float dstColor[4]; \ sw_framebuffer_read_color(dstColor, cptr); \ - \ sw_blend_colors(dstColor, srcColor); \ - dstColor[0] = sw_saturate(dstColor[0]); \ - dstColor[1] = sw_saturate(dstColor[1]); \ - dstColor[2] = sw_saturate(dstColor[2]); \ - \ sw_framebuffer_write_color(cptr, dstColor); \ } \ else \ @@ -2651,8 +2415,8 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, v += dvDx; \ } \ \ - sw_framebuffer_inc_color_addr(&cptr); \ - sw_framebuffer_inc_depth_addr(&dptr); \ + INC_COLOR_PTR(cptr); \ + INC_DEPTH_PTR(dptr); \ } \ } @@ -2777,13 +2541,17 @@ static inline void sw_triangle_render(void) } \ } - if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH_BLEND) - else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH_BLEND) - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_BLEND) - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH) - else if (SW_STATE_CHECK(SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_BLEND) - else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH) - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D)) TRIANGLE_RASTER(sw_triangle_raster_TEX) + uint32_t state = RLSW.stateFlags; + if (RLSW.currentTexture == 0) state &= ~SW_STATE_TEXTURE_2D; + if ((RLSW.srcFactor == SW_ONE) && (RLSW.dstFactor == SW_ZERO)) state &= ~SW_STATE_BLEND; + + if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH) + else if (SW_STATE_CHECK_EX(state, SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH) + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D)) TRIANGLE_RASTER(sw_triangle_raster_TEX) else TRIANGLE_RASTER(sw_triangle_raster) #undef TRIANGLE_RASTER @@ -2859,23 +2627,23 @@ static inline void sw_quad_clip_and_project(void) // Calculation of the reciprocal of W for normalization // as well as perspective-correct attributes - const float invW = 1.0f/v->homogeneous[3]; - v->homogeneous[3] = invW; + const float wRcp = 1.0f/v->homogeneous[3]; + v->homogeneous[3] = wRcp; // Division of XYZ coordinates by weight - v->homogeneous[0] *= invW; - v->homogeneous[1] *= invW; - v->homogeneous[2] *= invW; + v->homogeneous[0] *= wRcp; + v->homogeneous[1] *= wRcp; + v->homogeneous[2] *= wRcp; // Division of texture coordinates (perspective-correct) - v->texcoord[0] *= invW; - v->texcoord[1] *= invW; + v->texcoord[0] *= wRcp; + v->texcoord[1] *= wRcp; // Division of colors (perspective-correct) - v->color[0] *= invW; - v->color[1] *= invW; - v->color[2] *= invW; - v->color[3] *= invW; + v->color[0] *= wRcp; + v->color[1] *= wRcp; + v->color[2] *= wRcp; + v->color[3] *= wRcp; // Transformation to screen space sw_project_ndc_to_screen(v->screen, v->homogeneous); @@ -2908,76 +2676,40 @@ static inline bool sw_quad_is_axis_aligned(void) static inline void sw_quad_sort_cw(const sw_vertex_t* *output) { - // Sort 4 quad vertices into clockwise order with fixed layout: - // - // v0 -- v1 - // | | - // v3 -- v2 - // - // The goal is: - // - v0: top-left (minimum Y, then minimum X) - // - v1: top-right (minimum Y row, maximum X) - // - v2: bottom-right (maximum Y, maximum X) - // - v3: bottom-left (maximum Y, minimum X) const sw_vertex_t *input = RLSW.vertexBuffer; - // Separate vertices into top and bottom based on Y-coordinate - const sw_vertex_t *top[2] = {NULL, NULL}; - const sw_vertex_t *bottom[2] = {NULL, NULL}; - int topCount = 0, bottomCount = 0; + // Calculate the centroid of the quad + float cx = (input[0].screen[0] + input[1].screen[0] + + input[2].screen[0] + input[3].screen[0])*0.25f; + float cy = (input[0].screen[1] + input[1].screen[1] + + input[2].screen[1] + input[3].screen[1])*0.25f; - // Find minimum and maximum Y - float minY = input[0].screen[1]; - float maxY = input[0].screen[1]; + // Calculate the angle of each vertex relative to the center + // and assign them directly to their correct position + const sw_vertex_t *corners[4] = { 0 }; - for (int i = 1; i < 4; i++) - { - if (input[i].screen[1] < minY) minY = input[i].screen[1]; - if (input[i].screen[1] > maxY) maxY = input[i].screen[1]; - } - - // Separate vertices based on Y-coordinate for (int i = 0; i < 4; i++) { - if ((input[i].screen[1] == minY) && (topCount < 2)) top[topCount++] = &input[i]; - else if ((input[i].screen[1] == maxY) && (bottomCount < 2)) bottom[bottomCount++] = &input[i]; + float dx = input[i].screen[0] - cx; + float dy = input[i].screen[1] - cy; + + // Determine the quadrant (clockwise from top-left) + // top-left: dx < 0, dy < 0 + // top-right: dx >= 0, dy < 0 + // bottom-right: dx >= 0, dy >= 0 + // bottom-left: dx < 0, dy >= 0 + + int idx; + if (dy < 0) idx = (dx < 0)? 0 : 1; // Top row + else idx = (dx < 0)? 3 : 2; // Bottom row + + corners[idx] = &input[i]; } - // If we don't have enough top/bottom vertices (e.g., Y values are all different), - // classify vertices as top or bottom based on whether they're closer to minY or maxY - for (int i = 0; i < 4; i++) - { - if ((topCount < 2) && (&input[i] != top[0]) && (&input[i] != bottom[0]) && (&input[i] != bottom[1])) - { - if (fabsf(input[i].screen[1] - minY) <= fabsf(input[i].screen[1] - maxY)) top[topCount++] = &input[i]; - } - if ((bottomCount < 2) && (&input[i] != top[0]) && (&input[i] != top[1]) && (&input[i] != bottom[0])) - { - if (fabsf(input[i].screen[1] - maxY) < fabsf(input[i].screen[1] - minY)) bottom[bottomCount++] = &input[i]; - } - } - - // Sort top vertices by X (left to right) - if ((topCount == 2) && (top[0]->screen[0] > top[1]->screen[0])) - { - const sw_vertex_t *temp = top[0]; - top[0] = top[1]; - top[1] = temp; - } - - // Sort bottom vertices by X (left to right) - if ((bottomCount == 2) && (bottom[0]->screen[0] > bottom[1]->screen[0])) - { - const sw_vertex_t *temp = bottom[0]; - bottom[0] = bottom[1]; - bottom[1] = temp; - } - - // Assign vertices in clockwise order as per the required layout - output[0] = top[0]; // v0: top-left - output[1] = top[topCount-1]; // v1: top-right - output[2] = bottom[bottomCount-1]; // v2: bottom-right - output[3] = bottom[0]; // v3: bottom-left + output[0] = corners[0]; // top-left + output[1] = corners[1]; // top-right + output[2] = corners[2]; // bottom-right + output[3] = corners[3]; // bottom-left } // TODO: REVIEW: Could a perfectly aligned quad, where one of the four points has a different depth, @@ -3052,8 +2784,8 @@ static inline void FUNC_NAME(void) \ for (int y = yMin; y < yMax; y++) \ { \ - void *cptr = sw_framebuffer_get_color_addr(cDstBase, y*wDst + xMin); \ - void *dptr = sw_framebuffer_get_depth_addr(dDstBase, y*wDst + xMin); \ + void *cptr = GET_COLOR_PTR(cDstBase, y*wDst + xMin); \ + void *dptr = GET_DEPTH_PTR(dDstBase, y*wDst + xMin); \ \ float z = zScanline; \ float u = uScanline; \ @@ -3101,13 +2833,7 @@ static inline void FUNC_NAME(void) { \ float dstColor[4]; \ sw_framebuffer_read_color(dstColor, cptr); \ - \ sw_blend_colors(dstColor, srcColor); \ - dstColor[0] = sw_saturate(dstColor[0]); \ - dstColor[1] = sw_saturate(dstColor[1]); \ - dstColor[2] = sw_saturate(dstColor[2]); \ - dstColor[3] = sw_saturate(dstColor[3]); \ - \ sw_framebuffer_write_color(cptr, dstColor); \ } \ else sw_framebuffer_write_color(cptr, srcColor); \ @@ -3125,8 +2851,8 @@ static inline void FUNC_NAME(void) v += tcDx[1]; \ } \ \ - sw_framebuffer_inc_color_addr(&cptr); \ - sw_framebuffer_inc_depth_addr(&dptr); \ + INC_COLOR_PTR(cptr); \ + INC_DEPTH_PTR(dptr); \ } \ \ zScanline += zDy; \ @@ -3163,15 +2889,19 @@ static inline void sw_quad_render(void) if (RLSW.vertexCounter < 3) return; + uint32_t state = RLSW.stateFlags; + if (RLSW.currentTexture == 0) state &= ~SW_STATE_TEXTURE_2D; + if ((RLSW.srcFactor == SW_ONE) && (RLSW.dstFactor == SW_ZERO)) state &= ~SW_STATE_BLEND; + if ((RLSW.vertexCounter == 4) && sw_quad_is_axis_aligned()) { - if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_TEX_DEPTH_BLEND(); - else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_DEPTH_BLEND(); - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_TEX_BLEND(); - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST)) sw_quad_raster_axis_aligned_TEX_DEPTH(); - else if (SW_STATE_CHECK(SW_STATE_BLEND)) sw_quad_raster_axis_aligned_BLEND(); - else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST)) sw_quad_raster_axis_aligned_DEPTH(); - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D)) sw_quad_raster_axis_aligned_TEX(); + if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_TEX_DEPTH_BLEND(); + else if (SW_STATE_CHECK_EX(state, SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_DEPTH_BLEND(); + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_BLEND)) sw_quad_raster_axis_aligned_TEX_BLEND(); + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST)) sw_quad_raster_axis_aligned_TEX_DEPTH(); + else if (SW_STATE_CHECK_EX(state, SW_STATE_BLEND)) sw_quad_raster_axis_aligned_BLEND(); + else if (SW_STATE_CHECK_EX(state, SW_STATE_DEPTH_TEST)) sw_quad_raster_axis_aligned_DEPTH(); + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D)) sw_quad_raster_axis_aligned_TEX(); else sw_quad_raster_axis_aligned(); return; } @@ -3189,13 +2919,13 @@ static inline void sw_quad_render(void) } \ } - if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH_BLEND) - else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH_BLEND) - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_BLEND) - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH) - else if (SW_STATE_CHECK(SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_BLEND) - else if (SW_STATE_CHECK(SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH) - else if (SW_STATE_CHECK(SW_STATE_TEXTURE_2D)) TRIANGLE_RASTER(sw_triangle_raster_TEX) + if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_DEPTH_TEST | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_TEX_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D | SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_TEX_DEPTH) + else if (SW_STATE_CHECK_EX(state, SW_STATE_BLEND)) TRIANGLE_RASTER(sw_triangle_raster_BLEND) + else if (SW_STATE_CHECK_EX(state, SW_STATE_DEPTH_TEST)) TRIANGLE_RASTER(sw_triangle_raster_DEPTH) + else if (SW_STATE_CHECK_EX(state, SW_STATE_TEXTURE_2D)) TRIANGLE_RASTER(sw_triangle_raster_TEX) else TRIANGLE_RASTER(sw_triangle_raster) #undef TRIANGLE_RASTER @@ -3310,7 +3040,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ int dy = y2 - y1; \ \ /* Handling of lines that are more horizontal or vertical */ \ - if ((dx == 0) && (dy == 0)) \ + if ((dx == 0) && (dy == 0)) \ { \ /* TODO: A point should be rendered here */ \ return; \ @@ -3366,8 +3096,8 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ for (int i = 0; i != longLen; i += sgnInc) \ { \ int offset = (y1 + i)*fbWidth + (x1 + (j >> 16)); \ - void *dptr = sw_framebuffer_get_depth_addr(dBuffer, offset); \ - void *cptr; \ + void *dptr = GET_DEPTH_PTR(dBuffer, offset); \ + void *cptr = NULL; \ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -3377,13 +3107,12 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ \ sw_framebuffer_write_depth(dptr, z); \ \ - cptr = sw_framebuffer_get_color_addr(cBuffer, offset); \ + cptr = GET_COLOR_PTR(cBuffer, offset); \ \ if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ sw_framebuffer_read_color(dstColor, cptr); \ - \ sw_blend_colors(dstColor, color); \ sw_framebuffer_write_color(cptr, dstColor); \ } \ @@ -3403,8 +3132,8 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ for (int i = 0; i != longLen; i += sgnInc) \ { \ int offset = (y1 + (j >> 16))*fbWidth + (x1 + i); \ - void *dptr = sw_framebuffer_get_depth_addr(dBuffer, offset); \ - void *cptr; \ + void *dptr = GET_DEPTH_PTR(dBuffer, offset); \ + void *cptr = NULL; \ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -3414,17 +3143,16 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ \ sw_framebuffer_write_depth(dptr, z); \ \ - cptr = sw_framebuffer_get_color_addr(cBuffer, offset); \ + cptr = GET_COLOR_PTR(cBuffer, offset); \ \ if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ sw_framebuffer_read_color(dstColor, cptr); \ - \ sw_blend_colors(dstColor, color); \ sw_framebuffer_write_color(cptr, dstColor); \ } \ - else sw_framebuffer_write_color(cptr, color); \ + else sw_framebuffer_write_color(cptr, color); \ \ discardB: \ j += decInc; \ @@ -3570,7 +3298,7 @@ static inline void FUNC_NAME(int x, int y, float z, const float color[4]) \ \ int offset = y*RLSW.framebuffer.width + x; \ \ - void *dptr = sw_framebuffer_get_depth_addr(RLSW.framebuffer.depth, offset); \ + void *dptr = GET_DEPTH_PTR(RLSW.framebuffer.depth, offset); \ \ if (ENABLE_DEPTH_TEST) \ { \ @@ -3580,13 +3308,12 @@ static inline void FUNC_NAME(int x, int y, float z, const float color[4]) \ \ sw_framebuffer_write_depth(dptr, z); \ \ - void *cptr = sw_framebuffer_get_color_addr(RLSW.framebuffer.color, offset); \ + void *cptr = GET_COLOR_PTR(RLSW.framebuffer.color, offset); \ \ if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ sw_framebuffer_read_color(dstColor, cptr); \ - \ sw_blend_colors(dstColor, color); \ sw_framebuffer_write_color(cptr, dstColor); \ } \ @@ -3724,7 +3451,7 @@ static inline bool sw_is_texture_valid(uint32_t id) if (id == 0) valid = false; else if (id >= SW_MAX_TEXTURES) valid = false; - else if (RLSW.loadedTextures[id].pixels.cptr == 0) valid = false; + else if (RLSW.loadedTextures[id].pixels == NULL) valid = false; return true; } @@ -3872,26 +3599,24 @@ bool swInit(int w, int h) RLSW.polyMode = SW_FILL; RLSW.cullFace = SW_BACK; - static const float defTex[3*2*2] = { - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, + static uint32_t defaultTex[3*2*2] = { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF }; - RLSW.loadedTextures[0].pixels.cptr = defTex; + RLSW.loadedTextures[0].pixels = (uint8_t*)defaultTex; RLSW.loadedTextures[0].width = 2; RLSW.loadedTextures[0].height = 2; RLSW.loadedTextures[0].wMinus1 = 1; RLSW.loadedTextures[0].hMinus1 = 1; - RLSW.loadedTextures[0].format = SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32; RLSW.loadedTextures[0].minFilter = SW_NEAREST; RLSW.loadedTextures[0].magFilter = SW_NEAREST; RLSW.loadedTextures[0].sWrap = SW_REPEAT; RLSW.loadedTextures[0].tWrap = SW_REPEAT; RLSW.loadedTextures[0].tx = 0.5f; RLSW.loadedTextures[0].ty = 0.5f; - RLSW.loadedTextures[0].copy = false; RLSW.loadedTextureCount = 1; @@ -3900,10 +3625,13 @@ bool swInit(int w, int h) void swClose(void) { + // NOTE: Starts at texture 1, texture 0 does not have to be freed for (int i = 1; i < RLSW.loadedTextureCount; i++) { - sw_texture_t *texture = &RLSW.loadedTextures[i]; - if (sw_is_texture_valid(i) && texture->copy) SW_FREE(texture->pixels.ptr); + if (sw_is_texture_valid(i)) + { + SW_FREE(RLSW.loadedTextures[i].pixels); + } } SW_FREE(RLSW.framebuffer.color); @@ -3950,13 +3678,16 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_copy_to_R5G5B5A1(x, y, w, h, (uint16_t *)pixels); break; case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_copy_to_R4G4B4A4(x, y, w, h, (uint16_t *)pixels); break; case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_copy_to_R8G8B8A8(x, y, w, h, (uint8_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_framebuffer_copy_to_R32(x, y, w, h, (float *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_framebuffer_copy_to_R32G32B32(x, y, w, h, (float *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_framebuffer_copy_to_R32G32B32A32(x, y, w, h, (float *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_framebuffer_copy_to_R16(x, y, w, h, (sw_half_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_framebuffer_copy_to_R16G16B16(x, y, w, h, (sw_half_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_framebuffer_copy_to_R16G16B16A16(x, y, w, h, (sw_half_t *)pixels); break; - default: RLSW.errCode = SW_INVALID_ENUM; break; + // Below: not implemented + case SW_PIXELFORMAT_UNCOMPRESSED_R32: + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: + case SW_PIXELFORMAT_UNCOMPRESSED_R16: + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: + default: + RLSW.errCode = SW_INVALID_ENUM; + break; } } @@ -3991,13 +3722,16 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_blit_to_R5G5B5A1(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break; case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_blit_to_R4G4B4A4(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint16_t *)pixels); break; case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_blit_to_R8G8B8A8(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32: sw_framebuffer_blit_to_R32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: sw_framebuffer_blit_to_R32G32B32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (float *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: sw_framebuffer_blit_to_R32G32B32A32(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (float*)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16: sw_framebuffer_blit_to_R16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (sw_half_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: sw_framebuffer_blit_to_R16G16B16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (sw_half_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: sw_framebuffer_blit_to_R16G16B16A16(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (sw_half_t *)pixels); break; - default: RLSW.errCode = SW_INVALID_ENUM; break; + // Below: not implemented + case SW_PIXELFORMAT_UNCOMPRESSED_R32: + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: + case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: + case SW_PIXELFORMAT_UNCOMPRESSED_R16: + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: + case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: + default: + RLSW.errCode = SW_INVALID_ENUM; + break; } } @@ -4814,17 +4548,14 @@ void swDeleteTextures(int count, uint32_t *textures) continue; } - if (RLSW.loadedTextures[textures[i]].copy) - { - SW_FREE(RLSW.loadedTextures[textures[i]].pixels.ptr); - } + SW_FREE(RLSW.loadedTextures[textures[i]].pixels); - RLSW.loadedTextures[textures[i]].pixels.cptr = NULL; + RLSW.loadedTextures[textures[i]].pixels = NULL; RLSW.freeTextureIds[RLSW.freeTextureIdCount++] = textures[i]; } } -void swTexImage2D(int width, int height, SWformat format, SWtype type, bool copy, const void *data) +void swTexImage2D(int width, int height, SWformat format, SWtype type, const void *data) { uint32_t id = RLSW.currentTexture; @@ -4844,33 +4575,27 @@ void swTexImage2D(int width, int height, SWformat format, SWtype type, bool copy sw_texture_t *texture = &RLSW.loadedTextures[id]; - if (copy) + int size = width*height; + texture->pixels = SW_MALLOC(4*size); + + if (texture->pixels == NULL) { - int bytes = sw_get_pixel_bytes((sw_pixelformat_t)pixelFormat); - int size = bytes*width*height; - texture->pixels.ptr = SW_MALLOC(size); + RLSW.errCode = SW_STACK_OVERFLOW; // WARNING: Out of memory... + return; + } - if (texture->pixels.ptr == NULL) - { - RLSW.errCode = SW_STACK_OVERFLOW; // WARING: Out of memory... - return; - } - - for (int i = 0; i < size; i++) - { - ((uint8_t *)texture->pixels.ptr)[i] = ((uint8_t *)data)[i]; - } + for (int i = 0; i < size; i++) + { + uint32_t *dst = &((uint32_t*)texture->pixels)[i]; + sw_get_pixel((uint8_t*)dst, data, i, pixelFormat); } - else texture->pixels.cptr = data; texture->width = width; texture->height = height; texture->wMinus1 = width - 1; texture->hMinus1 = height - 1; - texture->format = (sw_pixelformat_t)pixelFormat; texture->tx = 1.0f/width; texture->ty = 1.0f/height; - texture->copy = copy; } void swTexParameteri(int param, int value) @@ -4939,7 +4664,7 @@ void swBindTexture(uint32_t id) return; } - if (RLSW.loadedTextures[id].pixels.cptr == NULL) + if (RLSW.loadedTextures[id].pixels == NULL) { RLSW.errCode = SW_INVALID_OPERATION; return; From 4bb8c89084930862b70042845166739cf058e883 Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Sat, 25 Oct 2025 00:49:31 -0700 Subject: [PATCH 006/189] Don't undefine the versions of LoadImage that don't conflict with raylib so that the Win32 platform can use them. (#5299) --- src/platforms/rcore_desktop_win32.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 9b66f8c4b..5b67c72b0 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -49,8 +49,6 @@ #define CloseWindow CloseWindowWin32 #define Rectangle RectangleWin32 #define ShowCursor ShowCursorWin32 -#define LoadImageA LoadImageAWin32 -#define LoadImageW LoadImageWin32 #define DrawTextA DrawTextAWin32 #define DrawTextW DrawTextWin32 #define DrawTextExA DrawTextExAWin32 @@ -63,8 +61,6 @@ #undef Rectangle // raylib symbol collision #undef ShowCursor // raylib symbol collision #undef LoadImage // raylib symbol collision -#undef LoadImageA -#undef LoadImageW #undef DrawText // raylib symbol collision #undef DrawTextA #undef DrawTextW @@ -1529,7 +1525,7 @@ int InitPlatform(void) // Load user-provided icon if available // NOTE: raylib resource file defaults to GLFW_ICON id, so looking for same identifier windowClass.hIcon = LoadImageW(hInstance, L"GLFW_ICON", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); - if (!windowClass.hIcon) windowClass.hIcon = LoadImageW(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + if (!windowClass.hIcon) windowClass.hIcon = LoadImageW(NULL, (LPCWSTR)IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); // Register window class result = (int)RegisterClassExW(&windowClass); From dbcc5081964cb2413b32eecf2135d73e32420285 Mon Sep 17 00:00:00 2001 From: themushroompirates <59015901+themushroompirates@users.noreply.github.com> Date: Sat, 25 Oct 2025 10:41:39 +0200 Subject: [PATCH 007/189] [examples] Added `models_decals` (#5298) * Added decal models example * Code formatting to match Raylib conventions --- examples/models/models_decals.c | 573 +++ examples/models/models_decals.png | Bin 0 -> 62387 bytes .../models/resources/models/obj/character.mtl | 12 + .../models/resources/models/obj/character.obj | 3454 +++++++++++++++++ .../models/obj/character_diffuse.png | Bin 0 -> 41705 bytes examples/models/resources/raylib_logo.png | Bin 0 -> 3672 bytes 6 files changed, 4039 insertions(+) create mode 100644 examples/models/models_decals.c create mode 100644 examples/models/models_decals.png create mode 100644 examples/models/resources/models/obj/character.mtl create mode 100644 examples/models/resources/models/obj/character.obj create mode 100644 examples/models/resources/models/obj/character_diffuse.png create mode 100644 examples/models/resources/raylib_logo.png diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c new file mode 100644 index 000000000..81bbd2796 --- /dev/null +++ b/examples/models/models_decals.c @@ -0,0 +1,573 @@ +/******************************************************************************************* +* +* raylib [models] example - decals +* +* Example complexity rating: [★★★☆] 3/4 +* +* Example originally created with raylib 5.6-dev +* +* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5) +* Based on previous work by @mrdoob +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 JP Mortiboys (@themushroompirates) and Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" + +#include + +#undef FLT_MAX +#define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111 + +#define MAX_DECALS 256 + +typedef struct MeshBuilder { + int vertexCount; + int vertexCapacity; + Vector3 *vertices; + Vector2 *uvs; +} MeshBuilder; + +// Utility functions +void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]); +void FreeMeshBuilder(MeshBuilder *mb); +Mesh BuildMesh(MeshBuilder *mb); + +Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); + +Mesh GenMeshDecal(Mesh inputMesh, Ray ray); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "raylib [models] example - decals"); + + // 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, 1.0f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.6f, 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 character model + Model model = LoadModel("resources/models/obj/character.obj"); + + // Apply character skin + Texture2D modelTexture = LoadTexture("resources/models/obj/character_diffuse.png"); // Load model texture + SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR); + model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture; // Set model diffuse texture + + + BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]); // Get mesh bounding box + + camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f); + camera.position = Vector3Scale(modelBBox.max, 1.0f); + camera.position.x *= 0.1f; + + float modelSize = fminf( + fminf(fabsf(modelBBox.max.x - modelBBox.min.x), + fabsf(modelBBox.max.y - modelBBox.min.y)), + fabsf(modelBBox.max.z - modelBBox.min.z) + ); + + camera.position = (Vector3){ 0, modelBBox.max.y * 1.2f, modelSize * 3.0f }; + + float decalSize = modelSize * .25f; + float decalOffset = 0.01f; + + Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize)); + placementCube.materials[0].maps[0].color = LIME; + + Material decalMaterial = LoadMaterialDefault(); + decalMaterial.maps[0].color = YELLOW; + + Image decalImage = LoadImage("resources/raylib_logo.png"); + ImageResizeNN(&decalImage, decalImage.width / 4, decalImage.height / 4); + Texture decalTexture = LoadTextureFromImage(decalImage); + UnloadImage(decalImage); + + SetTextureFilter(decalTexture, TEXTURE_FILTER_BILINEAR); + decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture; + decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE; + + // We're going to use these to build up our decal meshes + // They'll resize automatically as we go, we'll free them at the end + MeshBuilder mesh_builders[2] = { {0}, {0} }; + + bool showModel = true; + Model decalModels[MAX_DECALS] = {0}; + int decalCount = 0; + + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + + if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) { + UpdateCamera(&camera, CAMERA_THIRD_PERSON); + } + + if (IsKeyPressed(KEY_SPACE)) { + showModel = !showModel; + } + + // Display information about closest hit + RayCollision collision = { 0 }; + collision.distance = FLT_MAX; + collision.hit = false; + + // Get mouse ray + Ray ray = GetScreenToWorldRay(GetMousePosition(), camera); + + // Check ray collision against bounding box first, before trying the full ray-mesh test + RayCollision boxHitInfo = GetRayCollisionBox(ray, modelBBox); + + if ((boxHitInfo.hit) && decalCount < MAX_DECALS) + { + // Check ray collision against model meshes + RayCollision meshHitInfo = { 0 }; + for (int m = 0; m < model.meshCount; m++) + { + // NOTE: We consider the model.transform for the collision check but + // it can be checked against any transform Matrix, used when checking against same + // model drawn multiple times with multiple transforms + meshHitInfo = GetRayCollisionMesh(ray, model.meshes[m], model.transform); + if (meshHitInfo.hit) + { + // Save the closest hit mesh + if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo; + } + } + + if (meshHitInfo.hit) + { + collision = meshHitInfo; + } + } + + // -------------- + + if (collision.hit && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && decalCount < MAX_DECALS) + { + + // Create the transformation to project the decal + Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); + Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0}); + + // Spin the placement around a bit + splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD * ((float)GetRandomValue(-180, 180)))); + + Matrix splatInv = MatrixInvert(splat); + + // Reset the mesh builders + mesh_builders[0].vertexCount = 0; + mesh_builders[1].vertexCount = 0; + + // We'll be flip-flopping between the two mesh builders + // Reading from one and writing to the other, then swapping + int mb_index = 0; + + // First pass, just get any triangle inside the bounding box + // (for each mesh of the model) + for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++) { + Mesh mesh = model.meshes[meshIndex]; + for (int tri = 0; tri < mesh.triangleCount; tri++) + { + Vector3 vertices[3]; + + // The way we calculate the vertices of the mesh triangle + // depend on whether the mesh vertices are indexed or not + if (mesh.indices == 0) + { + for (int v = 0; v < 3; v++) { + vertices[v] = (Vector3) { + mesh.vertices[3*3*tri + 3*v + 0], + mesh.vertices[3*3*tri + 3*v + 1], + mesh.vertices[3*3*tri + 3*v + 2] + }; + } + } + else + { + for (int v = 0; v < 3; v++) + { + vertices[v] = (Vector3) { + mesh.vertices[ 3*mesh.indices[3*tri+0] + v], + mesh.vertices[ 3*mesh.indices[3*tri+1] + v], + mesh.vertices[ 3*mesh.indices[3*tri+2] + v] + }; + } + } + + // Transform all 3 vertices of the triangle + // and check if they are inside our decal box + int insideCount = 0; + for (int i = 0; i < 3; i++) + { + // To splat space + Vector3 v = Vector3Transform(vertices[i], splat); + + if (fabsf(v.x) 0) + { + AddTriangleToMeshBuilder(&mesh_builders[mb_index], vertices); + } + } + } + + // Clipping time! We need to clip against all 6 directions + Vector3 planes[6] = { + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 1, 0 }, + { 0, -1, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 } + }; + for (int face = 0; face < 6; face++) + { + // Swap current model builder (so we read from the one we just wrote to) + mb_index = 1 - mb_index; + + MeshBuilder *inMesh = &mesh_builders[1-mb_index]; + MeshBuilder *outMesh = &mesh_builders[mb_index]; + + // Reset write builder + outMesh->vertexCount = 0; + + float s = 0.5f * decalSize; + + for (int i = 0; i < inMesh->vertexCount; i+=3) + { + Vector3 nV1, nV2, nV3, nV4; + + float d1 = Vector3DotProduct(inMesh->vertices[ i + 0 ], planes[face] ) - s; + float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s; + float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s; + + int v1Out = d1 > 0; + int v2Out = d2 > 0; + int v3Out = d3 > 0; + + // calculate, how many vertices of the face lie outside of the clipping plane + int total = v1Out + v2Out + v3Out; + + switch ( total ) { + case 0: { + // the entire face lies inside of the plane, no clipping needed + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]}); + break; + } + + case 1: { + // one vertex lies outside of the plane, perform clipping + + if (v1Out) { + nV1 = inMesh->vertices[ i + 1 ]; + nV2 = inMesh->vertices[ i + 2 ]; + nV3 = ClipSegment( inMesh->vertices[ i ], nV1, planes[face], s ); + nV4 = ClipSegment( inMesh->vertices[ i ], nV2, planes[face], s ); + } + + if (v2Out) { + nV1 = inMesh->vertices[ i ]; + nV2 = inMesh->vertices[ i + 2 ]; + nV3 = ClipSegment( inMesh->vertices[ i + 1 ], nV1, planes[face], s ); + nV4 = ClipSegment( inMesh->vertices[ i + 1 ], nV2, planes[face], s ); + + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1}); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4}); + break; + } + + if (v3Out) { + nV1 = inMesh->vertices[ i ]; + nV2 = inMesh->vertices[ i + 1 ]; + nV3 = ClipSegment( inMesh->vertices[ i + 2 ], nV1, planes[face], s ); + nV4 = ClipSegment( inMesh->vertices[ i + 2 ], nV2, planes[face], s ); + } + + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2}); + + break; + } + + case 2: { + // two vertices lies outside of the plane, perform clipping + if (!v1Out) { + nV1 = inMesh->vertices[ i ]; + nV2 = ClipSegment( nV1, inMesh->vertices[ i + 1 ], planes[face], s ); + nV3 = ClipSegment( nV1, inMesh->vertices[ i + 2 ], planes[face], s ); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + } + if (!v2Out) { + nV1 = inMesh->vertices[ i + 1 ]; + nV2 = ClipSegment( nV1, inMesh->vertices[ i + 2 ], planes[face], s ); + nV3 = ClipSegment( nV1, inMesh->vertices[ i ], planes[face], s ); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + } + if (!v3Out) { + nV1 = inMesh->vertices[ i + 2 ]; + nV2 = ClipSegment( nV1, inMesh->vertices[ i ], planes[face], s ); + nV3 = ClipSegment( nV1, inMesh->vertices[ i + 1 ], planes[face], s ); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + } + break; + } + + case 3: { + // the entire face lies outside of the plane, so let's discard the corresponding vertices + break; + } + + } + } + } + + // Now we just need to re-transform the vertices + MeshBuilder *theMesh = &mesh_builders[mb_index]; + + // Allocate room for UVs + if (theMesh->vertexCount > 0) + { + theMesh->uvs = (Vector2*)MemAlloc(sizeof(Vector2)*theMesh->vertexCount); + for (int i = 0; i < theMesh->vertexCount; i++) + { + + // Calculate the UVs based on the projected coords + // They are clipped to (-decalSize .. decalSize) and we want them (0..1) + theMesh->uvs[i].x = (theMesh->vertices[i].x / decalSize + .5f); + theMesh->uvs[i].y = (theMesh->vertices[i].y / decalSize + .5f); + + // From splat space to world space + theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], splatInv); + + // Tiny nudge in the normal direction so it renders properly over the mesh + theMesh->vertices[i] = Vector3Add(theMesh->vertices[i], Vector3Scale(collision.normal, decalOffset)); + } + + // Decal model data ready, create it and add it + int decalIndex = decalCount++; + decalModels[decalIndex] = LoadModelFromMesh(BuildMesh(theMesh)); + decalModels[decalIndex].materials[0] = decalMaterial; + } + + } + + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + // Draw the model at the origin and default scale + 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); + } + + // If we hit the mesh, draw the box for the decal + if (collision.hit) + { + + 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)); + } + + DrawGrid(10, 10.0f); + + EndMode3D(); + + { + float yPos = 10; + float x0 = GetScreenWidth() - 300; + float x1 = x0 + 100; + float x2 = x1 + 100; + + DrawText("Vertices", x1, yPos, 10, LIME); + DrawText("Triangles", x2, yPos, 10, LIME); + yPos += 15; + + int vertexCount = 0; + int triangleCount = 0; + + for (int i = 0; i < model.meshCount; i++) + { + vertexCount += model.meshes[i].vertexCount; + 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); + yPos += 15; + + for (int i = 0; i < decalCount; i++) + { + 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); + + vertexCount += decalModels[i].meshes[0].vertexCount; + triangleCount += decalModels[i].meshes[0].triangleCount; + yPos += 15; + } + + DrawText("TOTAL", x0, yPos, 10, LIME); + DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); + DrawText(TextFormat("%d", triangleCount), x2, 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); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadModel(model); + UnloadTexture(modelTexture); + + for (int i = 0; i < decalCount; i++) + { + UnloadModel(decalModels[i]); + } + + UnloadTexture(decalTexture); + + FreeMeshBuilder(&mesh_builders[0]); + FreeMeshBuilder(&mesh_builders[1]); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +// A really simple dynamic array manager +void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]) { + // Reallocate and copy if we need to + if (mb->vertexCapacity <= mb->vertexCount + 3 ) + { + int newVertexCapacity = (1 + (mb->vertexCapacity / 256)) * 256; + Vector3 *newVertices = (Vector3*)MemAlloc(newVertexCapacity * sizeof(Vector3)); + if (mb->vertexCapacity > 0) + { + memcpy(newVertices, mb->vertices, mb->vertexCount * sizeof(Vector3)); + MemFree(mb->vertices); + } + mb->vertices = newVertices; + mb->vertexCapacity = newVertexCapacity; + } + + // Add 3 vertices + int index = mb->vertexCount; + mb->vertexCount += 3; + + for (int i = 0; i < 3; i++) + { + mb->vertices[index+i] = vertices[i]; + } +} + +void FreeMeshBuilder(MeshBuilder *mb) +{ + MemFree(mb->vertices); + + if (mb->uvs) + { + MemFree(mb->uvs); + } + + *mb = (MeshBuilder){ 0 }; +} + +// Construct a Raylib Mesh from our MeshBuilder data +Mesh BuildMesh(MeshBuilder *mb) +{ + Mesh outMesh = { 0 }; + + outMesh.vertexCount = mb->vertexCount; + outMesh.triangleCount = mb->vertexCount / 3; + + outMesh.vertices = MemAlloc(outMesh.vertexCount * 3 * sizeof(float)); + + if (mb->uvs) + { + outMesh.texcoords = MemAlloc(outMesh.vertexCount * 2 * sizeof(float)); + } + + for (int i = 0; i < mb->vertexCount; i++) + { + outMesh.vertices[3*i+0] = mb->vertices[i].x; + outMesh.vertices[3*i+1] = mb->vertices[i].y; + outMesh.vertices[3*i+2] = mb->vertices[i].z; + if (mb->uvs) + { + outMesh.texcoords[2*i+0] = mb->uvs[i].x; + outMesh.texcoords[2*i+1] = mb->uvs[i].y; + } + } + + UploadMesh(&outMesh, false); + + return outMesh; +} + +Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s) +{ + float d0 = Vector3DotProduct(v0, p) - s; + float d1 = Vector3DotProduct(v1, p) - s; + + float s0 = d0 / ( d0 - d1 ); + + Vector3 position = Vector3Lerp(v0, v1, s0); + + return position; +} \ No newline at end of file diff --git a/examples/models/models_decals.png b/examples/models/models_decals.png new file mode 100644 index 0000000000000000000000000000000000000000..48e027fe2d1711237f457995d46ddcc0647a102e GIT binary patch literal 62387 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 z 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

AIX)i);+Q2;^({W#g{?F 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 II;Vst0D_a9V*mgE literal 0 HcmV?d00001 diff --git a/examples/models/resources/raylib_logo.png b/examples/models/resources/raylib_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..15bbaa2f42d01ac30fb672d31ab00701e6c32895 GIT binary patch literal 3672 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 literal 0 HcmV?d00001 From 79fd6be0084a80dcbf7c7af2c1ccb12b78b77c47 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 25 Oct 2025 11:14:53 +0200 Subject: [PATCH 008/189] Minor format tweaks --- src/external/rlsw.h | 73 ++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 626cb2cc5..bc7a813d3 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -791,8 +791,7 @@ typedef struct { } sw_vertex_t; typedef struct { - - uint8_t* pixels; // Texture pixels (RGBA32) + uint8_t *pixels; // Texture pixels (RGBA32) int width, height; // Dimensions of the texture int wMinus1, hMinus1; // Dimensions minus one @@ -805,7 +804,6 @@ typedef struct { float tx; // Texel width float ty; // Texel height - } sw_texture_t; typedef struct { @@ -881,7 +879,6 @@ typedef struct { int freeTextureIdCount; uint32_t stateFlags; - } sw_context_t; //---------------------------------------------------------------------------------- @@ -966,11 +963,7 @@ static inline int sw_clampi(int v, int min, int max) return v; } -static inline void sw_lerp_vertex_PTCH( - sw_vertex_t *SW_RESTRICT out, - const sw_vertex_t *SW_RESTRICT a, - const sw_vertex_t *SW_RESTRICT b, - float t) +static inline void sw_lerp_vertex_PTCH(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT a, const sw_vertex_t *SW_RESTRICT b, float t) { const float tInv = 1.0f - t; @@ -997,11 +990,7 @@ static inline void sw_lerp_vertex_PTCH( out->homogeneous[3] = a->homogeneous[3]*tInv + b->homogeneous[3]*t; } -static inline void sw_get_vertex_grad_PTCH( - sw_vertex_t *SW_RESTRICT out, - const sw_vertex_t *SW_RESTRICT a, - const sw_vertex_t *SW_RESTRICT b, - float scale) +static inline void sw_get_vertex_grad_PTCH(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT a, const sw_vertex_t *SW_RESTRICT b, float scale) { // Calculate gradients for Position out->position[0] = (b->position[0] - a->position[0])*scale; @@ -1026,9 +1015,7 @@ static inline void sw_get_vertex_grad_PTCH( out->homogeneous[3] = (b->homogeneous[3] - a->homogeneous[3])*scale; } -static inline void sw_add_vertex_grad_PTCH( - sw_vertex_t *SW_RESTRICT out, - const sw_vertex_t *SW_RESTRICT gradients) +static inline void sw_add_vertex_grad_PTCH(sw_vertex_t *SW_RESTRICT out, const sw_vertex_t *SW_RESTRICT gradients) { // Add gradients to Position out->position[0] += gradients->position[0]; @@ -1065,7 +1052,6 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) uint8x8_t narrow8 = vmovn_u16(vcombine_u16(narrow16, narrow16)); vst1_lane_u32((uint32_t*)dst, vreinterpret_u32_u8(narrow8), 0); - #elif defined(SW_HAS_SSE41) __m128 values = _mm_loadu_ps(src); __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); @@ -1075,7 +1061,6 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) clamped = _mm_packus_epi32(clamped, clamped); clamped = _mm_packus_epi16(clamped, clamped); *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); - #elif defined(SW_HAS_SSE2) __m128 values = _mm_loadu_ps(src); __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); @@ -1085,7 +1070,6 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) clamped = _mm_packs_epi32(clamped, clamped); clamped = _mm_packus_epi16(clamped, clamped); *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); - #else for (int i = 0; i < 4; i++) { @@ -1110,14 +1094,12 @@ static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) float32x4_t floats = vcvtq_f32_u32(ints); floats = vmulq_n_f32(floats, 1.0f/255.0f); vst1q_f32(dst, floats); - #elif defined(SW_HAS_SSE41) __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); __m128i ints = _mm_cvtepu8_epi32(bytes); __m128 floats = _mm_cvtepi32_ps(ints); floats = _mm_mul_ps(floats, _mm_set1_ps(1.0f/255.0f)); _mm_storeu_ps(dst, floats); - #elif defined(SW_HAS_SSE2) __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); bytes = _mm_unpacklo_epi8(bytes, _mm_setzero_si128()); @@ -1125,7 +1107,6 @@ static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) __m128 floats = _mm_cvtepi32_ps(ints); floats = _mm_mul_ps(floats, _mm_set1_ps(1.0f/255.0f)); _mm_storeu_ps(dst, floats); - #else dst[0] = (float)src[0]/255.0f; dst[1] = (float)src[1]/255.0f; @@ -1188,7 +1169,7 @@ static inline sw_half_t sw_half_from_float(float i) } // Framebuffer management functions - +//------------------------------------------------------------------------------------------- static inline bool sw_framebuffer_load(int w, int h) { int size = w*h; @@ -1731,9 +1712,10 @@ DEFINE_FRAMEBUFFER_BLIT_BEGIN(R8G8B8A8, uint8_t) dst += 4; } DEFINE_FRAMEBUFFER_BLIT_END() +//------------------------------------------------------------------------------------------- // Pixel format management functions - +//------------------------------------------------------------------------------------------- static inline int sw_get_pixel_format(SWformat format, SWtype type) { int channels = 0; @@ -1920,9 +1902,10 @@ static inline void sw_get_pixel(uint8_t *color, const void *pixels, uint32_t off } } } +//------------------------------------------------------------------------------------------- // Texture sampling functionality - +//------------------------------------------------------------------------------------------- static inline void sw_texture_fetch(float* color, const sw_texture_t* tex, int x, int y) { sw_float_from_unorm8_simd(color, &tex->pixels[4*(y*tex->width + x)]); @@ -2016,9 +1999,10 @@ static inline void sw_texture_sample(float *color, const sw_texture_t *tex, floa default: break; } } +//------------------------------------------------------------------------------------------- -// Color Blending functionality - +// Color blending functionality +//------------------------------------------------------------------------------------------- static inline void sw_factor_zero(float *SW_RESTRICT factor, const float *SW_RESTRICT src, const float *SW_RESTRICT dst) { factor[0] = factor[1] = factor[2] = factor[3] = 0.0f; @@ -2091,17 +2075,19 @@ static inline void sw_blend_colors(float *SW_RESTRICT dst/*[4]*/, const float *S dst[2] = srcFactor[2]*src[2] + dstFactor[2]*dst[2]; dst[3] = srcFactor[3]*src[3] + dstFactor[3]*dst[3]; } +//------------------------------------------------------------------------------------------- // Projection helper functions - +//------------------------------------------------------------------------------------------- static inline void sw_project_ndc_to_screen(float screen[2], const float ndc[4]) { screen[0] = RLSW.vpCenter[0] + ndc[0]*RLSW.vpHalfSize[0]; screen[1] = RLSW.vpCenter[1] - ndc[1]*RLSW.vpHalfSize[1]; } +//------------------------------------------------------------------------------------------- -// Polygon Clipping management - +// Polygon clipping management +//------------------------------------------------------------------------------------------- #define DEFINE_CLIP_FUNC(name, FUNC_IS_INSIDE, FUNC_COMPUTE_T) \ static inline int sw_clip_##name( \ sw_vertex_t output[SW_MAX_CLIPPED_POLYGON_VERTICES], \ @@ -2133,9 +2119,10 @@ static inline int sw_clip_##name( \ return outputCount; \ } +//------------------------------------------------------------------------------------------- // Frustum cliping functions - +//------------------------------------------------------------------------------------------- #define IS_INSIDE_PLANE_W(h) ((h)[3] >= SW_CLIP_EPSILON) #define IS_INSIDE_PLANE_X_POS(h) ((h)[0] <= (h)[3]) #define IS_INSIDE_PLANE_X_NEG(h) (-(h)[0] <= (h)[3]) @@ -2159,9 +2146,10 @@ DEFINE_CLIP_FUNC(y_pos, IS_INSIDE_PLANE_Y_POS, COMPUTE_T_PLANE_Y_POS) DEFINE_CLIP_FUNC(y_neg, IS_INSIDE_PLANE_Y_NEG, COMPUTE_T_PLANE_Y_NEG) DEFINE_CLIP_FUNC(z_pos, IS_INSIDE_PLANE_Z_POS, COMPUTE_T_PLANE_Z_POS) DEFINE_CLIP_FUNC(z_neg, IS_INSIDE_PLANE_Z_NEG, COMPUTE_T_PLANE_Z_NEG) +//------------------------------------------------------------------------------------------- // Scissor clip functions - +//------------------------------------------------------------------------------------------- #define COMPUTE_T_SCISSOR_X_MIN(hPrev, hCurr) (((RLSW.scClipMin[0])*(hPrev)[3] - (hPrev)[0])/(((hCurr)[0] - (RLSW.scClipMin[0])*(hCurr)[3]) - ((hPrev)[0] - (RLSW.scClipMin[0])*(hPrev)[3]))) #define COMPUTE_T_SCISSOR_X_MAX(hPrev, hCurr) (((RLSW.scClipMax[0])*(hPrev)[3] - (hPrev)[0])/(((hCurr)[0] - (RLSW.scClipMax[0])*(hCurr)[3]) - ((hPrev)[0] - (RLSW.scClipMax[0])*(hPrev)[3]))) #define COMPUTE_T_SCISSOR_Y_MIN(hPrev, hCurr) (((RLSW.scClipMin[1])*(hPrev)[3] - (hPrev)[1])/(((hCurr)[1] - (RLSW.scClipMin[1])*(hCurr)[3]) - ((hPrev)[1] - (RLSW.scClipMin[1])*(hPrev)[3]))) @@ -2176,9 +2164,9 @@ DEFINE_CLIP_FUNC(scissor_x_min, IS_INSIDE_SCISSOR_X_MIN, COMPUTE_T_SCISSOR_X_MIN DEFINE_CLIP_FUNC(scissor_x_max, IS_INSIDE_SCISSOR_X_MAX, COMPUTE_T_SCISSOR_X_MAX) DEFINE_CLIP_FUNC(scissor_y_min, IS_INSIDE_SCISSOR_Y_MIN, COMPUTE_T_SCISSOR_Y_MIN) DEFINE_CLIP_FUNC(scissor_y_max, IS_INSIDE_SCISSOR_Y_MAX, COMPUTE_T_SCISSOR_Y_MAX) +//------------------------------------------------------------------------------------------- -// Main clip function - +// Main polygon clip function static inline bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VERTICES], int *vertexCounter) { static sw_vertex_t tmp[SW_MAX_CLIPPED_POLYGON_VERTICES]; @@ -2218,7 +2206,7 @@ static inline bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VE } // Triangle rendering logic - +//------------------------------------------------------------------------------------------- static inline bool sw_triangle_face_culling(void) { // NOTE: Face culling is done before clipping to avoid unnecessary computations. @@ -2556,9 +2544,10 @@ static inline void sw_triangle_render(void) #undef TRIANGLE_RASTER } +//------------------------------------------------------------------------------------------- // Quad rendering logic - +//------------------------------------------------------------------------------------------- static inline bool sw_quad_face_culling(void) { // NOTE: Face culling is done before clipping to avoid unnecessary computations. @@ -2930,9 +2919,10 @@ static inline void sw_quad_render(void) #undef TRIANGLE_RASTER } +//------------------------------------------------------------------------------------------- // Line rendering logic - +//------------------------------------------------------------------------------------------- static inline bool sw_line_clip_coord(float q, float p, float *t0, float *t1) { if (fabsf(p) < SW_CLIP_EPSILON) @@ -3243,9 +3233,10 @@ static inline void sw_line_render(sw_vertex_t *vertices) else sw_line_raster(&vertices[0], &vertices[1]); } } +//------------------------------------------------------------------------------------------- // Point rendering logic - +//------------------------------------------------------------------------------------------- static inline bool sw_point_clip_and_project(sw_vertex_t *v) { if (v->homogeneous[3] != 1.0f) @@ -3409,9 +3400,10 @@ static inline void sw_point_render(sw_vertex_t *v) else sw_point_raster(v->screen[0], v->screen[1], v->homogeneous[2], v->color); } } +//------------------------------------------------------------------------------------------- // Polygon modes mendering logic - +//------------------------------------------------------------------------------------------- static inline void sw_poly_point_render(void) { for (int i = 0; i < RLSW.vertexCounter; i++) sw_point_render(&RLSW.vertexBuffer[i]); @@ -3546,6 +3538,7 @@ static inline bool sw_is_blend_dst_factor_valid(int blend) return result; } +//------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- // Module Functions Definition From efe62f0e0df426ff64b14edc75dafd934552f1c0 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 25 Oct 2025 11:15:30 +0200 Subject: [PATCH 009/189] Formating review to follow raylib code conventions #5298 --- examples/models/models_decals.c | 397 +++++++++++++++----------------- 1 file changed, 181 insertions(+), 216 deletions(-) diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index 81bbd2796..af1ecfc6d 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -2,7 +2,7 @@ * * raylib [models] example - decals * -* Example complexity rating: [★★★☆] 3/4 +* Example complexity rating: [★★★★] 4/4 * * Example originally created with raylib 5.6-dev * @@ -17,15 +17,19 @@ ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" -#include +#include // Required for: memcpy() #undef FLT_MAX #define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111 #define MAX_DECALS 256 +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- typedef struct MeshBuilder { int vertexCount; int vertexCapacity; @@ -33,14 +37,14 @@ typedef struct MeshBuilder { Vector2 *uvs; } MeshBuilder; -// Utility functions -void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]); -void FreeMeshBuilder(MeshBuilder *mb); -Mesh BuildMesh(MeshBuilder *mb); - -Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); - -Mesh GenMeshDecal(Mesh inputMesh, Ray ray); +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]); +static void FreeMeshBuilder(MeshBuilder *mb); +static Mesh BuildMesh(MeshBuilder *mb); +static Mesh GenMeshDecal(Mesh inputMesh, Ray ray); +static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s); //------------------------------------------------------------------------------------ // Program main entry point @@ -67,11 +71,10 @@ int main(void) Model model = LoadModel("resources/models/obj/character.obj"); // Apply character skin - Texture2D modelTexture = LoadTexture("resources/models/obj/character_diffuse.png"); // Load model texture + Texture2D modelTexture = LoadTexture("resources/models/obj/character_diffuse.png"); SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR); - model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture; // Set model diffuse texture + model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture; - BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]); // Get mesh bounding box camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f); @@ -79,14 +82,12 @@ int main(void) camera.position.x *= 0.1f; float modelSize = fminf( - fminf(fabsf(modelBBox.max.x - modelBBox.min.x), - fabsf(modelBBox.max.y - modelBBox.min.y)), - fabsf(modelBBox.max.z - modelBBox.min.z) - ); + fminf(fabsf(modelBBox.max.x - modelBBox.min.x), fabsf(modelBBox.max.y - modelBBox.min.y)), + fabsf(modelBBox.max.z - modelBBox.min.z)); - camera.position = (Vector3){ 0, modelBBox.max.y * 1.2f, modelSize * 3.0f }; + camera.position = (Vector3){ 0.0f, modelBBox.max.y*1.2f, modelSize*3.0f }; - float decalSize = modelSize * .25f; + float decalSize = modelSize*0.25f; float decalOffset = 0.01f; Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize)); @@ -96,7 +97,7 @@ int main(void) decalMaterial.maps[0].color = YELLOW; Image decalImage = LoadImage("resources/raylib_logo.png"); - ImageResizeNN(&decalImage, decalImage.width / 4, decalImage.height / 4); + ImageResizeNN(&decalImage, decalImage.width/4, decalImage.height/4); Texture decalTexture = LoadTextureFromImage(decalImage); UnloadImage(decalImage); @@ -106,28 +107,23 @@ int main(void) // We're going to use these to build up our decal meshes // They'll resize automatically as we go, we'll free them at the end - MeshBuilder mesh_builders[2] = { {0}, {0} }; + MeshBuilder meshBuilders[2] = { 0 }; bool showModel = true; - Model decalModels[MAX_DECALS] = {0}; + Model decalModels[MAX_DECALS] = { 0 }; int decalCount = 0; - SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- + // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - - if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) { - UpdateCamera(&camera, CAMERA_THIRD_PERSON); - } - - if (IsKeyPressed(KEY_SPACE)) { - showModel = !showModel; - } + if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON); + + if (IsKeyPressed(KEY_SPACE)) showModel = !showModel; // Display information about closest hit RayCollision collision = { 0 }; @@ -140,7 +136,7 @@ int main(void) // Check ray collision against bounding box first, before trying the full ray-mesh test RayCollision boxHitInfo = GetRayCollisionBox(ray, modelBBox); - if ((boxHitInfo.hit) && decalCount < MAX_DECALS) + if ((boxHitInfo.hit) && (decalCount < MAX_DECALS)) { // Check ray collision against model meshes RayCollision meshHitInfo = { 0 }; @@ -153,52 +149,47 @@ int main(void) if (meshHitInfo.hit) { // Save the closest hit mesh - if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo; + if (!collision.hit || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo; } } - if (meshHitInfo.hit) - { - collision = meshHitInfo; - } + if (meshHitInfo.hit) collision = meshHitInfo; } - // -------------- - - if (collision.hit && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && decalCount < MAX_DECALS) + // Add decal to mesh on hit point + if (collision.hit && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (decalCount < MAX_DECALS)) { - // Create the transformation to project the decal Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); - Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0}); + Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){ 0.0f, 1.0f, 0.0f }); // Spin the placement around a bit - splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD * ((float)GetRandomValue(-180, 180)))); - + splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180)))); Matrix splatInv = MatrixInvert(splat); // Reset the mesh builders - mesh_builders[0].vertexCount = 0; - mesh_builders[1].vertexCount = 0; + meshBuilders[0].vertexCount = 0; + meshBuilders[1].vertexCount = 0; // We'll be flip-flopping between the two mesh builders // Reading from one and writing to the other, then swapping - int mb_index = 0; + int mbIndex = 0; - // First pass, just get any triangle inside the bounding box - // (for each mesh of the model) - for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++) { + // First pass, just get any triangle inside the bounding box (for each mesh of the model) + for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++) + { Mesh mesh = model.meshes[meshIndex]; for (int tri = 0; tri < mesh.triangleCount; tri++) { - Vector3 vertices[3]; + Vector3 vertices[3] = { 0 }; // The way we calculate the vertices of the mesh triangle // depend on whether the mesh vertices are indexed or not if (mesh.indices == 0) { - for (int v = 0; v < 3; v++) { - vertices[v] = (Vector3) { + for (int v = 0; v < 3; v++) + { + vertices[v] = (Vector3){ mesh.vertices[3*3*tri + 3*v + 0], mesh.vertices[3*3*tri + 3*v + 1], mesh.vertices[3*3*tri + 3*v + 2] @@ -209,7 +200,7 @@ int main(void) { for (int v = 0; v < 3; v++) { - vertices[v] = (Vector3) { + vertices[v] = (Vector3){ mesh.vertices[ 3*mesh.indices[3*tri+0] + v], mesh.vertices[ 3*mesh.indices[3*tri+1] + v], mesh.vertices[ 3*mesh.indices[3*tri+2] + v] @@ -225,19 +216,14 @@ int main(void) // To splat space Vector3 v = Vector3Transform(vertices[i], splat); - if (fabsf(v.x) 0) - { - AddTriangleToMeshBuilder(&mesh_builders[mb_index], vertices); - } + if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices); } } @@ -250,20 +236,21 @@ int main(void) { 0, 0, 1 }, { 0, 0, -1 } }; + for (int face = 0; face < 6; face++) { // Swap current model builder (so we read from the one we just wrote to) - mb_index = 1 - mb_index; + mbIndex = 1 - mbIndex; - MeshBuilder *inMesh = &mesh_builders[1-mb_index]; - MeshBuilder *outMesh = &mesh_builders[mb_index]; + MeshBuilder *inMesh = &meshBuilders[1 - mbIndex]; + MeshBuilder *outMesh = &meshBuilders[mbIndex]; // Reset write builder outMesh->vertexCount = 0; - float s = 0.5f * decalSize; + float s = 0.5f*decalSize; - for (int i = 0; i < inMesh->vertexCount; i+=3) + for (int i = 0; i < inMesh->vertexCount; i += 3) { Vector3 nV1, nV2, nV3, nV4; @@ -271,100 +258,101 @@ int main(void) float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s; float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s; - int v1Out = d1 > 0; - int v2Out = d2 > 0; - int v3Out = d3 > 0; + int v1Out = (d1 > 0); + int v2Out = (d2 > 0); + int v3Out = (d3 > 0); - // calculate, how many vertices of the face lie outside of the clipping plane + // Calculate, how many vertices of the face lie outside of the clipping plane int total = v1Out + v2Out + v3Out; - switch ( total ) { - case 0: { - // the entire face lies inside of the plane, no clipping needed + switch (total) + { + case 0: + { + // The entire face lies inside of the plane, no clipping needed AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]}); - break; - } - - case 1: { - // one vertex lies outside of the plane, perform clipping - - if (v1Out) { - nV1 = inMesh->vertices[ i + 1 ]; - nV2 = inMesh->vertices[ i + 2 ]; - nV3 = ClipSegment( inMesh->vertices[ i ], nV1, planes[face], s ); - nV4 = ClipSegment( inMesh->vertices[ i ], nV2, planes[face], s ); + } break; + case 1: + { + // One vertex lies outside of the plane, perform clipping + if (v1Out) + { + nV1 = inMesh->vertices[i + 1]; + nV2 = inMesh->vertices[i + 2]; + nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s); + nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s); } - if (v2Out) { - nV1 = inMesh->vertices[ i ]; - nV2 = inMesh->vertices[ i + 2 ]; - nV3 = ClipSegment( inMesh->vertices[ i + 1 ], nV1, planes[face], s ); - nV4 = ClipSegment( inMesh->vertices[ i + 1 ], nV2, planes[face], s ); + if (v2Out) + { + nV1 = inMesh->vertices[i]; + nV2 = inMesh->vertices[i + 2]; + nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s); + nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1}); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4}); break; } - if (v3Out) { - nV1 = inMesh->vertices[ i ]; - nV2 = inMesh->vertices[ i + 1 ]; - nV3 = ClipSegment( inMesh->vertices[ i + 2 ], nV1, planes[face], s ); - nV4 = ClipSegment( inMesh->vertices[ i + 2 ], nV2, planes[face], s ); + if (v3Out) + { + nV1 = inMesh->vertices[i]; + nV2 = inMesh->vertices[i + 1]; + nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s); + nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s); } AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2}); - - break; - } - - case 2: { - // two vertices lies outside of the plane, perform clipping - if (!v1Out) { - nV1 = inMesh->vertices[ i ]; - nV2 = ClipSegment( nV1, inMesh->vertices[ i + 1 ], planes[face], s ); - nV3 = ClipSegment( nV1, inMesh->vertices[ i + 2 ], planes[face], s ); + } break; + case 2: + { + // Two vertices lies outside of the plane, perform clipping + if (!v1Out) + { + nV1 = inMesh->vertices[i]; + nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s); + nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); } - if (!v2Out) { - nV1 = inMesh->vertices[ i + 1 ]; - nV2 = ClipSegment( nV1, inMesh->vertices[ i + 2 ], planes[face], s ); - nV3 = ClipSegment( nV1, inMesh->vertices[ i ], planes[face], s ); + + if (!v2Out) + { + nV1 = inMesh->vertices[i + 1]; + nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); + nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); } - if (!v3Out) { - nV1 = inMesh->vertices[ i + 2 ]; - nV2 = ClipSegment( nV1, inMesh->vertices[ i ], planes[face], s ); - nV3 = ClipSegment( nV1, inMesh->vertices[ i + 1 ], planes[face], s ); + + if (!v3Out) + { + nV1 = inMesh->vertices[i + 2]; + nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); + nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); } - break; - } - - case 3: { - // the entire face lies outside of the plane, so let's discard the corresponding vertices - break; - } - + } break; + case 3: // The entire face lies outside of the plane, so let's discard the corresponding vertices + default: break; } } } // Now we just need to re-transform the vertices - MeshBuilder *theMesh = &mesh_builders[mb_index]; + MeshBuilder *theMesh = &meshBuilders[mbIndex]; // Allocate room for UVs if (theMesh->vertexCount > 0) { - theMesh->uvs = (Vector2*)MemAlloc(sizeof(Vector2)*theMesh->vertexCount); + theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount); + for (int i = 0; i < theMesh->vertexCount; i++) { - // Calculate the UVs based on the projected coords // They are clipped to (-decalSize .. decalSize) and we want them (0..1) - theMesh->uvs[i].x = (theMesh->vertices[i].x / decalSize + .5f); - theMesh->uvs[i].y = (theMesh->vertices[i].y / decalSize + .5f); + theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f); + theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f); // From splat space to world space theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], splatInv); @@ -378,89 +366,73 @@ int main(void) decalModels[decalIndex] = LoadModelFromMesh(BuildMesh(theMesh)); decalModels[decalIndex].materials[0] = decalMaterial; } - } - //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(RAYWHITE); BeginMode3D(camera); - // Draw the model at the origin and default scale - if (showModel) - { - DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE); - } + 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) { - 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)); } DrawGrid(10, 10.0f); - EndMode3D(); + + float yPos = 10; + float x0 = GetScreenWidth() - 300; + float x1 = x0 + 100; + float x2 = x1 + 100; + DrawText("Vertices", x1, yPos, 10, LIME); + DrawText("Triangles", x2, yPos, 10, LIME); + yPos += 15; + + int vertexCount = 0; + int triangleCount = 0; + + for (int i = 0; i < model.meshCount; i++) { - float yPos = 10; - float x0 = GetScreenWidth() - 300; - float x1 = x0 + 100; - float x2 = x1 + 100; + vertexCount += model.meshes[i].vertexCount; + 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); + yPos += 15; + + for (int i = 0; i < decalCount; i++) + { + 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("Vertices", x1, yPos, 10, LIME); - DrawText("Triangles", x2, yPos, 10, LIME); - yPos += 15; - - int vertexCount = 0; - int triangleCount = 0; - - for (int i = 0; i < model.meshCount; i++) - { - vertexCount += model.meshes[i].vertexCount; - 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); - yPos += 15; - - for (int i = 0; i < decalCount; i++) - { - 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); - - vertexCount += decalModels[i].meshes[0].vertexCount; - triangleCount += decalModels[i].meshes[0].triangleCount; - yPos += 15; - } - - DrawText("TOTAL", x0, yPos, 10, LIME); - DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); - DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME); + vertexCount += decalModels[i].meshes[0].vertexCount; + triangleCount += decalModels[i].meshes[0].triangleCount; yPos += 15; } + + DrawText("TOTAL", x0, yPos, 10, LIME); + DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME); + DrawText(TextFormat("%d", triangleCount), x2, 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); DrawFPS(10, 10); @@ -474,15 +446,13 @@ int main(void) UnloadModel(model); UnloadTexture(modelTexture); - for (int i = 0; i < decalCount; i++) - { - UnloadModel(decalModels[i]); - } - + // TODO: WARNING: This line crashes program on closing + //for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); + UnloadTexture(decalTexture); - FreeMeshBuilder(&mesh_builders[0]); - FreeMeshBuilder(&mesh_builders[1]); + FreeMeshBuilder(&meshBuilders[0]); + FreeMeshBuilder(&meshBuilders[1]); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- @@ -490,18 +460,24 @@ int main(void) return 0; } -// A really simple dynamic array manager -void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]) { +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +// Add triangles to mesh builder (dynamic array manager) +static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]) +{ // Reallocate and copy if we need to - if (mb->vertexCapacity <= mb->vertexCount + 3 ) + if (mb->vertexCapacity <= (mb->vertexCount + 3)) { - int newVertexCapacity = (1 + (mb->vertexCapacity / 256)) * 256; - Vector3 *newVertices = (Vector3*)MemAlloc(newVertexCapacity * sizeof(Vector3)); + int newVertexCapacity = (1 + (mb->vertexCapacity/256))*256; + Vector3 *newVertices = (Vector3 *)MemAlloc(newVertexCapacity*sizeof(Vector3)); + if (mb->vertexCapacity > 0) { - memcpy(newVertices, mb->vertices, mb->vertexCount * sizeof(Vector3)); + memcpy(newVertices, mb->vertices, mb->vertexCount*sizeof(Vector3)); MemFree(mb->vertices); } + mb->vertices = newVertices; mb->vertexCapacity = newVertexCapacity; } @@ -510,44 +486,33 @@ void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]) { int index = mb->vertexCount; mb->vertexCount += 3; - for (int i = 0; i < 3; i++) - { - mb->vertices[index+i] = vertices[i]; - } + for (int i = 0; i < 3; i++) mb->vertices[index+i] = vertices[i]; } -void FreeMeshBuilder(MeshBuilder *mb) +// Free mesh builder +static void FreeMeshBuilder(MeshBuilder *mb) { MemFree(mb->vertices); - - if (mb->uvs) - { - MemFree(mb->uvs); - } - + if (mb->uvs) MemFree(mb->uvs); *mb = (MeshBuilder){ 0 }; } -// Construct a Raylib Mesh from our MeshBuilder data -Mesh BuildMesh(MeshBuilder *mb) +// Build a Mesh from MeshBuilder data +static Mesh BuildMesh(MeshBuilder *mb) { Mesh outMesh = { 0 }; outMesh.vertexCount = mb->vertexCount; - outMesh.triangleCount = mb->vertexCount / 3; - - outMesh.vertices = MemAlloc(outMesh.vertexCount * 3 * sizeof(float)); - - if (mb->uvs) - { - outMesh.texcoords = MemAlloc(outMesh.vertexCount * 2 * sizeof(float)); - } - + outMesh.triangleCount = mb->vertexCount/3; + outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float)); + if (mb->uvs) outMesh.texcoords = MemAlloc(outMesh.vertexCount*2*sizeof(float)); + for (int i = 0; i < mb->vertexCount; i++) { outMesh.vertices[3*i+0] = mb->vertices[i].x; outMesh.vertices[3*i+1] = mb->vertices[i].y; outMesh.vertices[3*i+2] = mb->vertices[i].z; + if (mb->uvs) { outMesh.texcoords[2*i+0] = mb->uvs[i].x; @@ -560,14 +525,14 @@ Mesh BuildMesh(MeshBuilder *mb) return outMesh; } -Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s) +// Clip segment +static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s) { float d0 = Vector3DotProduct(v0, p) - s; float d1 = Vector3DotProduct(v1, p) - s; - - float s0 = d0 / ( d0 - d1 ); + float s0 = d0/(d0 - d1); Vector3 position = Vector3Lerp(v0, v1, s0); return position; -} \ No newline at end of file +} From 6f101f40110cf1e5f49792ec2bf1ae4dfa0d3ab6 Mon Sep 17 00:00:00 2001 From: Jopestpe <47086979+Jopestpe@users.noreply.github.com> Date: Sat, 25 Oct 2025 08:38:06 -0300 Subject: [PATCH 010/189] [examples] Added: `shapes_math_sine_cosine` (#5257) * draft: [examples] Added shapes_math_sine_cosine * draft: [examples] Added screenshot shapes_math_sine_cosine * Explementary * Varying radius * adjustments * added comments and reorganized UI labels * Updated Makefile, README.md, and examples_list.txt * tabs to spaces * Fix MSVC compilation --------- Co-authored-by: Ray --- examples/Makefile | 1 + examples/Makefile.Web | 4 + examples/README.md | 2 +- examples/examples_list.txt | 1 + examples/shapes/shapes_math_sine_cosine.c | 176 ++++++++++++++++++++ examples/shapes/shapes_math_sine_cosine.png | Bin 0 -> 22098 bytes 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 examples/shapes/shapes_math_sine_cosine.c create mode 100644 examples/shapes/shapes_math_sine_cosine.png diff --git a/examples/Makefile b/examples/Makefile index ef7cb5948..9ae8bb480 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -564,6 +564,7 @@ SHAPES = \ shapes/shapes_lines_bezier \ shapes/shapes_logo_raylib \ shapes/shapes_logo_raylib_anim \ + shapes/shapes_math_sine_cosine \ shapes/shapes_mouse_trail \ shapes/shapes_pie_chart \ shapes/shapes_rectangle_advanced \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 5d4f3ffab..0e9b9f92f 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -564,6 +564,7 @@ SHAPES = \ shapes/shapes_lines_bezier \ shapes/shapes_logo_raylib \ shapes/shapes_logo_raylib_anim \ + shapes/shapes_math_sine_cosine \ shapes/shapes_mouse_trail \ shapes/shapes_pie_chart \ shapes/shapes_rectangle_advanced \ @@ -899,6 +900,9 @@ shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) diff --git a/examples/README.md b/examples/README.md index 19d110344..bbb0a0388 100644 --- a/examples/README.md +++ b/examples/README.md @@ -71,7 +71,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [core_clipboard_text](core/core_clipboard_text.c) | core_clipboard_text | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | | [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) | -### category: shapes [31] +### category: shapes [32] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 71cda6c1a..4805a37ec 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -80,6 +80,7 @@ shapes;shapes_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@ra shapes;shapes_pie_chart;★★★☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal shapes;shapes_clock_of_clocks;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates +shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814 shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates diff --git a/examples/shapes/shapes_math_sine_cosine.c b/examples/shapes/shapes_math_sine_cosine.c new file mode 100644 index 000000000..f61d4f548 --- /dev/null +++ b/examples/shapes/shapes_math_sine_cosine.c @@ -0,0 +1,176 @@ +/******************************************************************************************* +* +* raylib [shapes] example - math sine cosine +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev +* +* Example contributed by Jopestpe (@jopestpe) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025-2025 Jopestpe (@jopestpe) +* +********************************************************************************************/ + +#include "raylib.h" +#include +#include "raymath.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +// Wave points for sine/cosine visualization +#define WAVE_POINTS 36 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math sine cosine"); + + Vector2 sinePoints[WAVE_POINTS]; + Vector2 cosPoints[WAVE_POINTS]; + Vector2 center = { (screenWidth/2.0f) - 30.f, screenHeight/2.0f }; + Rectangle start = { 20.f, screenHeight - 120.f , 200.0f, 100.0f}; + float radius = 130.0f; + float angle = 0.0f; + bool pause = false; + + for (int i = 0; i < WAVE_POINTS; i++) + { + float t = i/(float)(WAVE_POINTS - 1); + float currentAngle = t*360.0f*DEG2RAD; + sinePoints[i] = (Vector2){ start.x + t*start.width, start.y + start.height/2.0f - sinf(currentAngle)*(start.height/2.0f) }; + cosPoints[i] = (Vector2){ start.x + t*start.width, start.y + start.height/2.0f - cosf(currentAngle)*(start.height/2.0f) }; + } + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + float angleRad = angle*DEG2RAD; + float cosRad = cosf(angleRad); + float sinRad = sinf(angleRad); + + Vector2 point = { center.x + cosRad*radius, center.y - sinRad*radius }; + Vector2 limitMin = { center.x - radius, center.y - radius }; + Vector2 limitMax = { center.x + radius, center.y + radius }; + + float complementary = 90.0f - angle; + float supplementary = 180.0f - angle; + float explementary = 360.0f - angle; + + float tangent = Clamp(tanf(angleRad), -10.0f, 10.0f); + float cotangent = (fabsf(tangent) > 0.001f) ? Clamp(1.0f/tangent, -radius, radius) : 0.0f; + Vector2 tangentPoint = { center.x + radius, center.y - tangent*radius }; + Vector2 cotangentPoint = { center.x + cotangent*radius, center.y - radius }; + + angle = Wrap(angle + (!pause ? 1.0f : 0.0f), 0.0f, 360.0f); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(RAYWHITE); + + // Cotangent (orange) + DrawLineEx((Vector2){ center.x , limitMin.y }, (Vector2){ cotangentPoint.x, limitMin.y }, 2.0f, ORANGE); + DrawLineDashed(center, cotangentPoint, 10.0f, 4.0f, ORANGE); + + // Side background + DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 }); + DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 }); + + // Base circle and axes + DrawCircleLinesV(center, radius, GRAY); + DrawLineEx((Vector2){ center.x, limitMin.y }, (Vector2){ center.x, limitMax.y }, 1.0f, GRAY); + DrawLineEx((Vector2){ limitMin.x, center.y }, (Vector2){ limitMax.x, center.y }, 1.f, GRAY); + + // Wave graph axes + DrawLineEx((Vector2){ start.x , start.y }, (Vector2){ start.x , start.y + start.height }, 2.0f, GRAY); + DrawLineEx((Vector2){ start.x + start.width, start.y }, (Vector2){ start.x + start.width, start.y + start.height }, 2.0f, GRAY); + DrawLineEx((Vector2){ start.x, start.y + start.height/2 }, (Vector2){ start.x + start.width, start.y + start.height/2 }, 2.0f, GRAY); + + // Wave graph axis labels + DrawText("1", start.x - 8, start.y, 6, GRAY); + DrawText("0", start.x - 8, start.y + start.height/2 - 6, 6, GRAY); + DrawText("-1", start.x - 12, start.y + start.height - 8, 6, GRAY); + DrawText("0", start.x - 2, start.y + start.height + 4, 6, GRAY); + DrawText("360", start.x + start.width - 8, start.y + start.height + 4, 6, GRAY); + + // Sine (red - vertical) + DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ center.x, point.y }, 2.0f, RED); + DrawLineDashed((Vector2){ point.x, center.y }, (Vector2){ point.x, point.y }, 10.0f, 4.0f, RED); + DrawText(TextFormat("Sine %.2f", sinRad), 640, 190, 6, RED); + DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-sinRad + 1)*start.height/2.0f) }, 4.0f, RED); + DrawSplineLinear(sinePoints, WAVE_POINTS, 1.0f, RED); + + // Cosine (blue - horizontal) + DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ point.x, center.y }, 2.0f, BLUE); + DrawLineDashed((Vector2){ center.x , point.y }, (Vector2){ point.x, point.y }, 10.0f, 4.0f, BLUE); + DrawText(TextFormat("Cosine %.2f", cosRad), 640, 210, 6, BLUE); + DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-cosRad + 1)*start.height/2.0f) }, 4.0f, BLUE); + DrawSplineLinear(cosPoints, WAVE_POINTS, 1.0f, BLUE); + + // Tangent (purple) + DrawLineEx((Vector2){ limitMax.x , center.y }, (Vector2){ limitMax.x, tangentPoint.y }, 2.0f, PURPLE); + DrawLineDashed(center, tangentPoint, 10.0f, 4.0f, PURPLE); + DrawText(TextFormat("Tangent %.2f", tangent), 640, 230, 6, PURPLE); + + // Cotangent (orange) + DrawText(TextFormat("Cotangent %.2f", cotangent), 640, 250, 6, ORANGE); + + // Complementary angle (beige) + DrawCircleSectorLines(center, radius*0.6f , -angle, -90.f , 36.0f, BEIGE); + DrawText(TextFormat("Complementary %0.f°",complementary), 640, 150, 6, BEIGE); + + // Supplementary angle (darkblue) + DrawCircleSectorLines(center, radius*0.5f , -angle, -180.f , 36.0f, DARKBLUE); + DrawText(TextFormat("Supplementary %0.f°",supplementary), 640, 130, 6, DARKBLUE); + + // Explementary angle (pink) + DrawCircleSectorLines(center, radius*0.4f , -angle, -360.f , 36.0f, PINK); + DrawText(TextFormat("Explementary %0.f°",explementary), 640, 170, 6, PINK); + + // Current angle - arc (lime), radius (black), endpoint (black) + DrawCircleSectorLines(center, radius*0.7f , -angle, 0.f, 36.0f, LIME); + DrawLineEx((Vector2){ center.x , center.y }, point, 2.0f, BLACK); + DrawCircleV(point, 4.0f, BLACK); + + // Draw GUI controls + //------------------------------------------------------------------------------ + GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(GRAY)); + GuiToggle((Rectangle){ 640, 70, 120, 20}, TextFormat("Pause"), &pause); + GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(LIME)); + GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.f); + + // Angle values panel + GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values"); + //------------------------------------------------------------------------------ + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/shapes/shapes_math_sine_cosine.png b/examples/shapes/shapes_math_sine_cosine.png new file mode 100644 index 0000000000000000000000000000000000000000..b561f74fbbd06ab006df7e5789e79a6cba255b07 GIT binary patch literal 22098 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ#=yWJp1k%10|NtRfk$L90|S2|2s5s* zU!KXppuphi;uum9_x5gXkL>l@`yVHIOx^U-VXN%PNxPbIEd!q}YfBEyJ>xp9m&G!1 zws@}GhQJF^t0s1F&RU|mM>D6RPH@Y#tOW}$+lU&ps%(%oKewpg;g(jPmTHREu1=NX z8+s-BbR!iKHG>kIW7q4rExGc0_w@fy3o4%9tF%aeW>do+G2zZ!OaA%AVYB|*`cKcz z&)*+ZpxD5`#G%l@z%-L9CpR}Ws(4lJ0Sl(-{gZWfD#4^U6dD}*m{=4nw^^0CF)*?S zIDm-+6-K5B6Ca!ugNraU%CK@c6y=n@>VcZdq0n%^gNa2!`QT(-h&^D-EV%?4p4@nK zMG{HtL>3MQwG_+T8c?(<&~1(V4sLX~EY!o2ot( zBbiVnmcXL&{Mzz&5KBN|#KEI;p@LICmn?i+?E607 z%IVU!d3X8|RyuSs^)xKGvFZvZLTjS~D~AJ9u0&TWiaHhr&23txNVX~jG+xVgxV5e_ zqq<(hZ{sv;5&Kh(2rUO}KzD++t!;$lR{K)fo{43L1<|6Bf*BJ_L>%2r*$B1Ea^Sx884| zi4>%o!>fToWyP}v21xE&qU*pgsqA-2`MmeuCmnNK}v3!+yV_tXzjd&@_?la zkz99=Rj%RzGq-zh#{G1L6SOokOe&X8(WA|7Oa!ne`v4{k;4b9<@w#fdz8oGp480cYO+ujr%Yq zZ2I$A)2CS{i*NY1tj=itd);6AUd4U?yiSirA@*qnJepr92JlL~YMLY$`9XszxUq;~ zQ}=4>`G@|CFk1dbKv+3DMpW!xebq?rIUjcQ@35H z-u^FF&mPP->OK8c{d(q!;O<>@fq(b)KXCrVqVUBL7R3oHjPb!6IIP?<&YajZNBqIB zSN)$eI2@E-8;FQALKQ`*Ja`?PeMPW9)q&xW*Q64d4;jxhbuT*?@xbtkiPZT})k=RR z-{tX@r|M?C0jKUCXBxJ^ikij=tlPG2bJB~;z4hxIYhgxuph{yll;*T8UOuBs+H)7)c;xc#tq zS_`|_j+zI5PQXJFR2~?KDKMPe@o}XUax8Kiux4izeuC#1CV_;&a)#asnSvY+M!6NM zdZF2?k~?F&iXO``fduJ$hF4C)0>4SHqg47{0)r+8lP+rn^Ch94+b}PJLTkZp21bu^ z>v=AqECzCefCEG0G$s}W-Ge)1K?-2vySN1!O13}tgoZF!X@;f)104)J@a|pzClz>@ zIP@@S&-OnSk#p)!z=JQpW=r3*JeSL&@OZ~$ZI~K^RR`9u*X1x7aJ&nxiTIKw@4h%+HEPldM1&4*`4Dk+) zh>PD(J9huAzWDcQli{I9TUIXX6l~aGuIh?#B0rPw@d7$YF)*@x5>{Y1x&G`* zLs)b*Ffc6!H3;1Nk3j+$?9M0Z4h)mxX9pu|brV)#knEk;gOr3%_&4NMe9kV;g11&g zZs~S%HyX0sXe;L_{RBmch!(p(>zzsuTpnEgpSgZ=iHC|_t^MB{ZdVz&asHhzTD#X_xJO=L-^c6*mj?~KVN*q zl+z*8%kHdodMUU=;ecMm7dDnQQ3VFcYqReNI4CePRxb=MSg`+fYF%yZUGKBgSruxH zLw~9J&6#n{F`lby6=U#yn+mzcjjS9F$MP6Io%d~EP}wfFe4i(GhRc&XSF=5@8y-1z zmfIpHhSxcBt6+)&mGj%H+S`?1dE}q8BH#;nK{y%=%k}28dVGNrz6cTq$`~AjAW*>3PsxnLs$ zBZnKt1O{phNRM&+dJ$Z#=EZ)+rYr+aiG`v;v^9T2G32AD@B;Z zSuECkxO8uV(}Td;&i+cT$*f9dT0+IKKl1(OFtI2UZj)Zx7v8|2a&Oz>CmbeX4{9bz zhI%!+dogxi~GF)%J?+9~fBVRzR0+R89LYnKC^D{H?jHM1^ya-w7|N2A99Ubl-) zVk_8qOC3EgOkGgm$tBRBa&t`xSL0D8%bt!YIV7( zfg6Ip|1DyjedjXE5>KnE7X^No&;MkuDgFJ2xB|n+d>=jz7WEC!`T5nVld4K*h34#z zV!a;erYF#N;sme5w?J+ksgD}{eN*1A{#_@z=%nrG2fzBxnP~psWc1961`@ zt^RKE^gY$s@vgs8`jOh#r*bT(m=^8{G1GOoZUEK|lI}%^{{f_$R(!s={pty}I)hQvNu}I+4q5eGnIn|rrm^}45$o|~P z9b)?WVOE<;`~(k$AbCW1TWlDh@P@e`0CZ^JHU;$Ljnmb z5Mx<14W4zrG<&tse{*qshFr??jwJ!x#9CffPc)G@>cY^d!y>_Wa?#9{Dol4-N+K3E zO;FT#vu(R_PFbH-aa(3%Zqfwzvny4ZI1~hyF)(_}cT=iIC^v+yx!on?Yivl)X(SUzpeV5SD)3-!1S2YfXQf{t);TS z)P~a&1;l2#U;W}KzHL`*{-vo)i$LyDVCrdLxg;RM+$g~kGiS!RZ@Ub)l+>l__@9i5 zjh&m5eBj=|aHL;*rP72o4)cXCi`LAsC`?NCzLGL=MZ^>)Gu6}EUa4|)Zj#hA zVd8L6I3TiyL#k6rNnn=4bm7aoKQ>%m>AYI_siOmvnW}fA(e9Ls>Y!+`XJS#Pi}4g~ zT*ERg_hK}k-Hjyk)$0UPQ#qX$<(P5xGB62p3N*M}i4YNO3}Ah8 z{{Eg*{dLz5f?2Br*SRvWD1PB*5pXy#pMkN%K03%vL7H*yjJi+C?A^cL?OtzD_vgo! zd%t!wP4usMB;2|z*6`Cr-*S&-i&zv-ny898Drhuj|Nkj3`b{+CAe#;k_q%s$@X6cl3BIad|MN79{7SPLwy#PYCl^dKUYqn&^~QDXjhAF! zNg1urn!Bp<_WtLRw>O{v)BawzOYKC>4OZ!z1$?~{rtey z&FNp?Z_Q4te;%dhAh799hxH?&3?Yk<>=0g`H_uD&>)Y>takJ9V@AjTm`roeBPk;T| zierWJ#T9k;OZOFi-NC(7m7#O%Qw?(_Mox_r7v6<$zgrf)FnG!7;7xt9)?s(5-|uCd zT6Skq#D>EA;%SV{P0d9K1wVGzEeZ|z@Tb$?=km^1)9aI#Cw&(a|7W*;+xPkWVIggg z`~RHrGe~MYxwpRh+v*du02*(!cQU*X!?DW zY}2;Jw$oCP4S~ENItDj?TTfP;dUC0eP*04OzrdqS=99wwm~!p^=2!o>IjyE_Y`N7@ zqg0iFbE&EZJJUq28F2)(S|pz*Emz^03h%YwUf4!VB7zV>8< zSi+XM`%Ln?u5PLd+wF4uw|J@M^vtE#O7(BwyH}^W)hke*ML@!B!Mh2L+zx9*#9A`e zdaP1byc*cIFz(v?{a?Rneh!@{zHoZ87HjxsL78h4=2(@ky6`SyR@ILB|Nj!}KAt$b z^T4%h(>|NTs{c6oxL>q<-P_{1Ijg^{>fUnt;PFifi$dKR@5F@PcjyX_?h*KP%1GJG zVH)ShVitiJ+83U+6tl{%>}#3A+;6x%^yj-}QadkB_r1Mo;>08)t3?Ug*H=dMwETEi zxupL<0aH%|Pr5II(Hv7t#R)wQvmYGRnj0jLnhDVv&Ub|ux+B74? z=d*3w<9DZ#foUeU#*Yg%-`D9!NO5i~b{6S5QlR<4;>QVpfAQqk!T$o9`UT#a{7O_- zloH)IcdL`m>eogu%bgCkHwoy08~;^|OafKxOdKX+7rLi*AKkW*MX{>#nskz;SsKXQR<_@hZonb7xB1!v0ijvw6;(YG|C&J<-p*y-hrXfjY-{aPKHcP zhV(tP@C-+f(p8~(-79BriM(FDs?p4VPr-d*1%`$E3JnhIjI*n*mfk(S zNXMDO>Dk(k9f?OCOZ(5!*;jhpS2n6-kGqb*MrXd`+MW03eBHh1WfzNL-CR#uMwUk+ z3DWm0ZubT$8_Z}pn_6!AH7oAm@jHvIpW9sVVOzXx?X0Wa_bp;;UP~|U65nq(d)Mc+ zC-;}`eYI6vd}Hj-UEJ0>d%rxpF1}uBjroq#9*rGqH(p%yRm6REj@GodJx~4mr-1tD zJ6Jg!9_874^*59=`tH4Too>%84NX(`XCgKbQ_+(sfXG3BqT9xs|x zx#?!f_G6rU6_3B@Obk*maW9r*>@L0fGgAzNlUklgv1>4xWICi)> z*7zjK>{@$*pOHnNK+%EWk<&yI0gr$KaWiWC_Rc!~%$Q?iAphPce5KQlU+$0FBe3)A z3%91btG0QSZQ9l3%&O$f-fp*6v|^53ZPoJ$PV*}#nlW)4(fn{{x%>^yA6MV+Q9tLk zMZ=WQgIg!hRY9CFSKjK%mDLNICM>*G6>`0B&o|xGN2g9TmD%}avEJ7?eQh=SX0RyQ z8}m8^MM@{_PBIi-?Y;hiq&(A8@q0zT^y2HLwx9kYX2~-%eDb#y(~keMJ%6|7OM2{X zlat2FsyQ5zvUE>%9dKZB_TT$Sw&jIzX{_CKi5p+Eo*urks!n$69y6E5WG_dK;Elh& z^3E&M4&dc0s{C2H`i9-sT?=&7>zO8e``e~2;1PA;YUXpj3BUY~Z_*66TOK`?nSWXM z&Wx|znKziehAc}l6g{2$U%~V{)3>CU@0zu@-%t0x@$Kfe@7ns+%lvIm9XvQ;v6geM z$jk27l+m7c*_4j+H7t}n~R$tzIlGCP!Eu;6?!Us}@aN_vBc_X-8F$;eA0(e&xO?uky}1HOyJLP@+&;|Ie|=wSec|KX_g-(A zr(zcG;CSMe>H8UMQ>-05k3@*I@NC>$dc;S>*0FJ0aL=uK@v5(X*IZVcA%5nHZ+`Nv z+dfknmSnzvWXB>T{-N^LPVQaH98a`9cziu3W%uMZ->sK^@iFl)-_k2|`Q(?V!^W}a zjU$)Hecm5%&)VrTE2lpX>3ieI96ie4oYK;7fPEat6K9+mO++;Oz^?yMLc9SeCac zD3`?@_5 z(b3u>Q(k;3?3lYOdhd^~!LBEwU)p{CH(x96>xJoEtL17d=A1JQT4&dE)^OFL`?kGJ z1s)G2eu;m&bL*DWb_U*}|4%+1@3OxB&2&fckLa5IIXv-;Bl|X9(|)oqDfcADiHNB{5%%9-;oJ&9`5z{ip-LV^;nw-k%lJXJ`^o%CQY|E|c-iHqf~ z-`{nPu}M$rRI-#Ni=x!e4R@bQuztJ|>2YgyL-$sxIPMz;A46VU+^}o$y|SMxc22fr z;!wEY?BLk3EHTq++OpKIJGWeW{LwTN}*M6;d+xvTZ>dEuW!X368 z8z=S$FZW|r^DabgQ8TiziM$YQ$++UoeRk_sy~T3OX0slz(c!rG=!=BDn`2Ur>8TzD zrdU=Ehh3*W$}mmjesRHZ@0TS-rJPP8H7{cL{fzto_0M@K6@_T@x;e;`TkW+JxwlGV?@LlS*kb$ z8onHO9LSO+;!*l#v8O;%^qWohl#k83z3xo={@3bi*2#Z;1fxNf_wKT1c`O1Q!3_*5 z=gJme;V2RFsQi)~D3ElJ{k5%C`P>z9F}t5lb8xCq};v^HrYs+x<^@f0)bomDb5n(`9ovn(%t>Ume4tFk#sN>36?_65}(k z6;!S*)8F4}E#RQQ3bM;-%O#HvKd19Uwfgp05!IDa+!nc*otI!^!PU4P)xs1J2x+uFvaD))HH+z*suZ zr8}s$aJzW&Y`KtsmpM-9pZ8r>IQ9L?WxI9G?%K0T|3j>s!Y-4{*jn-4v@4S3C+(M} zb2tQL`Mzp8Ak(|B;b(y{szm z_V3kCU;M7QT=jCF)#l3k@gfpiPZ}Ss=5z?k34PVVz~s%!;WSN1weoO@;I9;251rtR z60Dw^q}>8ne%i8nTX0*=eS7{5Cr|i@e3&URi9uy@+p<}eTp3@Sr^hAj&=XbQIJr6e z$QEs}#R`?*E-uX4oALI@o|h3?*B51aeDk@T>0bM8{psSFiPr-s@7i?kcinZH4%?e+ zU~2)UO|@;EAHQwy-oIX4q6_&r6be=zh+ySFs((G10cKR1u3?@sdF_Ja5CC8v_Vdh6G(Z;!i@aeDjKt)ewI?JNImd~|MW z?c!<0XLJi{!)&%zwO$CHwpE;6P*3>La}F1s36Bpp$Ig2FLI2c$LUfo_2)6-xQ z_(+aLNhIOR;>g9m&HeJf`X1er|99@?7j56en}jdVUV0#QBi9iVE~R8QhorZeQ=}PL zR)OYOI9Y^59(>r8*1PJ#;{#{c&t{V^6KpZr?EO?vnzeJG-K;KG0U>AaKsOeF2sH`+xCAo4?nczcfviBhqWi8Q$#cdlqxly6Y@UP`!M21qahj&@AhH zRt68>hOhE@P5j=i3MyOgPx$$@GgX(v(L?U<#3-c+yBHWfUg`S$-6Skg{kQ!B2zftd}ydtdGP@aNRx_*p)?ckSC|!=iX@mez`v9K&DDlY=ig z?=ktb@a42M-?=uHUecJ{+n^)8P~-Zw)C-f^l(t5wI50T z>+0qVn|V7J7(E{G`g|2Q5xU^~q0g1C?Kqr1z4Bbx-?V{GW&OVwi?@At)4AnSomITP z|I_5OJ4|nyM9Y5%RSrhUp9$(~w)~3j z*&4_Y{I6>x-;_$wQVsAh_Z-d^Gw~Ww3-;>TY^PZ9dD&l_U)!1dUG?^8$(n6R5AVx= zGST67y1}dcr%oh^^LJlD$o%!u%tre1;k$EMUwF-&#VOEWQv67drAf@9_E*V4?-Q+R zm(GR9UaQmivEugERhjGx9GP08|7zLS?MvOn_r!P&Gw1%58j0+UuHDDpreCdowJ&~p z?d{lYr@n7qvDbOA+ZT@D4N6%$U0n`y8{8bi!onD4aeRsVt$4t7cbq9}npIfv$_?)? zm+d(|uiEB@(=DqB3EUnBLA^aGMkaw>Y)qUSEoQ9QIhXWqzsvfPEY_fN@9V0}yBtol zyjrW}UppMimG)|5U@GJmXgG4WZi-yv%SwjTt5-XE&awP;@#3k)N1w;)`R*;M6>Qld zCaZ3{mYMTwl3~>fUFV$w4ha((7&-njH?pwY_?vaDBX)WG%|pfEi{+o{xe5q<*PoGl zTslkl+V$()YZ)JdI>|{w3Jjeqw`yoJap;J=*!*>!e^ise{9Q}dYR-rO4aNE}u_zdB z6-#wZ=wr~A7Z130@7JztwJFzyqg(gY^wb#$UD{>YRDIxDV~Y*1wuK27Xz7rSpaR3f zZiNO1A*NY%r4OEcV?6QHzh?90newq0BsgC#I%W)>3th=6(6Hp%qATjwjBXBTzIAW9 z!(i8;?FOTsY8m(%H!x3~Kn{Qnu3_k#mhxBIv`*af%j zlT*<#^%CB6VC()bt9Bl(e)fFd)m=BdR-Z2RHJTNEt|+e5e*631TH%v775ndHP*(WD z$D$;5f%C+yx{1H9mVMm0r|sU~tVn4?p-ny+cjjkvUEBCvPJX+MZrO>;3b2-`IWRoxnbacSkf768UH`*6I@R{c z!{)VIW;wdn_BsEg?T2QvIB!rkMT~02d)mg z6W-q6f8YC7t&nZ;m&Hc|UOSX9JltE$CH-JCiz1`hsU;o@^N#M`v?*wgO{LL^|6(mS zCrw$^?{HmVq23FP>8%Zm{ZAkHs>A3J^VT&JRNX9K=C~a!1T&BKN!Ph4WFAWYCYnoM2t<31LC)fR?poR%+c5SU~cBh_o!ci7C0iodR-rz7@ zr~7yA$fy?=^@b%}JY9YF{IuHrzlwjC&v!_SoOhK?}ccc`02jS6*x{VTNxcb<-gb#wa1{=U6K^5`#ILCM*kj z_ujhT>k|VfNQ2@Y6N|!LPEU{;i=P!T-vx?v*%iy}KDjH3bQ*z|C@5TrXo%eao(_D- znIRR{ab5QOzsHMyJc#`7`up^Hk)zx91>Pxt^E9mT@1b}5wdx+0|Bqjt-n9GYvv{p8 z`|9$K>hu3QeN^7QC*sb(pYi>4ESc^LL51xmP)W$x=)oEm7Pjnp!<+m2 z?RQA!w1+S0?pasy;?tw}yAzMq|MQzylm78caKFg)x~JP79s8T!wKt#V^V7YV>U)!Z zzkGD-Z{qx*`&;y!?|t9d-hQTc56I*?rZtQ&pC7->p&+pEz`B#3FEnGNe(v}kI-{Q(M%I`X3zCnu9R?j!x#1N;>PL9cAR@Nb#*y1tL(oY z)i#*j_0#zc%Oh5P{ z={j_UA3oX>P0DE+ICOx za?m{%ncQfFJ-;~}4rL2_fvTzs!41VuPP|SgtlHZbT<~_DtijaB60>%)LPEh61x{6G zhDia*K~w**goTB5O;-08`~Cg>`SqV{v({wVg^T!$S3NwNdCI@Ce2qY}K-qy;7gtt_ zF!D3yy6e4qmv5cADsNZ#WvyxDm$IUkEz2yPFU`m#VBWW+iGhj3MNuG2py;TxzqtP0 z!dj8Gg`z>b6ZV>JaSEKbg5_Cnz?I&pkp21p*F_s&GM{TU;p!%nv%7ue?!0zuU^vpN zyi%dTA%!W5ebMxL#qIlaH%b3o%S4N<* z5`h=G4h)xOPhb&{2yZZU*!4SGq-E~(WA=uzm)DE%6oKp7CyEXXliaO?y;%fS2v$@I zwLG!m&6ex-^O1j*^kwmW6M3gE<|?c#0uo^j3@H)$Ma~S32Uupbm1Z`-IPzs-lK^YI z{{0`b4pgxo1!V+*51I}PkAkOf5p+0N|f^Msd{I+HaEK#d&+rbSpUC{U2`G}6NiGq90tY{1=pUmG?+6sP58IPhjmu| zi)0m-;PoYjzb>x7|BAtBS;9BtCz&h)67C7#EpATIX5!c(azTB;tgeHnJ?umG3dC1_ z@jlw!p7&~cK$8FT<_X(n>l8QMIvPFq@^b&r*7EtEd*eQt|GBrd`1A*H`wu?3H@}=& zG@n0m<+{|3RnuP^o_7Le{Rv-vO!b*2ghWrPQfzR@ZhU#L#k_9wjJduC4_2f)gsU$z z{&jIz^fkK$f&$CpcYZ!&xHQWkP<+agl*=j`G^};FLxMI*Zqj3cEY+RIV)E&rQ;GQw zE}OW&|Bf$94>r(!ofOQfSgWUNb$#V?{hEyU`6(6O_B1d}`1-ZfMxa0~LH~BQ-Ou%X z3R`4t3rhEE+2)%ZmSp3s6jfmOc*^?`2akHfYlj(aSMUEhlfrear2B?*j$riipF4lY z#lF}x!OW3!`MmG%XHRQd7PD^Mx?SEArU-%B&EH(X6n zpYk%fWZNPIhK1q^6FL}PJKQl{;%2u_V_urpHKrizH5)PolG5u8ww{f(S5;+k5-70D zJ)Ii0N$~;4!uB)z%)1j>Z<|fwVPtU=x!_b{y*lYg63gt;*>^XJ)MUI8J=nhcS<3I& z@@Y#-92aCWED*2#{pxX~U;BfF{V6}r8!-vhNe4QyNO5Monz}4?gK4_*Iydu|t(E6f z!gYL4CfS}?n(|a(NuJ7)YqcjPa5J(T5{eKhxbipW-jtQw8oeiPncb6c#rJ;Js+fD8 zt21ZLT6VU!o0Y@ig(9d~-rLZ`cdc3Ho!sdr0oDTjyM?xla}M7(x>j#-R@2Ui)EIp2n%B(0q_$vU+b40ON-hJYN$I2vtG&G~?;Q@iJKsIm{=aeKM!|doO(lZ{hHPs#hdu>vHwUE*m97p4X~x@q+s_)` zxgB$W?^5uLPBdYhXyJC@ykgX!Kxx(>hCG$v(#T z|JC(jdlKL39Bf~1SNH47%cjkBHV-H1FmdpxIWQPWm`W-d^f0`3_+us9a^-i{S@z58 z{(Q3s4>$Zc+j0fe7C+C#qA;(~Q?79#>x`zS@pqa8_7-H%zIjJq@(QcGm0|7gm9aa8 zEmzwIZiVmy%=Cx(&++Wq> zub%evQRjGhU;Sp?_Wg>Q3JnhM0{6g5hRYk~6kStWCZ0D}*vLBP{mVonUXAHDIiLIM z+pO4lw(})pXzwCWBZ#9yM1kRBhxa88g$er_+#KU<>Q8NtJ61e%QtIs03` z{9JwD7eA!xc+4%(&~u+{3IpSFCZB^ve!EN@XE#mxHAROta(&(ZW;2yL#!9lV02)PbSVo7IGAk-zWEZH9jDXRs+A zExjyWUK?BY*nBx_=hKo8pAJ>s{&;%o5>~}^m%MFd-Ry(%6JNDE)G@Ir{M>43dd}lO z+2JIsYZbk5d@dne(w-9QUAl|ENmfiL4if;419B)#SkA!cG4HM4T4TWk5tTV@dh-|9 zNsIoxRWd7#W3iH0NsL|O{g0ng!u78!%RSuURHJ(FMZ4az_@md$rbsZdyaHt`Sq>Gw z0~#I?yg7{>|F*ck+8n#Ijo)p{w#SbaJYIHjLrKyuKHZd*lr3rspmnJ-Kr5vi z3t1#sC6Dj*T=z7=<@;^1?VAGy%NaX$o3=NoPg$@yCq;dka7)ac;w?XFl9LyEmOqkX z5pYnDVq}_-F{`Ud=|XHn;DmQ&&UTsUoe>6$>~p6aI<-(U=&5eO{hF-nU);lU&if_l zzu&Rc!Fl?;nXIPQegE5(Kdw-gEuHuD?nVx$G%p=H`A^&X_Xs#7crY?eP~3WwyKy4O zNu2xKw^=V%o;-JpSgilNKd-(Vzy5Ci-Q{z)C++2M(#x}Svrl?^5;TT6jkACcyrjoL ziOGy>l1J$Zw?#}cVHVjDZuUZNAB1o-vMgijX}BOLaKgo5v4V`x49{fuIA1rXuBMCq zC#*Lve^meJNAkQNwMfL8TZzzw($dmjC$*xh`fl;0+;dnU)3WF72X5YZ9?!+x>@Q_{ zPdD9JoIC&Y6A$jjK-L*erdswhl?~Q3F!9%JI@RjH!?bhWjCJ<|?NmAzwgGo|82t zNMO-L{@9$ovxE7Ut>btC+V@lbJNWk*RteUVdzf9~{!VF{aAJ1TBjpALrnM{_4pD`L z#!Q)a>$HuQ3#!MU~q6!QzwT>5as3eVcYCG9I%lWYv<&RxIg zU6F_!(&Sf=;D(p-+a%1URt562IEf}atb~p?ae&g?l#|Sj94schE|(oG6m6T1E$Z-Q zb+R*z-JdLDwPOqCPDVx+Au$C8&mDy;rI>PAMOqBFE`{~}b{66Id8A}nTh{@cq%hWRtJ2Ug~>-mqTF!Xx;FkUhk^{ zFO(LDEBgv2YK4j0&g1k{*rMQakUe<4(<{X(tc)zjK%4Bm=hX;uL^LpSG3Uv2UGq{{ zqR^sS9&IXXuH4{oh>1mk(_AmqdBJLi;ElUZeT?Z~Qe;uw_Uf1Zn-MxX|(Gp9fU zkE*X7hl|>QkToZydLHSCNPIq0;%B|QSgC=5NgOnkpe*39Agm$y(n}dl&YsdFtKjuP zuUxONGP1;Q2sG>nP~l|}5`8e`i;J|`<1F6VB&+CmX?Jd}uwvr4!X?mf!BW5>VIjlv zC6^rqUZ@?&e17*%1s5aBC2<7?&;7kC6`A(3TBznqo{GEQ$^c zLN3Mu94v>#A58i3;dY16Ht`Q&+iz`W^;c+cumcsKTTD$|7ffe}{`~FHBg&?DR-c;gnil;Yye3LKu> z=N7MtoUh=rpZnL`h}hV(6Z@=C5;4b&hPW*pPA~XZa+Yv9ojTZ_8$EXxH@JTr!zIwL zWUZZSs>H{N-Hp`zdt#C5VWH>aJ^D~S+MMwU680u2_6RTNo12`g}bc3ymB zWo+WFVg^lf`!+BvnJw+F*l?hdu}NT;6CcxU|F^qV%wmzZ++tPg!oV2M#G>S>R(6l-)ib`DE>IHMK~arMW8?pI>>b*xH245W*8W*y1IJAkW+p`!6 zDsY@!vQT*avpuZOWBIgw=5)RSrD1rv!Ldb9fg^MA(Y*^fb#A>~CDYOpmUjxYjj=_~ zfkCK>JJ60rNnC-Wa}T4jZr$XyWx50n?I z$?C~#*`E4^EI50@UDomEkuNSYSBQb4FFK+8y@&^B3?)Nx zfr3lCd!NiqyQ@!wpNZWp)Mn~s5fRX42&~`puuWRZ*7&{J?M31BMz*VsmHCw#93CEZif({C1j7$@5 zMD=`9nlPcE_SPDO7R^Xb(;Su1!1=-VHwRjVA64ThRQ0stP?)fafze}?uJ>Mn4i^Xg zdNU~}0U^)DssTRImBII48$Vsu*QB7*=;tIV;Ba7e!)Jyk|C05^kI%14{Uv(4^xH;z z-Ba=DeRUE-e$F(+rjtjvxoEfL4{+iLm=ezS$rC`gCE2_CH z0v(YLHobkDn?A8gSL^TJ?0-+M9BG_xWJkzkT11onE%I=KALUb-$L^-jYwa z*sM9pZtgX1CGIQJ%{y7MBTP3JZM;xZ=_h`F;o8cr*4J+H?Z5Et;<4}b@AifJzyCVZ z{qZ4}ipSTkg|#eQc7o%G_Jt~O9d0ABy)L#t-o=V{-ca9PZC|l1z`!U?A&AdPB;<`{ zN%+R{`|a7$1?PXxf3dT8a)QhC&)e_C#aMDWakxBs`(vGVo?|cA^SRt~1TLPA{K>jDvnux8<^#^>wO-r^zGEtTHKXdRn?u@n?GG2e=y1D~`MSB? zT5{FI{~dSy0-IZf376)JR`6V1e)#&!aHrZu`!{Veid9+D?f>I<<+EQ~R=+L%{cEFY ze!Sy6cZS9(EOXW~Mz$?hNcqjYd58PukhU4(>k|@xtKYYle*5D@`+5K6S#mXJR!?r4 z09r!yOL^&9n;oBoEPi|}zHGNUKuq`t@&1V^0+&?eg}$y8kDmLs*SyPhowQC)xcz$93iIeMyFk^VKu2i87r_Ze zb9(D;h%L)?cm8r{z4-r)91tLljWt8+KAc zkaKx$n@;E3f~7WFt7r8)v({c+F4L0X($e~B-x5!8MiwXG7a|QmWNy8)QuWT(kDF7& zYx^qj`U0PmTx(aCYx5s;H{ZT+-ln%zQ{|s0@+_5evwM2r@HLLsz)fXK6*w}VAHB<= zFrm#sAb7*7DQ2p#Z=`I@pM3P?X5rKJ(mo#&zi!lw)ROML{P=fk;Qe6vD_kq>~x?s zXr4T%(Jy#ITgw&h2PMxJo?L$Ms;Q#css!%+?K0&3ccg=`h=p&sS zy*%W-`j3wNsi&>e3TIW_dAo9ApRl^0&-Jn+Hdj}9Y8NC`39G(yWM~v&X_8~q>~DGT z{^`pIvrmGT%eHgbn7m3n*eb<*)Q1$9%`^c#K>^qc)fvokJ2Qt+j+#ktL9w-!DK zoPNuob!C{ZNo2=8m(FSd2Zgf62ks6$5sT%`gf@LV+W&sd&yJOhCcLX_Uf$<&5}7b( z_Mf}Q9Xkzw_QZy{*&WMctp91O^yvJx)KgbmpK@6h?Jr5Pa`b$+x8axagn14oj2$m> zt*&)Xei`xq*Y>pMxkt((CnRP&XiAXCQf0|tc|Vjcf6f_ zsxQn=q%_GY`pd5gs=h1&62S^xnh|VEGQ;h^ch1-EyYuIr+wSCEPHX-A*-cC5M=Bgz zas0>Hkb7C>e=Y?yDYBdj-aKXg+;w&?_ns6wDtv8ys(0&_*s^Su7H&os0S{M&Sqw+c z{j9iNTkh}fRAMm4Z+YL_paTm7`B{~B<*=x=)No)1Q=remO|7@LMPIq)a%Nfb(Gshzb0@^bb=ajnem-w| z6aQLmE1SspBbM@&-`Qq2Ew%p|wC3pfTcs!cuBLT`?f(}zFKOxi=NlG>+HdTh|7?TP z^jS+<8JH9~Tm&2DSpM4hGU@H764kv1uZ|jS^Iw1Zwapfe+Vcx{FXO%tdi<{Z&vyd9 zT+C7f?gz@R%6mVDmqB!{cEVz%szAHiUthk=D{|PhY11a*84ecl4rRMU&P-+ItL<-n zdbf(#(Zk$)o)bf(0c#V#gUMH~%Tu4}UYNJf!Y@wgt7e(c?PXE1-{!m*zI-4n$Upb^ z>5w&vb%9&nJwBk)q54DOnDw!kRmuut6J9Khy4)TX9=`l)Qpu7TY?4ys~WKiTNXut@yWjCeKCDK92CU7dM%!=HaaHzMT?zl-m8 zT4LvafJunkLZsuxrp;PK+#aVcuR7yx#v)T!Uw_K+#BIL)56q2&Kr5qdI9a3{ZY=r? zDxNd1n*Q4Oy*YjP=O4-QPUkOQ`hJ#PP`cH%OKtB9n%`Dz{o9zZyRJRz;|U3-r=`l@ zUhZdA5nHpwBzAS4Z2PO6?9^i!?J}RA9Qh&>J=aQk!Ze2s`H5EIhyA$no$|UbCD(7f zGE2bsXqHfgY2m|p-K;rx+4VSfh-t8^d|sA))GE~b^4W;v4|i?<;@^Lm^SAUQ(CEFo zKnlYm@d8%)++|8P7k#;LtvO_NoU;5X>(`EV{s(1zX?A`7F4ps7P-ErgtvRQrt)0HX zezh{k(~B&<3vOI3ow9IFzwRpidjFTV_ph$Jkr(Q-nrruTP}SWY>)_SSz{C;4qIdh= zy|S_yZD(8W-MI0BXYI=HUAI`|pPmtESh8V91f$2@N59YQkhGULw2NPSzr3V*;-%2} z;wn>^n_u164Y)A>YQmy-_lgz-^X05!47hZmGt94D<^pPCg62qqggBHKHh#9-weI(f>k4JZn$Q02-+J-P zk!#0}MD-h<*_Zin_-hXDt0&c7eI4GDkUUYMa z$=!KdB*xL>P4LE$a8^a1qpR{uw;BeopY<=S0JM}0Jo#*}=YR%d$7$X2*^_RbaDTHq z>1LE<+0k8Fp3bbg`el3LZ>Wh3jUQRq<~OD8j_WPlAs4*y*z1ga#m}}B-#@gZA9l#V z4nc_;mLp|*i-P}rTWKJ=dT%6;zrk0nwy;G#;58wjvF$(}sRo{nudi-$OVzq&wD3n= z-txJ{4-#r}-8(^}xuDTA`^JOI5_&DauDZ3x=cw26#hYJ;TIG8BLLH*O-+0i?;n=(? zQ+S6~B1* zprkae#m@1%$-EisZQI{zm8|PpQ@k_hmFR1`qRhfqoltMBKdGTiWc#Hl{0VoUA{UWYdu_6WG!uetbE_{$A`4U@+*d>SdQ zLeKp_xd?WgkHGGR>kKZJo1FOU)_k1NB^qvi?FD=A`bSyDUfocWIA%D!&aLQ|u`KGm zckI|P)%%y#KQ8p!yGm@Eji`6@mt$2^mnXgbccT1wRB!9kZN~PK*2qi+FEaoob|Zlo zCQOSO4)1#=srkdgI`X&R;TP>w@7o3T*E{~o*;wDjeMz)NW_FImffw#<|5F!rLE~q_ z8i(Z!DKn4dyt*2DI*Wt{;=|cuL~nIz8D&p zGQ}|o`0l+_vfzf^>@Lx2fu!J#L0nEbucpquFBE-$(H^Mj4Gc`ipc8y%9r*j|TD;iN zIa`%{=gIz_XFHi`PxdF#%#ZrdcE8M537WVlVD}5FPwL6v1wMhwbV%I2P=1igvc$i! zLJXYMpu{E77bZ+b`RZ$oF7Aoln52BgWDWD=X0GJ;4{I_bc7NY%yNZ|bRPE7o>79FJ zw-_ESNdZm9Kny$)v!Ik=l2gIOC1iL3VD@QYro+Y-{W0=B}p=PBV}1d*>XRU8Z*KO@Rk^-3K^8 z8W$-rL|)>4lQZGQ@}!$L6%2ijZZft{`ppE5r2dR!*>K`}yAKm2t z$a!AZ)JyBaUq$uQnfzdVECww}PIxsiEJ-Xj7G13va{ji-C6UkTlEZ3!_g*@e90PSB zbd=2GjiArbERL&>&1P4LRx>08uTQ%DZHN2ij~cL&>_S8X!xF>Ljhi*B{;|H??0QjA z*CYHxVNTII_cz?+PT8PfvNpiopKEDv#>gUP- z)a&V){+sK<%Uch5Swf=HfuZpMX!O*q)AwkXEyu>#jZPd+Gpep`5-zfaSue1WfzhM= z*ycp!;^e1HmvKE@fc!IG>iT6;^%V%Cb1aUl;fBe*n!UgET+Uc3^n4 z;BBtfw750N``)-lwZHtiD`-~L(Z=R|Rh%zDYi(I} z@Ve$pO`pA!c-i@^ejQbmgnHxz=v1G;$+tsv_9h&!xyjg?-dA^~(zK*vF_UTJ(VCNP zukBKfw!#V^g$sTS3`^!-KeT&hSLpf0E5q5<8rvl;Q{+uFef@9megF1NmFWtrnV=yk zkTblPb_cKW;V7;AaCdjtUU?hqzf7Ewcoggg~P$d)cmz$SCekJ zZK>WQS6F*MNvxwfsP4gsGOwz>*N$6c4PV#+7<^YK?Nin8w3UVUvSw3Me$!s z%Z|HUbY1zqg6HOU$pUFcju2BoV~Y+p=4D>59k=|=ne6&ftmeqRch04$ciW%G3rvER zU5#&8I2_nAiuQKA=HXe}+3|A|>y2A|+ul9e(?276#wKX7z`*nmbmWJ$e{q07QO+hk zC;b;u@(Tl*{@QL^;1d0LUhSLBNB1bSxISktRoeu$pOHmLEJ5&BLvMQbC0%b;rLv=#DL=nOGovEi`hk5RtMNC4mW=5BO9GsYc<>ZSp zkA-nJa*u24?&$v+6q|F`{r=_q$z==PKocr#k;T+4Z%ayaeYPKPuGjBx;fa_N7x|Jk zmV3+BLwV|RqxV*++B`a}V^P1njkpq78Bp^VEuPetetN!E&3w=^Im=U zntxBzmuJT$?c=aZ%Cm)6p@y7C{$7)q{AI}+v!`D5w=x==CP=tDxU3hPd%OOJ?9t!f z>egNSwr8Q)^d|mX!<^kUtxWTi$;}K8pWqFr4z_tL8?IW(fx)Q2JV0R6-^RPGWj&Xsy9s<*?k1cw@z(*@tf_bRJWxKSaKx`9 z{Z{DeXV24M+8~Qc59M)c2xz{SN?pFRU8Y5c%Pxu2DQ9)8o87Lj(evQ-_b)DihA*Ne zKlZRHR@+yYt!RB2rLx}W=B)nIP(AUS#1Fb_=sLoRKZSHgrU?h4;vGBY&RBQ( z=<$6aY`rx%N;WQgs>!Yxm2LQKsZqwQseAz`x31n;>-Y~ErxP|iEN6IfVxn^Ez8!x! zZtR+{(cdHd!$KpCA1{hdEQtH^^-%q{jpxOZ*%VLxK6-NcsY9I4>wf91gqAxDOunpE ztP0Z7(!Q6U@9SfFD!aK&j`QLa?cS;{oOWw&RXx1ky2tq ziZ~37Wf!*&uS3o*(aY<0DSxjGa_rdl?&?!*fxrg~x0t?KxJT#1%jj>PK65#l2rYd5 zGdlmfk*@b*Ij?B(#d3Pl{aauKH={Yz=Iysw#V@a&#>xA=n3eU{rUb|CtH0T}X62=} zE0x8*z8L1vcw${`zWzDiWp0`gJBmKNx8pvX8+Co=V)@yunQOjg+*U!HZOEgx!Gu9_ zjY`Uuhy^kw8CRTMyPBk~s@is94~uBQi=Yb&_rI33?%i9+D064UR>faI4;H=*66?^& zWL5VS>(>4daABc+dgk4$FD%)Qs&m2;4MSre6N`fE!((-4ngpZ;11sMM99FXq>lG}y zGET+k|X zi?{*<=u`)eFM<)fxWncjsYGdt321;O%jDtV%Ocn-UKGc>c$`5oH1S2gU%=mt2D!;br+0X@2CDZHqUojQcv-ND)LuwrC!6D+V|GV6guF3nJ%t*2Is2ZTfQuMke)5~~Hxc!3-V_63`8ffduCL!S@c>g{0?jrd}Hp(HD8 zLFnQLXa;I%5NvNX+Bh!S6+kKPZbq0rmz+47K xj}l+EMre5ps+l_AhbVz8ggDkk{lkC817}0{&oO^I%fP_E;OXk;vd$@?2>|B*6=VPa literal 0 HcmV?d00001 From a25d11ad1a3d7c5660127229a3a9ffd62a2225e4 Mon Sep 17 00:00:00 2001 From: Kris Date: Sat, 25 Oct 2025 17:12:35 +0530 Subject: [PATCH 011/189] Add example: shapes_math_angle_rotation (angle rotation lines) (#5236) Co-authored-by: Ray --- examples/shaders/shaders_palette_switch.c | 4 +- examples/shapes/shapes_math_angle_rotation.c | 102 ++++ .../shapes/shapes_math_angle_rotation.png | Bin 0 -> 4869 bytes .../shapes_math_angle_rotation.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 2 + 5 files changed, 675 insertions(+), 2 deletions(-) create mode 100644 examples/shapes/shapes_math_angle_rotation.c create mode 100644 examples/shapes/shapes_math_angle_rotation.png create mode 100644 projects/VS2022/examples/shapes_math_angle_rotation.vcxproj diff --git a/examples/shaders/shaders_palette_switch.c b/examples/shaders/shaders_palette_switch.c index 048fe7fbc..e23cad1d3 100644 --- a/examples/shaders/shaders_palette_switch.c +++ b/examples/shaders/shaders_palette_switch.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [shaders] example - palette switch +* raylib [shaders] example - palette switch * * Example complexity rating: [★★★☆] 3/4 * @@ -11,7 +11,7 @@ * on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders * raylib comes with shaders ready for both versions, check raylib/shaders install folder * -* Example originally created with raylib 2.5, last time updated with raylib 3.7 +* Example originally created with raylib 2.5, last time updated with raylib 3.7 * * Example contributed by Marco Lizza (@MarcoLizza) and reviewed by Ramon Santamaria (@raysan5) * diff --git a/examples/shapes/shapes_math_angle_rotation.c b/examples/shapes/shapes_math_angle_rotation.c new file mode 100644 index 000000000..0e4802064 --- /dev/null +++ b/examples/shapes/shapes_math_angle_rotation.c @@ -0,0 +1,102 @@ +/******************************************************************************************* +* +* raylib [shapes] example - Math angle rotation lines +* +* Example complexity rating: [★☆☆☆] 1/4 +* +* Example originally created with raylib 5.5, last time updated with raylib 5.6 +* +* Example contributed by Kris (@krispy-snacc) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" // for DEG2RAD + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 720; + const int screenHeight = 400; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - angle rotation lines"); + SetTargetFPS(60); + + Vector2 center = { screenWidth / 2.0f, screenHeight / 2.0f }; + const float lineLength = 150.0f; + + // Predefined angles for fixed lines + int angles[] = { 0, 30, 60, 90 }; + int numAngles = sizeof(angles)/sizeof(angles[0]); + + float totalAngle = 0.0f; // Animated rotation angle + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + totalAngle += 1.0f; // degrees per frame + if (totalAngle >= 360.0f) totalAngle -= 360.0f; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(WHITE); + + DrawText("Fixed angles + rotating line", 10, 10, 20, LIGHTGRAY); + + // Draw fixed-angle lines with colorful gradient + for (int i = 0; i < numAngles; i++) + { + float rad = angles[i] * DEG2RAD; + Vector2 end = { center.x + cosf(rad) * lineLength, + center.y + sinf(rad) * lineLength }; + + // Gradient color from green → cyan → blue → magenta + Color col; + switch(i) + { + case 0: col = GREEN; break; + case 1: col = ORANGE; break; + case 2: col = BLUE; break; + case 3: col = MAGENTA; break; + default: col = WHITE; break; + } + + DrawLineEx(center, end, 5.0f, col); + + // Draw angle label slightly offset along the line + Vector2 textPos = { center.x + cosf(rad) * (lineLength + 20), + center.y + sinf(rad) * (lineLength + 20) }; + DrawText(TextFormat("%d°", angles[i]), (int)textPos.x, (int)textPos.y, 20, col); + } + + // Draw animated rotating line with changing color + float animRad = totalAngle * DEG2RAD; + Vector2 animEnd = { center.x + cosf(animRad) * lineLength, + center.y + sinf(animRad) * lineLength }; + + // Cycle through HSV colors for animated line + Color animCol = ColorFromHSV(fmodf(totalAngle, 360.0f), 0.8f, 0.9f); + DrawLineEx(center, animEnd, 5.0f, animCol); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/shapes/shapes_math_angle_rotation.png b/examples/shapes/shapes_math_angle_rotation.png new file mode 100644 index 0000000000000000000000000000000000000000..fd9a92360b6c2f187c91324a3b2005bb83471e5d GIT binary patch literal 4869 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 TY^lb;z`)??>gTe~DWM4fetn1b literal 0 HcmV?d00001 diff --git a/projects/VS2022/examples/shapes_math_angle_rotation.vcxproj b/projects/VS2022/examples/shapes_math_angle_rotation.vcxproj new file mode 100644 index 000000000..0bee76192 --- /dev/null +++ b/projects/VS2022/examples/shapes_math_angle_rotation.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 + shapes_math_angle_rotation + 10.0 + shapes_math_angle_rotation + + + + 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 ec35ed5e5..8d2704abf 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -395,6 +395,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_text_file_loading", "e 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", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 From e501dfad60791346ade0cd389fd04e20e97d427f Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Sat, 25 Oct 2025 23:13:24 +0200 Subject: [PATCH 012/189] [rlsw] Subpixel correction (#5300) * fix triangle cracking * subpixel corretion for quads * replace Bresenham for DDA + subpixel correction * consistency * adding note * style tweaks --- src/external/rlsw.h | 502 ++++++++++++++++++++++---------------------- 1 file changed, 252 insertions(+), 250 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index bc7a813d3..50a60d74f 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -819,8 +819,8 @@ typedef struct { float clearColor[4]; // Color used to clear the screen float clearDepth; // Depth value used to clear the screen - int vpCenter[2]; // Viewport center - int vpHalfSize[2]; // Viewport half dimensions + float vpCenter[2]; // Viewport center + float vpHalf[2]; // Viewport half dimensions int vpSize[2]; // Viewport dimensions (minus one) int vpMin[2]; // Viewport minimum renderable point (top-left) int vpMax[2]; // Viewport maximum renderable point (bottom-right) @@ -1040,6 +1040,34 @@ static inline void sw_add_vertex_grad_PTCH(sw_vertex_t *SW_RESTRICT out, const s out->homogeneous[3] += gradients->homogeneous[3]; } +static inline void sw_add_vertex_grad_scaled_PTCH( + sw_vertex_t *SW_RESTRICT out, + const sw_vertex_t *SW_RESTRICT gradients, + float scale) +{ + // Add gradients to Position + out->position[0] += gradients->position[0]*scale; + out->position[1] += gradients->position[1]*scale; + out->position[2] += gradients->position[2]*scale; + out->position[3] += gradients->position[3]*scale; + + // Add gradients to Texture coordinates + out->texcoord[0] += gradients->texcoord[0]*scale; + out->texcoord[1] += gradients->texcoord[1]*scale; + + // Add gradients to Color + out->color[0] += gradients->color[0]*scale; + out->color[1] += gradients->color[1]*scale; + out->color[2] += gradients->color[2]*scale; + out->color[3] += gradients->color[3]*scale; + + // Add gradients to Homogeneous coordinates + out->homogeneous[0] += gradients->homogeneous[0]*scale; + out->homogeneous[1] += gradients->homogeneous[1]*scale; + out->homogeneous[2] += gradients->homogeneous[2]*scale; + out->homogeneous[3] += gradients->homogeneous[3]*scale; +} + static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) { #if defined(SW_HAS_NEON) @@ -1977,18 +2005,18 @@ 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) +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` - //float du = sqrtf(duDx*duDx + duDy*duDy); - //float dv = sqrtf(dvDx*dvDx + dvDy*dvDy); + //float du = sqrtf(dUdx*dUdx + dUdy*dUdy); + //float dv = sqrtf(dVdx*dVdx + dVdy*dVdy); //float L = (du > dv)? du : dv; // Calculate the derivatives for each axis - float du2 = duDx*duDx + duDy*duDy; - float dv2 = dvDx*dvDx + dvDy*dvDy; - float L2 = (du2 > dv2)? du2 : dv2; + float dU2 = dUdx*dUdx + dUdy*dUdy; + float dV2 = dVdx*dVdx + dVdy*dVdy; + float L2 = (dU2 > dV2)? dU2 : dV2; SWfilter filter = (L2 > 1.0f)? tex->minFilter : tex->magFilter; @@ -2081,8 +2109,8 @@ static inline void sw_blend_colors(float *SW_RESTRICT dst/*[4]*/, const float *S //------------------------------------------------------------------------------------------- static inline void sw_project_ndc_to_screen(float screen[2], const float ndc[4]) { - screen[0] = RLSW.vpCenter[0] + ndc[0]*RLSW.vpHalfSize[0]; - screen[1] = RLSW.vpCenter[1] - ndc[1]*RLSW.vpHalfSize[1]; + screen[0] = RLSW.vpCenter[0] + ndc[0]*RLSW.vpHalf[0] + 0.5f; + screen[1] = RLSW.vpCenter[1] - ndc[1]*RLSW.vpHalf[1] + 0.5f; } //------------------------------------------------------------------------------------------- @@ -2295,67 +2323,73 @@ static inline void sw_triangle_clip_and_project(void) #define DEFINE_TRIANGLE_RASTER_SCANLINE(FUNC_NAME, ENABLE_TEXTURE, ENABLE_DEPTH_TEST, ENABLE_COLOR_BLEND) \ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, \ - const sw_vertex_t *end, float duDy, float dvDy) \ + const sw_vertex_t *end, float dUdy, float dVdy) \ { \ - /* Convert and center the screen coordinates */ \ - int xStart = (int)(start->screen[0] + 0.5f); \ - int xEnd = (int)(end->screen[0] + 0.5f); \ - int y = (int)start->screen[1]; \ + /* Gets the start and end coordinates */ \ + int xStart = (int)start->screen[0]; \ + int xEnd = (int)end->screen[0]; \ + \ + /* Avoid empty lines */ \ + if (xStart == xEnd) return; \ + \ + /* Compute the subpixel distance to traverse before the first pixel */ \ + float xSubstep = 1.0f - sw_fract(start->screen[0]); \ \ /* Compute the inverse horizontal distance along the X axis */ \ - float dx = end->screen[0] - start->screen[0]; \ - if (fabsf(dx) < 1e-6f) return; \ - float dxRcp = 1.0f/dx; \ + float dxRcp = 1.0f/(end->screen[0] - start->screen[0]); \ \ /* Compute the interpolation steps along the X axis */ \ - float dzDx = (end->homogeneous[2] - start->homogeneous[2])*dxRcp; \ - float dwDx = (end->homogeneous[3] - start->homogeneous[3])*dxRcp; \ + float dZdx = (end->homogeneous[2] - start->homogeneous[2])*dxRcp; \ + float dWdx = (end->homogeneous[3] - start->homogeneous[3])*dxRcp; \ \ - float dcDx[4] = { 0 }; \ - dcDx[0] = (end->color[0] - start->color[0])*dxRcp; \ - dcDx[1] = (end->color[1] - start->color[1])*dxRcp; \ - dcDx[2] = (end->color[2] - start->color[2])*dxRcp; \ - dcDx[3] = (end->color[3] - start->color[3])*dxRcp; \ + float dCdx[4] = { \ + (end->color[0] - start->color[0])*dxRcp, \ + (end->color[1] - start->color[1])*dxRcp, \ + (end->color[2] - start->color[2])*dxRcp, \ + (end->color[3] - start->color[3])*dxRcp \ + }; \ \ - float duDx = 0.0f, dvDx = 0.0f; \ + float dUdx = 0.0f; \ + float dVdx = 0.0f; \ if (ENABLE_TEXTURE) { \ - duDx = (end->texcoord[0] - start->texcoord[0])*dxRcp; \ - dvDx = (end->texcoord[1] - start->texcoord[1])*dxRcp; \ + dUdx = (end->texcoord[0] - start->texcoord[0])*dxRcp; \ + dVdx = (end->texcoord[1] - start->texcoord[1])*dxRcp; \ } \ \ /* Initializing the interpolation starting values */ \ - float z = start->homogeneous[2]; \ - float w = start->homogeneous[3]; \ + float z = start->homogeneous[2] + dZdx*xSubstep; \ + float w = start->homogeneous[3] + dWdx*xSubstep; \ \ - float color[4] = { 0 }; \ - color[0] = start->color[0]; \ - color[1] = start->color[1]; \ - color[2] = start->color[2]; \ - color[3] = start->color[3]; \ + float color[4] = { \ + start->color[0] + dCdx[0]*xSubstep, \ + start->color[1] + dCdx[1]*xSubstep, \ + start->color[2] + dCdx[2]*xSubstep, \ + start->color[3] + dCdx[3]*xSubstep \ + }; \ \ - float u = 0.0f, v = 0.0f; \ + float u = 0.0f; \ + float v = 0.0f; \ if (ENABLE_TEXTURE) { \ - u = start->texcoord[0]; \ - v = start->texcoord[1]; \ + u = start->texcoord[0] + dUdx*xSubstep; \ + v = start->texcoord[1] + dVdx*xSubstep; \ } \ \ /* Pre-calculate the starting pointers for the framebuffer row */ \ + int y = (int)start->screen[1]; \ void *cptr = GET_COLOR_PTR(RLSW.framebuffer.color, y*RLSW.framebuffer.width + xStart); \ void *dptr = GET_DEPTH_PTR(RLSW.framebuffer.depth, y*RLSW.framebuffer.width + xStart); \ \ /* Scanline rasterization */ \ for (int x = xStart; x < xEnd; x++) \ { \ - /* Pixel color computation */ \ float wRcp = 1.0f/w; \ float srcColor[4] = { \ - color[0]*wRcp, \ - color[1]*wRcp, \ - color[2]*wRcp, \ - color[3]*wRcp \ + color[0]*wRcp, \ + color[1]*wRcp, \ + color[2]*wRcp, \ + color[3]*wRcp \ }; \ \ - /* Test and write depth */ \ if (ENABLE_DEPTH_TEST) \ { \ /* TODO: Implement different depth funcs? */ \ @@ -2363,6 +2397,7 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, if (z > depth) goto discard; \ } \ \ + /* TODO: Implement depth mask */ \ sw_framebuffer_write_depth(dptr, z); \ \ if (ENABLE_TEXTURE) \ @@ -2370,7 +2405,7 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, float texColor[4]; \ float s = u*wRcp; \ float t = v*wRcp; \ - sw_texture_sample(texColor, tex, s, t, duDx, duDy, dvDx, dvDy); \ + sw_texture_sample(texColor, tex, s, t, dUdx, dUdy, dVdx, dVdy); \ srcColor[0] *= texColor[0]; \ srcColor[1] *= texColor[1]; \ srcColor[2] *= texColor[2]; \ @@ -2391,16 +2426,16 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, \ /* Increment the interpolation parameter, UVs, and pointers */ \ discard: \ - z += dzDx; \ - w += dwDx; \ - color[0] += dcDx[0]; \ - color[1] += dcDx[1]; \ - color[2] += dcDx[2]; \ - color[3] += dcDx[3]; \ + z += dZdx; \ + w += dWdx; \ + color[0] += dCdx[0]; \ + color[1] += dCdx[1]; \ + color[2] += dCdx[2]; \ + color[3] += dCdx[3]; \ if (ENABLE_TEXTURE) \ { \ - u += duDx; \ - v += dvDx; \ + u += dUdx; \ + v += dVdx; \ } \ \ INC_COLOR_PTR(cptr); \ @@ -2430,60 +2465,71 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1, if (h02 < 1e-6f) return; \ \ /* Precompute the inverse values without additional checks */ \ - float invH02 = 1.0f/h02; \ - float invH01 = (h01 > 1e-6f)? 1.0f/h01 : 0.0f; \ - float invH12 = (h12 > 1e-6f)? 1.0f/h12 : 0.0f; \ + float h02Rcp = 1.0f/h02; \ + float h01Rcp = (h01 > 1e-6f)? 1.0f/h01 : 0.0f; \ + float h12Rcp = (h12 > 1e-6f)? 1.0f/h12 : 0.0f; \ \ /* Pre-calculation of slopes */ \ - float dx02 = (x2 - x0)*invH02; \ - float dx01 = (x1 - x0)*invH01; \ - float dx12 = (x2 - x1)*invH12; \ + float dXdy02 = (x2 - x0)*h02Rcp; \ + float dXdy01 = (x1 - x0)*h01Rcp; \ + float dXdy12 = (x2 - x1)*h12Rcp; \ + \ + /* Y subpixel correction */ \ + float y0Substep = 1.0f - sw_fract(y0); \ + float y1Substep = 1.0f - sw_fract(y1); \ \ /* Y bounds (vertical clipping) */ \ - int yTop = (int)(y0 + 0.5f); \ - int yMiddle = (int)(y1 + 0.5f); \ - int yBottom = (int)(y2 + 0.5f); \ + int yTop = (int)y0; \ + int yMid = (int)y1; \ + int yBot = (int)y2; \ \ /* Compute gradients for each side of the triangle */ \ - sw_vertex_t vDy02, vDy01, vDy12; \ - sw_get_vertex_grad_PTCH(&vDy02, v0, v2, invH02); \ - sw_get_vertex_grad_PTCH(&vDy01, v0, v1, invH01); \ - sw_get_vertex_grad_PTCH(&vDy12, v1, v2, invH12); \ + sw_vertex_t dVXdy02, dVXdy01, dVXdy12; \ + sw_get_vertex_grad_PTCH(&dVXdy02, v0, v2, h02Rcp); \ + sw_get_vertex_grad_PTCH(&dVXdy01, v0, v1, h01Rcp); \ + sw_get_vertex_grad_PTCH(&dVXdy12, v1, v2, h12Rcp); \ \ - /* Initializing scanline variables */ \ - sw_vertex_t vLeft = *v0; \ - vLeft.screen[0] = x0; \ - sw_vertex_t vRight = *v0; \ - vRight.screen[0] = x0; \ + /* Get a copy of vertices for interpolation and apply substep correction */ \ + sw_vertex_t vLeft = *v0, vRight = *v0; \ + sw_add_vertex_grad_scaled_PTCH(&vLeft, &dVXdy02, y0Substep); \ + sw_add_vertex_grad_scaled_PTCH(&vRight, &dVXdy01, y0Substep); \ + \ + vLeft.screen[0] += dXdy02*y0Substep; \ + vRight.screen[0] += dXdy01*y0Substep; \ \ /* Scanline for the upper part of the triangle */ \ - for (int y = yTop; y < yMiddle; y++) \ + for (int y = yTop; y < yMid; y++) \ { \ vLeft.screen[1] = vRight.screen[1] = y; \ \ - if (vLeft.screen[0] < vRight.screen[0]) FUNC_SCANLINE(tex, &vLeft, &vRight, vDy02.texcoord[0], vDy02.texcoord[1]); \ - else FUNC_SCANLINE(tex, &vRight, &vLeft, vDy02.texcoord[0], vDy02.texcoord[1]); \ + if (vLeft.screen[0] < vRight.screen[0]) FUNC_SCANLINE(tex, &vLeft, &vRight, dVXdy02.texcoord[0], dVXdy02.texcoord[1]); \ + else FUNC_SCANLINE(tex, &vRight, &vLeft, dVXdy02.texcoord[0], dVXdy02.texcoord[1]); \ \ - sw_add_vertex_grad_PTCH(&vLeft, &vDy02); \ - vLeft.screen[0] += dx02; \ - sw_add_vertex_grad_PTCH(&vRight, &vDy01); \ - vRight.screen[0] += dx01; \ + sw_add_vertex_grad_PTCH(&vLeft, &dVXdy02); \ + vLeft.screen[0] += dXdy02; \ + \ + sw_add_vertex_grad_PTCH(&vRight, &dVXdy01); \ + vRight.screen[0] += dXdy01; \ } \ \ - /* Scanline for the lower part of the triangle */ \ - vRight = *v1, vRight.screen[0] = x1; \ + /* Get a copy of next right for interpolation and apply substep correction */ \ + vRight = *v1; \ + sw_add_vertex_grad_scaled_PTCH(&vRight, &dVXdy12, y1Substep); \ + vRight.screen[0] += dXdy12*y1Substep; \ \ - for (int y = yMiddle; y < yBottom; y++) \ + /* Scanline for the lower part of the triangle */ \ + for (int y = yMid; y < yBot; y++) \ { \ vLeft.screen[1] = vRight.screen[1] = y; \ \ - if (vLeft.screen[0] < vRight.screen[0]) FUNC_SCANLINE(tex, &vLeft, &vRight, vDy02.texcoord[0], vDy02.texcoord[1]); \ - else FUNC_SCANLINE(tex, &vRight, &vLeft, vDy02.texcoord[0], vDy02.texcoord[1]); \ + if (vLeft.screen[0] < vRight.screen[0]) FUNC_SCANLINE(tex, &vLeft, &vRight, dVXdy02.texcoord[0], dVXdy02.texcoord[1]); \ + else FUNC_SCANLINE(tex, &vRight, &vLeft, dVXdy02.texcoord[0], dVXdy02.texcoord[1]); \ \ - sw_add_vertex_grad_PTCH(&vLeft, &vDy02); \ - vLeft.screen[0] += dx02; \ - sw_add_vertex_grad_PTCH(&vRight, &vDy12); \ - vRight.screen[0] += dx12; \ + sw_add_vertex_grad_PTCH(&vLeft, &dVXdy02); \ + vLeft.screen[0] += dXdy02; \ + \ + sw_add_vertex_grad_PTCH(&vRight, &dVXdy12); \ + vRight.screen[0] += dXdy12; \ } \ } @@ -2716,41 +2762,46 @@ static inline void FUNC_NAME(void) const sw_vertex_t *v3 = sortedVerts[3]; \ \ /* Screen bounds (axis-aligned) */ \ - int xMin = (int)(v0->screen[0] + 0.5f); \ - int yMin = (int)(v0->screen[1] + 0.5f); \ - int xMax = (int)(v2->screen[0] + 0.5f); \ - int yMax = (int)(v2->screen[1] + 0.5f); \ + int xMin = (int)v0->screen[0]; \ + int yMin = (int)v0->screen[1]; \ + int xMax = (int)v2->screen[0]; \ + int yMax = (int)v2->screen[1]; \ \ - int width = xMax - xMin; \ - int height = yMax - yMin; \ + float w = v2->screen[0] - v0->screen[0]; \ + float h = v2->screen[1] - v0->screen[1]; \ \ - if ((width == 0) || (height == 0)) return; \ + if ((w == 0) || (h == 0)) return; \ \ - float wRcp = (width > 0.0f)? 1.0f/width : 0.0f; \ - float hRcp = (height > 0.0f)? 1.0f/height : 0.0f; \ + float wRcp = (w > 0.0f)? 1.0f/w : 0.0f; \ + float hRcp = (h > 0.0f)? 1.0f/h : 0.0f; \ + \ + /* Subpixel corrections */ \ + float xSubstep = 1.0f - sw_fract(v0->screen[0]); \ + float ySubstep = 1.0f - sw_fract(v0->screen[1]); \ \ /* Calculation of vertex gradients in X and Y */ \ - float tcDx[2], tcDy[2]; \ + float dUdx, dVdx; \ + float dUdy, dVdy; \ if (ENABLE_TEXTURE) { \ - tcDx[0] = (v1->texcoord[0] - v0->texcoord[0])*wRcp; \ - tcDx[1] = (v1->texcoord[1] - v0->texcoord[1])*wRcp; \ - tcDy[0] = (v3->texcoord[0] - v0->texcoord[0])*hRcp; \ - tcDy[1] = (v3->texcoord[1] - v0->texcoord[1])*hRcp; \ + dUdx = (v1->texcoord[0] - v0->texcoord[0])*wRcp; \ + dVdx = (v1->texcoord[1] - v0->texcoord[1])*wRcp; \ + dUdy = (v3->texcoord[0] - v0->texcoord[0])*hRcp; \ + dVdy = (v3->texcoord[1] - v0->texcoord[1])*hRcp; \ } \ \ - float cDx[4], cDy[4]; \ - cDx[0] = (v1->color[0] - v0->color[0])*wRcp; \ - cDx[1] = (v1->color[1] - v0->color[1])*wRcp; \ - cDx[2] = (v1->color[2] - v0->color[2])*wRcp; \ - cDx[3] = (v1->color[3] - v0->color[3])*wRcp; \ - cDy[0] = (v3->color[0] - v0->color[0])*hRcp; \ - cDy[1] = (v3->color[1] - v0->color[1])*hRcp; \ - cDy[2] = (v3->color[2] - v0->color[2])*hRcp; \ - cDy[3] = (v3->color[3] - v0->color[3])*hRcp; \ + float dCdx[4], dCdy[4]; \ + dCdx[0] = (v1->color[0] - v0->color[0])*wRcp; \ + dCdx[1] = (v1->color[1] - v0->color[1])*wRcp; \ + dCdx[2] = (v1->color[2] - v0->color[2])*wRcp; \ + dCdx[3] = (v1->color[3] - v0->color[3])*wRcp; \ + dCdy[0] = (v3->color[0] - v0->color[0])*hRcp; \ + dCdy[1] = (v3->color[1] - v0->color[1])*hRcp; \ + dCdy[2] = (v3->color[2] - v0->color[2])*hRcp; \ + dCdy[3] = (v3->color[3] - v0->color[3])*hRcp; \ \ - float zDx, zDy; \ - zDx = (v1->homogeneous[2] - v0->homogeneous[2])*wRcp; \ - zDy = (v3->homogeneous[2] - v0->homogeneous[2])*hRcp; \ + float dZdx, dZdy; \ + dZdx = (v1->homogeneous[2] - v0->homogeneous[2])*wRcp; \ + dZdy = (v3->homogeneous[2] - v0->homogeneous[2])*hRcp; \ \ /* Start of quad rasterization */ \ const sw_texture_t *tex; \ @@ -2760,15 +2811,15 @@ static inline void FUNC_NAME(void) void *dDstBase = RLSW.framebuffer.depth; \ int wDst = RLSW.framebuffer.width; \ \ - float zScanline = v0->homogeneous[2]; \ - float uScanline = v0->texcoord[0]; \ - float vScanline = v0->texcoord[1]; \ + float zScanline = v0->homogeneous[2] + dZdx*xSubstep + dZdy*ySubstep; \ + float uScanline = v0->texcoord[0] + dUdx*xSubstep + dUdy*ySubstep; \ + float vScanline = v0->texcoord[1] + dVdx*xSubstep + dVdy*ySubstep; \ \ float colorScanline[4] = { \ - v0->color[0], \ - v0->color[1], \ - v0->color[2], \ - v0->color[3] \ + v0->color[0] + dCdx[0]*xSubstep + dCdy[0]*ySubstep, \ + v0->color[1] + dCdx[1]*xSubstep + dCdy[1]*ySubstep, \ + v0->color[2] + dCdx[2]*xSubstep + dCdy[2]*ySubstep, \ + v0->color[3] + dCdx[3]*xSubstep + dCdy[3]*ySubstep \ }; \ \ for (int y = yMin; y < yMax; y++) \ @@ -2806,12 +2857,13 @@ static inline void FUNC_NAME(void) if (z > depth) goto discard; \ } \ \ + /* TODO: Implement depth mask */ \ sw_framebuffer_write_depth(dptr, z); \ \ if (ENABLE_TEXTURE) \ { \ float texColor[4]; \ - sw_texture_sample(texColor, tex, u, v, tcDx[0], tcDy[0], tcDx[1], tcDy[1]); \ + sw_texture_sample(texColor, tex, u, v, dUdx, dUdy, dVdx, dVdy); \ srcColor[0] *= texColor[0]; \ srcColor[1] *= texColor[1]; \ srcColor[2] *= texColor[2]; \ @@ -2828,32 +2880,32 @@ static inline void FUNC_NAME(void) else sw_framebuffer_write_color(cptr, srcColor); \ \ discard: \ - z += zDx; \ - color[0] += cDx[0]; \ - color[1] += cDx[1]; \ - color[2] += cDx[2]; \ - color[3] += cDx[3]; \ + z += dZdx; \ + color[0] += dCdx[0]; \ + color[1] += dCdx[1]; \ + color[2] += dCdx[2]; \ + color[3] += dCdx[3]; \ \ if (ENABLE_TEXTURE) \ { \ - u += tcDx[0]; \ - v += tcDx[1]; \ + u += dUdx; \ + v += dVdx; \ } \ \ INC_COLOR_PTR(cptr); \ INC_DEPTH_PTR(dptr); \ } \ \ - zScanline += zDy; \ - colorScanline[0] += cDy[0]; \ - colorScanline[1] += cDy[1]; \ - colorScanline[2] += cDy[2]; \ - colorScanline[3] += cDy[3]; \ + zScanline += dZdy; \ + colorScanline[0] += dCdy[0]; \ + colorScanline[1] += dCdy[1]; \ + colorScanline[2] += dCdy[2]; \ + colorScanline[3] += dCdy[3]; \ \ if (ENABLE_TEXTURE) \ { \ - uScanline += tcDy[0]; \ - vScanline += tcDy[1]; \ + uScanline += dUdy; \ + vScanline += dVdy; \ } \ } \ } @@ -3021,137 +3073,87 @@ static inline bool sw_line_clip_and_project(sw_vertex_t *v0, sw_vertex_t *v1) #define DEFINE_LINE_RASTER(FUNC_NAME, ENABLE_DEPTH_TEST, ENABLE_COLOR_BLEND) \ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ { \ - int x1 = (int)(v0->screen[0] + 0.5f); \ - int y1 = (int)(v0->screen[1] + 0.5f); \ - int x2 = (int)(v1->screen[0] + 0.5f); \ - int y2 = (int)(v1->screen[1] + 0.5f); \ + float x0 = v0->screen[0]; \ + float y0 = v0->screen[1]; \ + float x1 = v1->screen[0]; \ + float y1 = v1->screen[1]; \ \ - int dx = x2 - x1; \ - int dy = y2 - y1; \ + float dx = x1 - x0; \ + float dy = y1 - y0; \ \ - /* Handling of lines that are more horizontal or vertical */ \ - if ((dx == 0) && (dy == 0)) \ + /* Compute dominant axis and subpixel offset */ \ + float steps, substep; \ + if (fabsf(dx) > fabsf(dy)) \ { \ - /* TODO: A point should be rendered here */ \ - return; \ - } \ - \ - bool yLonger = (abs(dy) > abs(dx)); \ - int longLen, shortLen; \ - \ - if (yLonger) \ - { \ - longLen = dy; \ - shortLen = dx; \ + steps = fabsf(dx); \ + if (steps < 1.0f) return; \ + substep = (dx >= 0.0f)? (1.0f - sw_fract(x0)) : sw_fract(x0); \ } \ else \ { \ - longLen = dx; \ - shortLen = dy; \ + steps = fabsf(dy); \ + if (steps < 1.0f) return; \ + substep = (dy >= 0.0f)? (1.0f - sw_fract(y0)) : sw_fract(y0); \ } \ \ - /* Handling of traversal direction */ \ - int sgnInc = (longLen < 0)? -1 : 1; \ - int abslongLen = abs(longLen); \ + /* Compute per pixel increments */ \ + float xInc = dx/steps; \ + float yInc = dy/steps; \ + float stepRcp = 1.0f/steps; \ \ - /* Calculation of the increment step for the shorter coordinate */ \ - int decInc = 0; \ - if (abslongLen != 0) decInc = (shortLen << 16)/abslongLen; \ + float zInc = (v1->homogeneous[2] - v0->homogeneous[2])*stepRcp; \ + float rInc = (v1->color[0] - v0->color[0])*stepRcp; \ + float gInc = (v1->color[1] - v0->color[1])*stepRcp; \ + float bInc = (v1->color[2] - v0->color[2])*stepRcp; \ + float aInc = (v1->color[3] - v0->color[3])*stepRcp; \ \ - float longLenRcp = (abslongLen != 0)? (1.0f/abslongLen) : 0.0f; \ - \ - /* Calculation of interpolation steps */ \ - const float zStep = (v1->homogeneous[2] - v0->homogeneous[2])*longLenRcp; \ - const float rStep = (v1->color[0] - v0->color[0])*longLenRcp; \ - const float gStep = (v1->color[1] - v0->color[1])*longLenRcp; \ - const float bStep = (v1->color[2] - v0->color[2])*longLenRcp; \ - const float aStep = (v1->color[3] - v0->color[3])*longLenRcp; \ - \ - float z = v0->homogeneous[2]; \ - \ - float color[4] = { \ - v0->color[0], \ - v0->color[1], \ - v0->color[2], \ - v0->color[3] \ - }; \ + /* Initializing the interpolation starting values */ \ + float x = x0 + xInc*substep; \ + float y = y0 + yInc*substep; \ + float z = v0->homogeneous[2] + zInc*substep; \ + float r = v0->color[0] + rInc*substep; \ + float g = v0->color[1] + gInc*substep; \ + float b = v0->color[2] + bInc*substep; \ + float a = v0->color[3] + aInc*substep; \ \ const int fbWidth = RLSW.framebuffer.width; \ void *cBuffer = RLSW.framebuffer.color; \ void *dBuffer = RLSW.framebuffer.depth; \ \ - int j = 0; \ - if (yLonger) \ + int numPixels = (int)(steps - substep) + 1; \ + \ + for (int i = 0; i < numPixels; i++) \ { \ - for (int i = 0; i != longLen; i += sgnInc) \ + /* REVIEW: May require reviewing projection details */ \ + int px = (int)(x - 0.5f); \ + int py = (int)(y - 0.5f); \ + \ + int offset = py*fbWidth + px; \ + void *dptr = GET_DEPTH_PTR(dBuffer, offset); \ + \ + if (ENABLE_DEPTH_TEST) \ { \ - int offset = (y1 + i)*fbWidth + (x1 + (j >> 16)); \ - void *dptr = GET_DEPTH_PTR(dBuffer, offset); \ - void *cptr = NULL; \ - \ - if (ENABLE_DEPTH_TEST) \ - { \ - float depth = sw_framebuffer_read_depth(dptr); \ - if (z > depth) goto discardA; \ - } \ - \ - sw_framebuffer_write_depth(dptr, z); \ - \ - cptr = GET_COLOR_PTR(cBuffer, offset); \ - \ - if (ENABLE_COLOR_BLEND) \ - { \ - float dstColor[4]; \ - sw_framebuffer_read_color(dstColor, cptr); \ - sw_blend_colors(dstColor, color); \ - sw_framebuffer_write_color(cptr, dstColor); \ - } \ - else sw_framebuffer_write_color(cptr, color); \ - \ - discardA: \ - j += decInc; \ - z += zStep; \ - color[0] += rStep; \ - color[1] += gStep; \ - color[2] += bStep; \ - color[3] += aStep; \ + float depth = sw_framebuffer_read_depth(dptr); \ + if (z > depth) goto discard; \ } \ - } \ - else \ - { \ - for (int i = 0; i != longLen; i += sgnInc) \ + \ + sw_framebuffer_write_depth(dptr, z); \ + \ + void *cptr = GET_COLOR_PTR(cBuffer, offset); \ + float color[4] = {r, g, b, a}; \ + \ + if (ENABLE_COLOR_BLEND) \ { \ - int offset = (y1 + (j >> 16))*fbWidth + (x1 + i); \ - void *dptr = GET_DEPTH_PTR(dBuffer, offset); \ - void *cptr = NULL; \ - \ - if (ENABLE_DEPTH_TEST) \ - { \ - float depth = sw_framebuffer_read_depth(dptr); \ - if (z > depth) goto discardB; \ - } \ - \ - sw_framebuffer_write_depth(dptr, z); \ - \ - cptr = GET_COLOR_PTR(cBuffer, offset); \ - \ - if (ENABLE_COLOR_BLEND) \ - { \ - float dstColor[4]; \ - sw_framebuffer_read_color(dstColor, cptr); \ - sw_blend_colors(dstColor, color); \ - sw_framebuffer_write_color(cptr, dstColor); \ - } \ - else sw_framebuffer_write_color(cptr, color); \ - \ - discardB: \ - j += decInc; \ - z += zStep; \ - color[0] += rStep; \ - color[1] += gStep; \ - color[2] += bStep; \ - color[3] += aStep; \ + float dstColor[4]; \ + sw_framebuffer_read_color(dstColor, cptr); \ + sw_blend_colors(dstColor, color); \ + sw_framebuffer_write_color(cptr, dstColor); \ } \ + else sw_framebuffer_write_color(cptr, color); \ + \ + discard: \ + x += xInc; y += yInc; z += zInc; \ + r += rInc; g += gInc; b += bInc; a += aInc; \ } \ } @@ -3857,11 +3859,11 @@ void swViewport(int x, int y, int width, int height) RLSW.vpSize[0] = width; RLSW.vpSize[1] = height; - RLSW.vpHalfSize[0] = (int)(width/2.0f + 0.5f); - RLSW.vpHalfSize[1] = (int)(height/2.0f + 0.5f); + RLSW.vpHalf[0] = width/2.0f; + RLSW.vpHalf[1] = height/2.0f; - RLSW.vpCenter[0] = x + RLSW.vpHalfSize[0]; - RLSW.vpCenter[1] = y + RLSW.vpHalfSize[1]; + RLSW.vpCenter[0] = (float)x + RLSW.vpHalf[0]; + RLSW.vpCenter[1] = (float)y + RLSW.vpHalf[1]; RLSW.vpMin[0] = sw_clampi(x, 0, RLSW.framebuffer.width - 1); RLSW.vpMin[1] = sw_clampi(y, 0, RLSW.framebuffer.height - 1); From 1c20b5588d349c08a0e0df114477e5f4090f6966 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 25 Oct 2025 23:20:49 +0200 Subject: [PATCH 013/189] Updatee project id --- .../shapes_math_angle_rotation.vcxproj | 2 +- projects/VS2022/raylib.sln | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/projects/VS2022/examples/shapes_math_angle_rotation.vcxproj b/projects/VS2022/examples/shapes_math_angle_rotation.vcxproj index 0bee76192..48da9d846 100644 --- a/projects/VS2022/examples/shapes_math_angle_rotation.vcxproj +++ b/projects/VS2022/examples/shapes_math_angle_rotation.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {84DE22BB-C25F-425C-A7FE-0120CF107B83} Win32Proj shapes_math_angle_rotation 10.0 diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 8d2704abf..81f700bec 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -395,7 +395,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_text_file_loading", "e 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", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_math_angle_rotation", "examples\shapes_math_angle_rotation.vcxproj", "{84DE22BB-C25F-425C-A7FE-0120CF107B83}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -4899,6 +4899,30 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5098,6 +5122,7 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From a818508158119f74e99b4dc98345c28ce112733c Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Sun, 26 Oct 2025 00:58:56 +0200 Subject: [PATCH 014/189] [rlsw] Completeness of `glDraw` functions (#5304) * adding `glDrawElements` * tweaks * fix `glDrawArrays` and `glDrawElements` behavior --- src/external/rlsw.h | 303 +++++++++++++++++++++++++++++++++----------- 1 file changed, 229 insertions(+), 74 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 50a60d74f..e049e707e 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -376,6 +376,7 @@ typedef double GLclampd; #define glTexCoordPointer(sz, t, s, p) swBindArray(SW_TEXTURE_COORD_ARRAY, (p)) #define glColorPointer(sz, t, s, p) swBindArray(SW_COLOR_ARRAY, (p)) #define glDrawArrays(m, o, c) swDrawArrays((m), (o), (c)) +#define glDrawElements(m,c,t,i) swDrawElements((m),(c),(t),(i)) #define glGenTextures(c, v) swGenTextures((c), (v)) #define glDeleteTextures(c, v) swDeleteTextures((c), (v)) #define glTexImage2D(tr, l, if, w, h, b, f, t, p) swTexImage2D((w), (h), (f), (t), (p)) @@ -393,7 +394,6 @@ typedef double GLclampd; #define glDepthFunc(X) ((void)(X)) #define glTexSubImage2D(X,Y,Z,W,A,B,C,D,E) ((void)(X),(void)(Y),(void)(Z),(void)(W),(void)(A),(void)(B),(void)(C),(void)(D),(void)(E)) #define glGetTexImage(X,Y,Z,W,A) ((void)(X),(void)(Y),(void)(Z),(void)(W),(void)(A)) -#define glDrawElements(X,Y,Z,W) ((void)(X),(void)(Y),(void)(Z),(void)(W)) #define glNormal3f(X,Y,Z) ((void)(X),(void)(Y),(void)(Z)) #define glNormal3fv(X) ((void)(X)) #define glNormalPointer(X,Y,Z) ((void)(X),(void)(Y),(void)(Z)) @@ -589,6 +589,7 @@ SWAPI void swTexCoord2fv(const float *v); SWAPI void swBindArray(SWarray type, void *buffer); SWAPI void swDrawArrays(SWdraw mode, int offset, int count); +SWAPI void swDrawElements(SWdraw mode, int count, int type, const void *indices); SWAPI void swGenTextures(int count, uint32_t *textures); SWAPI void swDeleteTextures(int count, uint32_t *textures); @@ -674,6 +675,7 @@ SWAPI void swBindTexture(uint32_t id); // Defines and Macros //---------------------------------------------------------------------------------- #define SW_PI 3.14159265358979323846f +#define SW_INV_255 0.00392156862745098f #define SW_DEG2RAD (SW_PI/180.0f) #define SW_RAD2DEG (180.0f/SW_PI) @@ -1120,26 +1122,26 @@ static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16)); float32x4_t floats = vcvtq_f32_u32(ints); - floats = vmulq_n_f32(floats, 1.0f/255.0f); + floats = vmulq_n_f32(floats, SW_INV_255); vst1q_f32(dst, floats); #elif defined(SW_HAS_SSE41) __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); __m128i ints = _mm_cvtepu8_epi32(bytes); __m128 floats = _mm_cvtepi32_ps(ints); - floats = _mm_mul_ps(floats, _mm_set1_ps(1.0f/255.0f)); + floats = _mm_mul_ps(floats, _mm_set1_ps(SW_INV_255)); _mm_storeu_ps(dst, floats); #elif defined(SW_HAS_SSE2) __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); bytes = _mm_unpacklo_epi8(bytes, _mm_setzero_si128()); __m128i ints = _mm_unpacklo_epi16(bytes, _mm_setzero_si128()); __m128 floats = _mm_cvtepi32_ps(ints); - floats = _mm_mul_ps(floats, _mm_set1_ps(1.0f/255.0f)); + floats = _mm_mul_ps(floats, _mm_set1_ps(SW_INV_255)); _mm_storeu_ps(dst, floats); #else - dst[0] = (float)src[0]/255.0f; - dst[1] = (float)src[1]/255.0f; - dst[2] = (float)src[2]/255.0f; - dst[3] = (float)src[3]/255.0f; + dst[0] = (float)src[0]*SW_INV_255; + dst[1] = (float)src[1]*SW_INV_255; + dst[2] = (float)src[2]*SW_INV_255; + dst[3] = (float)src[3]*SW_INV_255; #endif } @@ -1894,7 +1896,7 @@ static inline void sw_get_pixel(uint8_t *color, const void *pixels, uint32_t off case SW_PIXELFORMAT_UNCOMPRESSED_R16: { uint16_t val = ((const uint16_t*)pixels)[offset]; - uint8_t gray = sw_half_to_float(val)/255.0f; + uint8_t gray = sw_half_to_float(val)*SW_INV_255; color[0] = gray; color[1] = gray; color[2] = gray; @@ -1904,19 +1906,19 @@ static inline void sw_get_pixel(uint8_t *color, const void *pixels, uint32_t off case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: { const uint16_t *src = &((const uint16_t*)pixels)[offset*3]; - color[0] = sw_half_to_float(src[0])/255.0f; - color[1] = sw_half_to_float(src[1])/255.0f; - color[2] = sw_half_to_float(src[2])/255.0f; + color[0] = sw_half_to_float(src[0])*SW_INV_255; + color[1] = sw_half_to_float(src[1])*SW_INV_255; + color[2] = sw_half_to_float(src[2])*SW_INV_255; color[3] = 255; break; } case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: { const uint16_t *src = &((const uint16_t*)pixels)[offset*4]; - color[0] = sw_half_to_float(src[0])/255.0f; - color[1] = sw_half_to_float(src[1])/255.0f; - color[2] = sw_half_to_float(src[2])/255.0f; - color[3] = sw_half_to_float(src[3])/255.0f; + color[0] = sw_half_to_float(src[0])*SW_INV_255; + color[1] = sw_half_to_float(src[1])*SW_INV_255; + color[2] = sw_half_to_float(src[2])*SW_INV_255; + color[3] = sw_half_to_float(src[3])*SW_INV_255; break; } case SW_PIXELFORMAT_UNKNOWN: @@ -3404,7 +3406,7 @@ static inline void sw_point_render(sw_vertex_t *v) } //------------------------------------------------------------------------------------------- -// Polygon modes mendering logic +// Polygon modes rendering logic //------------------------------------------------------------------------------------------- static inline void sw_poly_point_render(void) { @@ -3436,9 +3438,47 @@ static inline void sw_poly_fill_render(void) case SW_QUADS: sw_quad_render(); break; } } +//------------------------------------------------------------------------------------------- + +// Immediate rendering logic +//------------------------------------------------------------------------------------------- +void sw_immediate_push_vertex(const float position[4], const float color[4], const float texcoord[2]) +{ + // Copy the attributes in the current vertex + sw_vertex_t *vertex = &RLSW.vertexBuffer[RLSW.vertexCounter++]; + for (int i = 0; i < 4; i++) + { + vertex->position[i] = position[i]; + if (i < 2) vertex->texcoord[i] = texcoord[i]; + vertex->color[i] = color[i]; + } + + // Calculate homogeneous coordinates + const float *m = RLSW.matMVP, *v = vertex->position; + vertex->homogeneous[0] = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3]; + vertex->homogeneous[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3]; + vertex->homogeneous[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3]; + vertex->homogeneous[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3]; + + // Immediate rendering of the primitive if the required number is reached + if (RLSW.vertexCounter == RLSW.reqVertices) + { + switch (RLSW.polyMode) + { + case SW_FILL: sw_poly_fill_render(); break; + case SW_LINE: sw_poly_line_render(); break; + case SW_POINT: sw_poly_point_render(); break; + default: break; + } + + RLSW.vertexCounter = 0; + } +} + +//------------------------------------------------------------------------------------------- // Validity check helper functions - +//------------------------------------------------------------------------------------------- static inline bool sw_is_texture_valid(uint32_t id) { bool valid = true; @@ -4301,89 +4341,62 @@ void swEnd(void) void swVertex2i(int x, int y) { const float v[4] = { (float)x, (float)y, 0.0f, 1.0f }; - swVertex4fv(v); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex2f(float x, float y) { const float v[4] = { x, y, 0.0f, 1.0f }; - swVertex4fv(v); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex2fv(const float *v) { const float v4[4] = { v[0], v[1], 0.0f, 1.0f }; - swVertex4fv(v4); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex3i(int x, int y, int z) { const float v[4] = { (float)x, (float)y, (float)z, 1.0f }; - swVertex4fv(v); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex3f(float x, float y, float z) { const float v[4] = { x, y, z, 1.0f }; - swVertex4fv(v); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex3fv(const float *v) { const float v4[4] = { v[0], v[1], v[2], 1.0f }; - swVertex4fv(v4); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex4i(int x, int y, int z, int w) { const float v[4] = { (float)x, (float)y, (float)z, (float)w }; - swVertex4fv(v); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex4f(float x, float y, float z, float w) { const float v[4] = { x, y, z, w }; - swVertex4fv(v); + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swVertex4fv(const float *v) { - // Copy the position in the current vertex - sw_vertex_t *vertex = &RLSW.vertexBuffer[RLSW.vertexCounter++]; - for (int i = 0; i < 4; i++) vertex->position[i] = v[i]; - - // Copy additonal vertex data - for (int i = 0; i < 2; i++) vertex->texcoord[i] = RLSW.current.texcoord[i]; - for (int i = 0; i < 4; i++) vertex->color[i] = RLSW.current.color[i]; - - // Calculation of homogeneous coordinates - const float *m = RLSW.matMVP; - vertex->homogeneous[0] = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3]; - vertex->homogeneous[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3]; - vertex->homogeneous[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3]; - vertex->homogeneous[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3]; - - // Immediate rendering of the primitive if the required number is reached - if (RLSW.vertexCounter == RLSW.reqVertices) - { - switch (RLSW.polyMode) - { - case SW_FILL: sw_poly_fill_render(); break; - case SW_LINE: sw_poly_line_render(); break; - case SW_POINT: sw_poly_point_render(); break; - default: break; - } - - RLSW.vertexCounter = 0; - } + sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); } void swColor3ub(uint8_t r, uint8_t g, uint8_t b) { float cv[4]; - cv[0] = (float)r/255; - cv[1] = (float)g/255; - cv[2] = (float)b/255; + cv[0] = (float)r*SW_INV_255; + cv[1] = (float)g*SW_INV_255; + cv[2] = (float)b*SW_INV_255; cv[3] = 1.0f; swColor4fv(cv); @@ -4392,9 +4405,9 @@ void swColor3ub(uint8_t r, uint8_t g, uint8_t b) void swColor3ubv(const uint8_t *v) { float cv[4]; - cv[0] = (float)v[0]/255; - cv[1] = (float)v[1]/255; - cv[2] = (float)v[2]/255; + cv[0] = (float)v[0]*SW_INV_255; + cv[1] = (float)v[1]*SW_INV_255; + cv[2] = (float)v[2]*SW_INV_255; cv[3] = 1.0f; swColor4fv(cv); @@ -4425,10 +4438,10 @@ void swColor3fv(const float *v) void swColor4ub(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { float cv[4]; - cv[0] = (float)r/255; - cv[1] = (float)g/255; - cv[2] = (float)b/255; - cv[3] = (float)a/255; + cv[0] = (float)r*SW_INV_255; + cv[1] = (float)g*SW_INV_255; + cv[2] = (float)b*SW_INV_255; + cv[3] = (float)a*SW_INV_255; swColor4fv(cv); } @@ -4436,10 +4449,10 @@ void swColor4ub(uint8_t r, uint8_t g, uint8_t b, uint8_t a) void swColor4ubv(const uint8_t *v) { float cv[4]; - cv[0] = (float)v[0]/255; - cv[1] = (float)v[1]/255; - cv[2] = (float)v[2]/255; - cv[3] = (float)v[3]/255; + cv[0] = (float)v[0]*SW_INV_255; + cv[1] = (float)v[1]*SW_INV_255; + cv[2] = (float)v[2]*SW_INV_255; + cv[3] = (float)v[3]*SW_INV_255; swColor4fv(cv); } @@ -4497,14 +4510,156 @@ void swDrawArrays(SWdraw mode, int offset, int count) swBegin(mode); { - swTexCoord2f(0.0f, 0.0f); - swColor4f(1.0f, 1.0f, 1.0f, 1.0f); + const float *texMatrix = RLSW.stackTexture[RLSW.stackTextureCounter - 1]; + const float *defaultTexcoord = RLSW.current.texcoord; + const float *defaultColor = RLSW.current.color; + + const float *positions = RLSW.array.positions; + const float *texcoords = RLSW.array.texcoords; + const uint8_t *colors = RLSW.array.colors; - for (int i = offset; i < count; i++) + int end = offset + count; + + for (int i = offset; i < end; i++) { - if (RLSW.array.texcoords) swTexCoord2fv(RLSW.array.texcoords + 2*i); - if (RLSW.array.colors) swColor4ubv(RLSW.array.colors + 4*i); - swVertex3fv(RLSW.array.positions + 3*i); + float u, v; + if (texcoords) + { + int idx = 2 * i; + u = texcoords[idx]; + v = texcoords[idx + 1]; + } + else + { + u = defaultTexcoord[0]; + v = defaultTexcoord[1]; + } + + float texcoord[2]; + texcoord[0] = texMatrix[0] * u + texMatrix[4] * v + texMatrix[12]; + texcoord[1] = texMatrix[1] * u + texMatrix[5] * v + texMatrix[13]; + + float color[4] = { + defaultColor[0], + defaultColor[1], + defaultColor[2], + defaultColor[3] + }; + + if (colors) + { + int idx = 4 * i; + color[0] *= (float)colors[idx]*SW_INV_255; + color[1] *= (float)colors[idx + 1]*SW_INV_255; + color[2] *= (float)colors[idx + 2]*SW_INV_255; + color[3] *= (float)colors[idx + 3]*SW_INV_255; + } + + int idx = 3 * i; + float position[4] = { + positions[idx], + positions[idx + 1], + positions[idx + 2], + 1.0f + }; + + sw_immediate_push_vertex(position, color, texcoord); + } + } + swEnd(); +} + +void swDrawElements(SWdraw mode, int count, int type, const void *indices) +{ + if (RLSW.array.positions == 0) + { + RLSW.errCode = SW_INVALID_OPERATION; + return; + } + + if (count < 0) + { + RLSW.errCode = SW_INVALID_VALUE; + return; + } + + const uint8_t *indicesUb = NULL; + const uint16_t *indicesUs = NULL; + const uint32_t *indicesUi = NULL; + + switch (type) + { + case SW_UNSIGNED_BYTE: + indicesUb = (const uint8_t *)indices; + break; + case SW_UNSIGNED_SHORT: + indicesUs = (const uint16_t *)indices; + break; + case SW_UNSIGNED_INT: + indicesUi = (const uint32_t *)indices; + break; + default: + RLSW.errCode = SW_INVALID_ENUM; + return; + } + + swBegin(mode); + { + const float *texMatrix = RLSW.stackTexture[RLSW.stackTextureCounter - 1]; + const float *defaultTexcoord = RLSW.current.texcoord; + const float *defaultColor = RLSW.current.color; + + const float *positions = RLSW.array.positions; + const float *texcoords = RLSW.array.texcoords; + const uint8_t *colors = RLSW.array.colors; + + for (int i = 0; i < count; i++) + { + int index = indicesUb ? indicesUb[i] : + (indicesUs ? indicesUs[i] : indicesUi[i]); + + float u, v; + if (texcoords) + { + int idx = 2 * index; + u = texcoords[idx]; + v = texcoords[idx + 1]; + } + else + { + u = defaultTexcoord[0]; + v = defaultTexcoord[1]; + } + + float texcoord[2]; + texcoord[0] = texMatrix[0] * u + texMatrix[4] * v + texMatrix[12]; + texcoord[1] = texMatrix[1] * u + texMatrix[5] * v + texMatrix[13]; + + float color[4] = { + defaultColor[0], + defaultColor[1], + defaultColor[2], + defaultColor[3] + }; + + if (colors) + { + int idx = 4 * index; + color[0] *= (float)colors[idx]*SW_INV_255; + color[1] *= (float)colors[idx + 1]*SW_INV_255; + color[2] *= (float)colors[idx + 2]*SW_INV_255; + color[3] *= (float)colors[idx + 3]*SW_INV_255; + } + + int idx = 3 * index; + float position[4] = { + positions[idx], + positions[idx + 1], + positions[idx + 2], + 1.0f + }; + + sw_immediate_push_vertex(position, color, texcoord); } } swEnd(); From e244cf297abd7c3cac887cbb38ad194d4c20a53d Mon Sep 17 00:00:00 2001 From: themushroompirates <59015901+themushroompirates@users.noreply.github.com> Date: Sun, 26 Oct 2025 18:15:45 +0100 Subject: [PATCH 015/189] examples_model_decals : Fixed unload crash, added buttons (#5306) --- examples/models/models_decals.c | 497 +++++++++++++++++------------- examples/models/models_decals.png | Bin 62387 -> 67453 bytes 2 files changed, 283 insertions(+), 214 deletions(-) diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index af1ecfc6d..2786168f6 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -43,8 +43,10 @@ typedef struct MeshBuilder { static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]); static void FreeMeshBuilder(MeshBuilder *mb); static Mesh BuildMesh(MeshBuilder *mb); -static Mesh GenMeshDecal(Mesh inputMesh, Ray ray); +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) +static bool Button(Rectangle rec, char *label); //------------------------------------------------------------------------------------ // Program main entry point @@ -105,10 +107,6 @@ int main(void) decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture; decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE; - // We're going to use these to build up our decal meshes - // They'll resize automatically as we go, we'll free them at the end - MeshBuilder meshBuilders[2] = { 0 }; - bool showModel = true; Model decalModels[MAX_DECALS] = { 0 }; int decalCount = 0; @@ -123,8 +121,6 @@ int main(void) //---------------------------------------------------------------------------------- if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON); - if (IsKeyPressed(KEY_SPACE)) showModel = !showModel; - // Display information about closest hit RayCollision collision = { 0 }; collision.distance = FLT_MAX; @@ -165,206 +161,12 @@ int main(void) // Spin the placement around a bit splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180)))); - Matrix splatInv = MatrixInvert(splat); - // Reset the mesh builders - meshBuilders[0].vertexCount = 0; - meshBuilders[1].vertexCount = 0; - - // We'll be flip-flopping between the two mesh builders - // Reading from one and writing to the other, then swapping - int mbIndex = 0; - - // First pass, just get any triangle inside the bounding box (for each mesh of the model) - for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++) - { - Mesh mesh = model.meshes[meshIndex]; - for (int tri = 0; tri < mesh.triangleCount; tri++) - { - Vector3 vertices[3] = { 0 }; - - // The way we calculate the vertices of the mesh triangle - // depend on whether the mesh vertices are indexed or not - if (mesh.indices == 0) - { - for (int v = 0; v < 3; v++) - { - vertices[v] = (Vector3){ - mesh.vertices[3*3*tri + 3*v + 0], - mesh.vertices[3*3*tri + 3*v + 1], - mesh.vertices[3*3*tri + 3*v + 2] - }; - } - } - else - { - for (int v = 0; v < 3; v++) - { - vertices[v] = (Vector3){ - mesh.vertices[ 3*mesh.indices[3*tri+0] + v], - mesh.vertices[ 3*mesh.indices[3*tri+1] + v], - mesh.vertices[ 3*mesh.indices[3*tri+2] + v] - }; - } - } - - // Transform all 3 vertices of the triangle - // and check if they are inside our decal box - int insideCount = 0; - for (int i = 0; i < 3; i++) - { - // To splat space - Vector3 v = Vector3Transform(vertices[i], splat); - - if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++; - - // We need to keep the transformed vertex - vertices[i] = v; - } - - // If any of them are inside, we add the triangle - we'll clip it later - if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices); - } - } - - // Clipping time! We need to clip against all 6 directions - Vector3 planes[6] = { - { 1, 0, 0 }, - { -1, 0, 0 }, - { 0, 1, 0 }, - { 0, -1, 0 }, - { 0, 0, 1 }, - { 0, 0, -1 } - }; - - for (int face = 0; face < 6; face++) - { - // Swap current model builder (so we read from the one we just wrote to) - mbIndex = 1 - mbIndex; - - MeshBuilder *inMesh = &meshBuilders[1 - mbIndex]; - MeshBuilder *outMesh = &meshBuilders[mbIndex]; - - // Reset write builder - outMesh->vertexCount = 0; - - float s = 0.5f*decalSize; - - for (int i = 0; i < inMesh->vertexCount; i += 3) - { - Vector3 nV1, nV2, nV3, nV4; - - float d1 = Vector3DotProduct(inMesh->vertices[ i + 0 ], planes[face] ) - s; - float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s; - float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s; - - int v1Out = (d1 > 0); - int v2Out = (d2 > 0); - int v3Out = (d3 > 0); - - // Calculate, how many vertices of the face lie outside of the clipping plane - int total = v1Out + v2Out + v3Out; - - switch (total) - { - case 0: - { - // The entire face lies inside of the plane, no clipping needed - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]}); - } break; - case 1: - { - // One vertex lies outside of the plane, perform clipping - if (v1Out) - { - nV1 = inMesh->vertices[i + 1]; - nV2 = inMesh->vertices[i + 2]; - nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s); - nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s); - } - - if (v2Out) - { - nV1 = inMesh->vertices[i]; - nV2 = inMesh->vertices[i + 2]; - nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s); - nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s); - - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1}); - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4}); - break; - } - - if (v3Out) - { - nV1 = inMesh->vertices[i]; - nV2 = inMesh->vertices[i + 1]; - nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s); - nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s); - } - - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2}); - } break; - case 2: - { - // Two vertices lies outside of the plane, perform clipping - if (!v1Out) - { - nV1 = inMesh->vertices[i]; - nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s); - nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); - } - - if (!v2Out) - { - nV1 = inMesh->vertices[i + 1]; - nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); - nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); - } - - if (!v3Out) - { - nV1 = inMesh->vertices[i + 2]; - nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); - nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s); - AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); - } - } break; - case 3: // The entire face lies outside of the plane, so let's discard the corresponding vertices - default: break; - } - } - } - - // Now we just need to re-transform the vertices - MeshBuilder *theMesh = &meshBuilders[mbIndex]; - - // Allocate room for UVs - if (theMesh->vertexCount > 0) - { - theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount); - - for (int i = 0; i < theMesh->vertexCount; i++) - { - // Calculate the UVs based on the projected coords - // They are clipped to (-decalSize .. decalSize) and we want them (0..1) - theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f); - theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f); - - // From splat space to world space - theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], splatInv); - - // Tiny nudge in the normal direction so it renders properly over the mesh - theMesh->vertices[i] = Vector3Add(theMesh->vertices[i], Vector3Scale(collision.normal, decalOffset)); - } - - // Decal model data ready, create it and add it + Mesh decalMesh = GenMeshDecal(model, splat, decalSize, decalOffset); + if (decalMesh.vertexCount > 0) { int decalIndex = decalCount++; - decalModels[decalIndex] = LoadModelFromMesh(BuildMesh(theMesh)); - decalModels[decalIndex].materials[0] = decalMaterial; + decalModels[decalIndex] = LoadModelFromMesh(decalMesh); + decalModels[decalIndex].materials[0].maps[0] = decalMaterial.maps[0]; } } //---------------------------------------------------------------------------------- @@ -381,7 +183,7 @@ int main(void) // Draw the decal models 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 we hit the mesh, draw the box for the decal if (collision.hit) { Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); @@ -418,13 +220,20 @@ int main(void) for (int i = 0; i < decalCount; i++) { - 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); + if (i == 20) { + DrawText("...", x0, 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); + yPos += 15; + } vertexCount += decalModels[i].meshes[0].vertexCount; triangleCount += decalModels[i].meshes[0].triangleCount; - yPos += 15; } DrawText("TOTAL", x0, yPos, 10, LIME); @@ -434,6 +243,23 @@ int main(void) 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); + + Rectangle rect = (Rectangle){ 10, screenHeight - 100, 100, 60 }; + + if (Button(rect, showModel ? "Hide Model" : "Show Model")) { + showModel = !showModel; + } + + rect.x += rect.width + 10; + + if (Button(rect, "Clear Decals")) { + for (int i = 0; i < decalCount; i++) + { + UnloadModel(decalModels[i]); + } + decalCount = 0; + } + DrawFPS(10, 10); @@ -446,13 +272,14 @@ int main(void) UnloadModel(model); UnloadTexture(modelTexture); - // TODO: WARNING: This line crashes program on closing - //for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); + for (int i = 0; i < decalCount; i++) { + UnloadModel(decalModels[i]); + } UnloadTexture(decalTexture); - FreeMeshBuilder(&meshBuilders[0]); - FreeMeshBuilder(&meshBuilders[1]); + // Free the data for decal generation + FreeDecalMeshData(); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- @@ -536,3 +363,245 @@ static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s) return position; } + +static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset) +{ + // We're going to use these to build up our decal meshes + // They'll resize automatically as we go, we'll free them at the end + static MeshBuilder meshBuilders[2] = { 0 }; + + // Ugly way of telling us to free the static MeshBuilder data + if (inputModel.meshCount == -1) { + FreeMeshBuilder(&meshBuilders[0]); + FreeMeshBuilder(&meshBuilders[1]); + return (Mesh){0}; + } + + // We're going to need the inverse matrix + Matrix invProj = MatrixInvert(projection); + + // Reset the mesh builders + meshBuilders[0].vertexCount = 0; + meshBuilders[1].vertexCount = 0; + + // We'll be flip-flopping between the two mesh builders + // Reading from one and writing to the other, then swapping + int mbIndex = 0; + + // First pass, just get any triangle inside the bounding box (for each mesh of the model) + for (int meshIndex = 0; meshIndex < inputModel.meshCount; meshIndex++) + { + Mesh mesh = inputModel.meshes[meshIndex]; + for (int tri = 0; tri < mesh.triangleCount; tri++) + { + Vector3 vertices[3] = { 0 }; + + // The way we calculate the vertices of the mesh triangle + // depend on whether the mesh vertices are indexed or not + if (mesh.indices == 0) + { + for (int v = 0; v < 3; v++) + { + vertices[v] = (Vector3){ + mesh.vertices[3*3*tri + 3*v + 0], + mesh.vertices[3*3*tri + 3*v + 1], + mesh.vertices[3*3*tri + 3*v + 2] + }; + } + } + else + { + for (int v = 0; v < 3; v++) + { + vertices[v] = (Vector3){ + mesh.vertices[ 3*mesh.indices[3*tri+0] + v], + mesh.vertices[ 3*mesh.indices[3*tri+1] + v], + mesh.vertices[ 3*mesh.indices[3*tri+2] + v] + }; + } + } + + // Transform all 3 vertices of the triangle + // and check if they are inside our decal box + int insideCount = 0; + for (int i = 0; i < 3; i++) + { + // To projection space + Vector3 v = Vector3Transform(vertices[i], projection); + + if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++; + + // We need to keep the transformed vertex + vertices[i] = v; + } + + // If any of them are inside, we add the triangle - we'll clip it later + if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices); + } + } + + // Clipping time! We need to clip against all 6 directions + Vector3 planes[6] = { + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 1, 0 }, + { 0, -1, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 } + }; + + for (int face = 0; face < 6; face++) + { + // Swap current model builder (so we read from the one we just wrote to) + mbIndex = 1 - mbIndex; + + MeshBuilder *inMesh = &meshBuilders[1 - mbIndex]; + MeshBuilder *outMesh = &meshBuilders[mbIndex]; + + // Reset write builder + outMesh->vertexCount = 0; + + float s = 0.5f*decalSize; + + for (int i = 0; i < inMesh->vertexCount; i += 3) + { + Vector3 nV1, nV2, nV3, nV4; + + float d1 = Vector3DotProduct(inMesh->vertices[ i + 0 ], planes[face] ) - s; + float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s; + float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s; + + int v1Out = (d1 > 0); + int v2Out = (d2 > 0); + int v3Out = (d3 > 0); + + // Calculate, how many vertices of the face lie outside of the clipping plane + int total = v1Out + v2Out + v3Out; + + switch (total) + { + case 0: + { + // The entire face lies inside of the plane, no clipping needed + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]}); + } break; + case 1: + { + // One vertex lies outside of the plane, perform clipping + if (v1Out) + { + nV1 = inMesh->vertices[i + 1]; + nV2 = inMesh->vertices[i + 2]; + nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s); + nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s); + } + + if (v2Out) + { + nV1 = inMesh->vertices[i]; + nV2 = inMesh->vertices[i + 2]; + nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s); + nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s); + + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1}); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4}); + break; + } + + if (v3Out) + { + nV1 = inMesh->vertices[i]; + nV2 = inMesh->vertices[i + 1]; + nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s); + nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s); + } + + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2}); + } break; + case 2: + { + // Two vertices lies outside of the plane, perform clipping + if (!v1Out) + { + nV1 = inMesh->vertices[i]; + nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s); + nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + } + + if (!v2Out) + { + nV1 = inMesh->vertices[i + 1]; + nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); + nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + } + + if (!v3Out) + { + nV1 = inMesh->vertices[i + 2]; + nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); + nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s); + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); + } + } break; + case 3: // The entire face lies outside of the plane, so let's discard the corresponding vertices + default: break; + } + } + } + + // Now we just need to re-transform the vertices + MeshBuilder *theMesh = &meshBuilders[mbIndex]; + + // Allocate room for UVs + if (theMesh->vertexCount > 0) + { + theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount); + + for (int i = 0; i < theMesh->vertexCount; i++) + { + // Calculate the UVs based on the projected coords + // They are clipped to (-decalSize .. decalSize) and we want them (0..1) + theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f); + theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f); + + // Tiny nudge in the normal direction so it renders properly over the mesh + theMesh->vertices[i].z -= decalOffset; + + // From projection space to world space + theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], invProj); + } + + // Decal model data ready, create the mesh and return it + return BuildMesh(theMesh); + } + else + { + // Return a blank mesh as there's nothing to add + return (Mesh){ 0 }; + } +} + +static bool Button(Rectangle rec, char *label) +{ + Color bgColor = GRAY; + bool pressed = false; + if (CheckCollisionPointRec(GetMousePosition(), rec)) { + bgColor = LIGHTGRAY; + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + pressed = true; + } + } + + DrawRectangleRec(rec, bgColor); + DrawRectangleLinesEx(rec, 2.0f, DARKGRAY); + + float fontSize = 10.0f; + float 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); + + return pressed; +} \ No newline at end of file diff --git a/examples/models/models_decals.png b/examples/models/models_decals.png index 48e027fe2d1711237f457995d46ddcc0647a102e..6bdbaf17ca034c1e481e5afa69c9f954693dd79e 100644 GIT binary patch literal 67453 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 V(=>jESquye44$rjF6*2UngD6y9?k#& literal 62387 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 z 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

AIX)i);+Q2;^({W#g{?F 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 Date: Sun, 26 Oct 2025 18:21:24 +0100 Subject: [PATCH 016/189] Review formating #5306 --- examples/models/models_decals.c | 172 ++++++++++++++++---------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index 2786168f6..6fa2bd75b 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -71,46 +71,46 @@ int main(void) // Load character model Model model = LoadModel("resources/models/obj/character.obj"); - + // Apply character skin Texture2D modelTexture = LoadTexture("resources/models/obj/character_diffuse.png"); SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR); model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture; - + BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]); // Get mesh bounding box - + camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f); camera.position = Vector3Scale(modelBBox.max, 1.0f); camera.position.x *= 0.1f; - + float modelSize = fminf( fminf(fabsf(modelBBox.max.x - modelBBox.min.x), fabsf(modelBBox.max.y - modelBBox.min.y)), fabsf(modelBBox.max.z - modelBBox.min.z)); - + camera.position = (Vector3){ 0.0f, modelBBox.max.y*1.2f, modelSize*3.0f }; - + float decalSize = modelSize*0.25f; float decalOffset = 0.01f; - + Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize)); placementCube.materials[0].maps[0].color = LIME; - + Material decalMaterial = LoadMaterialDefault(); decalMaterial.maps[0].color = YELLOW; - + Image decalImage = LoadImage("resources/raylib_logo.png"); ImageResizeNN(&decalImage, decalImage.width/4, decalImage.height/4); Texture decalTexture = LoadTextureFromImage(decalImage); UnloadImage(decalImage); - + SetTextureFilter(decalTexture, TEXTURE_FILTER_BILINEAR); decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture; decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE; - + bool showModel = true; Model decalModels[MAX_DECALS] = { 0 }; int decalCount = 0; - + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -151,19 +151,21 @@ int main(void) if (meshHitInfo.hit) collision = meshHitInfo; } - + // Add decal to mesh on hit point if (collision.hit && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (decalCount < MAX_DECALS)) { // Create the transformation to project the decal Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){ 0.0f, 1.0f, 0.0f }); - + // Spin the placement around a bit splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180)))); - + Mesh decalMesh = GenMeshDecal(model, splat, decalSize, decalOffset); - if (decalMesh.vertexCount > 0) { + + if (decalMesh.vertexCount > 0) + { int decalIndex = decalCount++; decalModels[decalIndex] = LoadModelFromMesh(decalMesh); decalModels[decalIndex].materials[0].maps[0] = decalMaterial.maps[0]; @@ -179,7 +181,7 @@ int main(void) BeginMode3D(camera); // Draw the model at the origin and default scale 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); @@ -199,43 +201,45 @@ int main(void) float x0 = GetScreenWidth() - 300; float x1 = x0 + 100; float x2 = x1 + 100; - + DrawText("Vertices", x1, yPos, 10, LIME); DrawText("Triangles", x2, yPos, 10, LIME); yPos += 15; - + int vertexCount = 0; int triangleCount = 0; - + for (int i = 0; i < model.meshCount; i++) { vertexCount += model.meshes[i].vertexCount; 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); yPos += 15; - + for (int i = 0; i < decalCount; i++) { - if (i == 20) { + if (i == 20) + { DrawText("...", x0, yPos, 10, LIME); yPos += 15; } - - if (i < 20) { + + 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); yPos += 15; } - + vertexCount += decalModels[i].meshes[0].vertexCount; 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); @@ -243,23 +247,18 @@ int main(void) 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); - + Rectangle rect = (Rectangle){ 10, screenHeight - 100, 100, 60 }; - - if (Button(rect, showModel ? "Hide Model" : "Show Model")) { - showModel = !showModel; - } - + + if (Button(rect, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; + rect.x += rect.width + 10; - - if (Button(rect, "Clear Decals")) { - for (int i = 0; i < decalCount; i++) - { - UnloadModel(decalModels[i]); - } + + if (Button(rect, "Clear Decals")) + { + for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); decalCount = 0; } - DrawFPS(10, 10); @@ -271,15 +270,13 @@ int main(void) //-------------------------------------------------------------------------------------- UnloadModel(model); UnloadTexture(modelTexture); - - for (int i = 0; i < decalCount; i++) { - UnloadModel(decalModels[i]); - } + + // Unload decal models + for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); UnloadTexture(decalTexture); - - // Free the data for decal generation - FreeDecalMeshData(); + + FreeDecalMeshData(); // Free the data for decal generation CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- @@ -298,21 +295,21 @@ static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]) { int newVertexCapacity = (1 + (mb->vertexCapacity/256))*256; Vector3 *newVertices = (Vector3 *)MemAlloc(newVertexCapacity*sizeof(Vector3)); - + if (mb->vertexCapacity > 0) { memcpy(newVertices, mb->vertices, mb->vertexCount*sizeof(Vector3)); MemFree(mb->vertices); } - + mb->vertices = newVertices; mb->vertexCapacity = newVertexCapacity; } - + // Add 3 vertices int index = mb->vertexCount; mb->vertexCount += 3; - + for (int i = 0; i < 3; i++) mb->vertices[index+i] = vertices[i]; } @@ -328,7 +325,7 @@ static void FreeMeshBuilder(MeshBuilder *mb) static Mesh BuildMesh(MeshBuilder *mb) { Mesh outMesh = { 0 }; - + outMesh.vertexCount = mb->vertexCount; outMesh.triangleCount = mb->vertexCount/3; outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float)); @@ -339,16 +336,16 @@ static Mesh BuildMesh(MeshBuilder *mb) outMesh.vertices[3*i+0] = mb->vertices[i].x; outMesh.vertices[3*i+1] = mb->vertices[i].y; outMesh.vertices[3*i+2] = mb->vertices[i].z; - + if (mb->uvs) { outMesh.texcoords[2*i+0] = mb->uvs[i].x; outMesh.texcoords[2*i+1] = mb->uvs[i].y; } } - + UploadMesh(&outMesh, false); - + return outMesh; } @@ -364,22 +361,24 @@ static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s) return position; } +// Generate mesh decals for provided model static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset) { // We're going to use these to build up our decal meshes // They'll resize automatically as we go, we'll free them at the end static MeshBuilder meshBuilders[2] = { 0 }; - + // Ugly way of telling us to free the static MeshBuilder data - if (inputModel.meshCount == -1) { + if (inputModel.meshCount == -1) + { FreeMeshBuilder(&meshBuilders[0]); FreeMeshBuilder(&meshBuilders[1]); - return (Mesh){0}; + return (Mesh){ 0 }; } - + // We're going to need the inverse matrix Matrix invProj = MatrixInvert(projection); - + // Reset the mesh builders meshBuilders[0].vertexCount = 0; meshBuilders[1].vertexCount = 0; @@ -395,7 +394,7 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f for (int tri = 0; tri < mesh.triangleCount; tri++) { Vector3 vertices[3] = { 0 }; - + // The way we calculate the vertices of the mesh triangle // depend on whether the mesh vertices are indexed or not if (mesh.indices == 0) @@ -420,7 +419,7 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f }; } } - + // Transform all 3 vertices of the triangle // and check if they are inside our decal box int insideCount = 0; @@ -428,13 +427,13 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f { // To projection space Vector3 v = Vector3Transform(vertices[i], projection); - + if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++; - + // We need to keep the transformed vertex vertices[i] = v; } - + // If any of them are inside, we add the triangle - we'll clip it later if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices); } @@ -454,15 +453,15 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f { // Swap current model builder (so we read from the one we just wrote to) mbIndex = 1 - mbIndex; - + MeshBuilder *inMesh = &meshBuilders[1 - mbIndex]; MeshBuilder *outMesh = &meshBuilders[mbIndex]; - + // Reset write builder outMesh->vertexCount = 0; - + float s = 0.5f*decalSize; - + for (int i = 0; i < inMesh->vertexCount; i += 3) { Vector3 nV1, nV2, nV3, nV4; @@ -515,7 +514,7 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s); nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s); } - + AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2}); } break; @@ -529,7 +528,7 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); } - + if (!v2Out) { nV1 = inMesh->vertices[i + 1]; @@ -537,7 +536,7 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s); AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3}); } - + if (!v3Out) { nV1 = inMesh->vertices[i + 2]; @@ -559,21 +558,21 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f if (theMesh->vertexCount > 0) { theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount); - + for (int i = 0; i < theMesh->vertexCount; i++) { // Calculate the UVs based on the projected coords // They are clipped to (-decalSize .. decalSize) and we want them (0..1) theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f); theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f); - + // Tiny nudge in the normal direction so it renders properly over the mesh theMesh->vertices[i].z -= decalOffset; - + // From projection space to world space theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], invProj); } - + // Decal model data ready, create the mesh and return it return BuildMesh(theMesh); } @@ -584,24 +583,25 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f } } -static bool Button(Rectangle rec, char *label) +// Button UI element +static bool Button(Rectangle rec, const char *label) { Color bgColor = GRAY; bool pressed = false; - if (CheckCollisionPointRec(GetMousePosition(), rec)) { + + if (CheckCollisionPointRec(GetMousePosition(), rec)) + { bgColor = LIGHTGRAY; - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - pressed = true; - } + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) pressed = true; } - + DrawRectangleRec(rec, bgColor); DrawRectangleLinesEx(rec, 2.0f, DARKGRAY); - + float fontSize = 10.0f; float 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); - + return pressed; -} \ No newline at end of file +} From 0fbc4272d0b6e777a19c212027b4825c90f55f77 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 18:22:23 +0100 Subject: [PATCH 017/189] Remove trailing spaces --- examples/examples_template.c | 2 +- .../shaders/shaders_normalmap_rendering.c | 2 +- examples/shapes/shapes_bullet_hell.c | 2 +- examples/shapes/shapes_starfield_effect.c | 36 +++++++++---------- src/platforms/rcore_desktop_sdl.c | 2 +- src/platforms/rcore_desktop_win32.c | 2 +- src/rcore.c | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/examples_template.c b/examples/examples_template.c index 39a19351d..211749e82 100644 --- a/examples/examples_template.c +++ b/examples/examples_template.c @@ -36,7 +36,7 @@ 10. Have fun! - The following files must be updated when adding a new example, + The following files must be updated when adding a new example, but it can be automatically done using the raylib provided tool: rexm So, no worries if just the .c/.png are provided when adding the example. diff --git a/examples/shaders/shaders_normalmap_rendering.c b/examples/shaders/shaders_normalmap_rendering.c index 4859ec813..07399a78e 100644 --- a/examples/shaders/shaders_normalmap_rendering.c +++ b/examples/shaders/shaders_normalmap_rendering.c @@ -49,7 +49,7 @@ int main(void) camera.projection = CAMERA_PERSPECTIVE; // Load basic normal map lighting shader - Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/normalmap.vs", GLSL_VERSION), + Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/normalmap.vs", GLSL_VERSION), TextFormat("resources/shaders/glsl%i/normalmap.fs", GLSL_VERSION)); // Get some required shader locations diff --git a/examples/shapes/shapes_bullet_hell.c b/examples/shapes/shapes_bullet_hell.c index 235df4d16..95abc4dc9 100644 --- a/examples/shapes/shapes_bullet_hell.c +++ b/examples/shapes/shapes_bullet_hell.c @@ -197,7 +197,7 @@ int main(void) bullets[i].color); } } - } + } else { // Draw bullets using DrawCircle(), less performant diff --git a/examples/shapes/shapes_starfield_effect.c b/examples/shapes/shapes_starfield_effect.c index 8dd90fe0b..ca409c926 100644 --- a/examples/shapes/shapes_starfield_effect.c +++ b/examples/shapes/shapes_starfield_effect.c @@ -32,18 +32,18 @@ int main(void) const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [shapes] example - starfield effect"); - + Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.69f); - + // Speed at which we fly forward float speed = 10.0f/9.0f; - + // We're either drawing lines or circles bool drawLines = true; - + Vector3 stars[STAR_COUNT] = { 0 }; Vector2 starsScreenPos[STAR_COUNT] = { 0 }; - + // Setup the stars with a random position for (int i = 0; i < STAR_COUNT; i++) { @@ -65,22 +65,22 @@ int main(void) if ((int)mouseMove != 0) speed += 2.0f*mouseMove/9.0f; if (speed < 0.0f) speed = 0.1f; else if (speed > 2.0f) speed = 2.0f; - + // Toggle lines / points with space bar if (IsKeyPressed(KEY_SPACE)) drawLines = !drawLines; - + float dt = GetFrameTime(); - for (int i = 0; i < STAR_COUNT; i++) + for (int i = 0; i < STAR_COUNT; i++) { // Update star's timer stars[i].z -= dt*speed; - + // Calculate the screen position starsScreenPos[i] = (Vector2){ screenWidth*0.5f + stars[i].x/stars[i].z, screenHeight*0.5f + stars[i].y/stars[i].z, }; - + // If the star is too old, or offscreen, it dies and we make a new random one if ((stars[i].z < 0.0f) || (starsScreenPos[i].x < 0) || (starsScreenPos[i].y < 0.0f) || (starsScreenPos[i].x > screenWidth) || (starsScreenPos[i].y > screenHeight)) @@ -97,14 +97,14 @@ int main(void) BeginDrawing(); ClearBackground(bgColor); - + for (int i = 0; i < STAR_COUNT; i++) { if (drawLines) { // Get the time a little while ago for this star, but clamp it float t = Clamp(stars[i].z + 1.0f/32.0f, 0.0f, 1.0f); - + // If it's different enough from the current time, we proceed if ((t - stars[i].z) > 1e-3) { @@ -113,26 +113,26 @@ int main(void) screenWidth*0.5f + stars[i].x/t, screenHeight*0.5f + stars[i].y/t, }; - + // Draw a line connecting the old point to the current point DrawLineV(startPos, starsScreenPos[i], RAYWHITE); } } - else + else { // Make the radius grow as the star ages float radius = Lerp(stars[i].z, 1.0f, 5.0f); - + // Draw the circle DrawCircleV(starsScreenPos[i], radius, RAYWHITE); } } - + DrawText(TextFormat("[MOUSE WHEEL] Current Speed: %.0f", 9.0f*speed/2.0f), 10, 40, 20, RAYWHITE); DrawText(TextFormat("[SPACE] Current draw mode: %s", drawLines ? "Lines" : "Circles"), 10, 70, 20, RAYWHITE); - + DrawFPS(10, 10); - + EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index e135cd848..03bad80f9 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1243,7 +1243,7 @@ void EnableCursor(void) SDL_SetRelativeMouseMode(SDL_FALSE); #if defined(USING_VERSION_SDL3) - // NOTE: SDL_ShowCursor() has been split into three functions: + // NOTE: SDL_ShowCursor() has been split into three functions: // SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible() SDL_ShowCursor(); #else diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 5b67c72b0..1dadd5586 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1139,7 +1139,7 @@ void ShowCursor(void) // Hides mouse cursor void HideCursor(void) { - // NOTE: We use SetCursor() instead of ShowCursor() because + // NOTE: We use SetCursor() instead of ShowCursor() because // it makes it easy to only hide the cursor while it's inside the client area SetCursor(NULL); CORE.Input.Mouse.cursorHidden = true; diff --git a/src/rcore.c b/src/rcore.c index e4628e77c..d06e3089b 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -709,7 +709,7 @@ void InitWindow(int width, int height, const char *title) //-------------------------------------------------------------- // Initialize rlgl default data (buffers and shaders) - // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl + // NOTE: Current fbo size stored as globals in rlgl for convenience rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); isGpuReady = true; // Flag to note GPU has been initialized successfully From 70f491169836d5cbdcba943d3d49ed83299ca05f Mon Sep 17 00:00:00 2001 From: JordSant <77529699+JordSant@users.noreply.github.com> Date: Sun, 26 Oct 2025 18:24:19 +0100 Subject: [PATCH 018/189] [examples] Added `shaders_color_correction` (#5307) * [examples] Added `shaders_color_correction` * Add _CRT_SECURE_NO_WARNINGS to VS Project * Added to makefiles --- examples/Makefile | 1 + examples/Makefile.Web | 9 + examples/README.md | 5 +- examples/examples_list.txt | 1 + examples/shaders/raygui.h | 5757 +++++++++++++++++ examples/shaders/resources/LICENSE.md | 5 +- examples/shaders/resources/cat.png | Bin 0 -> 388467 bytes examples/shaders/resources/mandrill.png | Bin 0 -> 197452 bytes examples/shaders/resources/parrots.png | Bin 0 -> 294960 bytes .../shaders/glsl100/color_correction.fs | 34 + .../shaders/glsl120/color_correction.fs | 31 + .../shaders/glsl330/color_correction.fs | 34 + examples/shaders/shaders_color_correction.c | 149 + examples/shaders/shaders_color_correction.png | Bin 0 -> 311867 bytes .../examples/shaders_color_correction.vcxproj | 569 ++ projects/VS2022/raylib.sln | 27 + 16 files changed, 6619 insertions(+), 3 deletions(-) create mode 100644 examples/shaders/raygui.h create mode 100644 examples/shaders/resources/cat.png create mode 100644 examples/shaders/resources/mandrill.png create mode 100644 examples/shaders/resources/parrots.png create mode 100644 examples/shaders/resources/shaders/glsl100/color_correction.fs create mode 100644 examples/shaders/resources/shaders/glsl120/color_correction.fs create mode 100644 examples/shaders/resources/shaders/glsl330/color_correction.fs create mode 100644 examples/shaders/shaders_color_correction.c create mode 100644 examples/shaders/shaders_color_correction.png create mode 100644 projects/VS2022/examples/shaders_color_correction.vcxproj diff --git a/examples/Makefile b/examples/Makefile index 9ae8bb480..c601c72b2 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -655,6 +655,7 @@ SHADERS = \ shaders/shaders_ascii_rendering \ shaders/shaders_basic_lighting \ shaders/shaders_basic_pbr \ + shaders/shaders_color_correction \ shaders/shaders_custom_uniform \ shaders/shaders_deferred_rendering \ shaders/shaders_depth_rendering \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 0e9b9f92f..99be781ac 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -655,6 +655,7 @@ SHADERS = \ shaders/shaders_ascii_rendering \ shaders/shaders_basic_lighting \ shaders/shaders_basic_pbr \ + shaders/shaders_color_correction \ shaders/shaders_custom_uniform \ shaders/shaders_deferred_rendering \ shaders/shaders_depth_rendering \ @@ -1261,6 +1262,14 @@ shaders/shaders_basic_pbr: shaders/shaders_basic_pbr.c --preload-file shaders/resources/road_mra.png@resources/road_mra.png \ --preload-file shaders/resources/road_n.png@resources/road_n.png +shapes/shapes_recursive_tree: shaders/shaders_color_correction.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file shaders/resources/shaders/glsl100/color_correction.fs@resources/shaders/glsl100/color_correction.fs \ + --preload-file shaders/resources/parrots.png@resources/parrots.png \ + --preload-file shaders/resources/cat.png@resources/cat.png \ + --preload-file shaders/resources/mandrill.png@resources/mandrill.png \ + --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png + shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/models/barracks.obj@resources/models/barracks.obj \ diff --git a/examples/README.md b/examples/README.md index bbb0a0388..de28c931f 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: 187] +## EXAMPLES COLLECTION [TOTAL: 188] ### category: core [45] @@ -196,7 +196,7 @@ Examples using raylib models functionality, including models loading/generation | [models_basic_voxel](models/models_basic_voxel.c) | models_basic_voxel | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) | | [models_rotating_cube](models/models_rotating_cube.c) | models_rotating_cube | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) | -### category: shaders [31] +### category: shaders [32] 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. @@ -233,6 +233,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_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | shaders_mandelbrot_set | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | +| [shaders_color_correction](shaders/shaders_color_correction.c) | shaders_color_correction | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | ### category: audio [8] diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 4805a37ec..f24cb9905 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -163,6 +163,7 @@ shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff"; shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232 shaders;shaders_mandelbrot_set;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant +shaders;shaders_color_correction;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant shaders;shaders_eratosthenes_sieve;★★★☆;2.5;4.0;2019;2025;"ProfJski";@ProfJski shaders;shaders_fog_rendering;★★★☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho shaders;shaders_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho diff --git a/examples/shaders/raygui.h b/examples/shaders/raygui.h new file mode 100644 index 000000000..a3fc51f0f --- /dev/null +++ b/examples/shaders/raygui.h @@ -0,0 +1,5757 @@ +/******************************************************************************************* +* +* raygui v4.5-dev - A simple and easy-to-use immediate-mode gui library +* +* DESCRIPTION: +* raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also +* available as a standalone library, as long as input and drawing functions are provided. +* +* FEATURES: +* - Immediate-mode gui, minimal retained data +* - +25 controls provided (basic and advanced) +* - Styling system for colors, font and metrics +* - Icons supported, embedded as a 1-bit icons pack +* - Standalone mode option (custom input/graphics backend) +* - Multiple support tools provided for raygui development +* +* POSSIBLE IMPROVEMENTS: +* - Better standalone mode API for easy plug of custom backends +* - Externalize required inputs, allow user easier customization +* +* LIMITATIONS: +* - No editable multi-line word-wraped text box supported +* - No auto-layout mechanism, up to the user to define controls position and size +* - Standalone mode requires library modification and some user work to plug another backend +* +* NOTES: +* - WARNING: GuiLoadStyle() and GuiLoadStyle{Custom}() functions, allocate memory for +* font atlas recs and glyphs, freeing that memory is (usually) up to the user, +* no unload function is explicitly provided... but note that GuiLoadStyleDefault() unloads +* by default any previously loaded font (texture, recs, glyphs). +* - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions +* +* CONTROLS PROVIDED: +* # Container/separators Controls +* - WindowBox --> StatusBar, Panel +* - GroupBox --> Line +* - Line +* - Panel --> StatusBar +* - ScrollPanel --> StatusBar +* - TabBar --> Button +* +* # Basic Controls +* - Label +* - LabelButton --> Label +* - Button +* - Toggle +* - ToggleGroup --> Toggle +* - ToggleSlider +* - CheckBox +* - ComboBox +* - DropdownBox +* - TextBox +* - ValueBox --> TextBox +* - Spinner --> Button, ValueBox +* - Slider +* - SliderBar --> Slider +* - ProgressBar +* - StatusBar +* - DummyRec +* - Grid +* +* # Advance Controls +* - ListView +* - ColorPicker --> ColorPanel, ColorBarHue +* - MessageBox --> Window, Label, Button +* - TextInputBox --> Window, Label, TextBox, Button +* +* It also provides a set of functions for styling the controls based on its properties (size, color). +* +* +* RAYGUI STYLE (guiStyle): +* raygui uses a global data array for all gui style properties (allocated on data segment by default), +* when a new style is loaded, it is loaded over the global style... but a default gui style could always be +* recovered with GuiLoadStyleDefault() function, that overwrites the current style to the default one +* +* The global style array size is fixed and depends on the number of controls and properties: +* +* static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)]; +* +* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB +* +* Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style +* used for all controls, when any of those base values is set, it is automatically populated to all +* controls, so, specific control values overwriting generic style should be set after base values. +* +* After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those +* properties are actually common to all controls and can not be overwritten individually (like BASE ones) +* Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR +* +* Custom control properties can be defined using the EXTENDED properties for each independent control. +* +* TOOL: rGuiStyler is a visual tool to customize raygui style: github.com/raysan5/rguistyler +* +* +* RAYGUI ICONS (guiIcons): +* raygui could use a global array containing icons data (allocated on data segment by default), +* a custom icons set could be loaded over this array using GuiLoadIcons(), but loaded icons set +* must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS will be loaded +* +* Every icon is codified in binary form, using 1 bit per pixel, so, every 16x16 icon +* requires 8 integers (16*16/32) to be stored in memory. +* +* When the icon is draw, actually one quad per pixel is drawn if the bit for that pixel is set. +* +* The global icons array size is fixed and depends on the number of icons and size: +* +* static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS]; +* +* guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB +* +* TOOL: rGuiIcons is a visual tool to customize/create raygui icons: github.com/raysan5/rguiicons +* +* RAYGUI LAYOUT: +* raygui currently does not provide an auto-layout mechanism like other libraries, +* layouts must be defined manually on controls drawing, providing the right bounds Rectangle for it. +* +* TOOL: rGuiLayout is a visual tool to create raygui layouts: github.com/raysan5/rguilayout +* +* CONFIGURATION: +* #define RAYGUI_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RAYGUI_STANDALONE +* Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined +* internally in the library and input management and drawing functions must be provided by +* the user (check library implementation for further details). +* +* #define RAYGUI_NO_ICONS +* Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB) +* +* #define RAYGUI_CUSTOM_ICONS +* Includes custom ricons.h header defining a set of custom icons, +* this file can be generated using rGuiIcons tool +* +* #define RAYGUI_DEBUG_RECS_BOUNDS +* Draw control bounds rectangles for debug +* +* #define RAYGUI_DEBUG_TEXT_BOUNDS +* Draw text bounds rectangles for debug +* +* VERSIONS HISTORY: +* 4.5-dev (Sep-2024) Current dev version... +* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes +* ADDED: GuiValueBoxFloat() +* ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP +* ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH +* ADDED: Multiple new icons +* REVIEWED: GuiTabBar(), close tab with mouse middle button +* REVIEWED: GuiScrollPanel(), scroll speed proportional to content +* REVIEWED: GuiDropdownBox(), support roll up and hidden arrow +* REVIEWED: GuiTextBox(), cursor position initialization +* REVIEWED: GuiSliderPro(), control value change check +* REVIEWED: GuiGrid(), simplified implementation +* REVIEWED: GuiIconText(), increase buffer size and reviewed padding +* REVIEWED: GuiDrawText(), improved wrap mode drawing +* REVIEWED: GuiScrollBar(), minor tweaks +* REVIEWED: Functions descriptions, removed wrong return value reference +* REDESIGNED: GuiColorPanel(), improved HSV <-> RGBA convertion +* +* 4.0 (12-Sep-2023) ADDED: GuiToggleSlider() +* ADDED: GuiColorPickerHSV() and GuiColorPanelHSV() +* ADDED: Multiple new icons, mostly compiler related +* ADDED: New DEFAULT properties: TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE +* ADDED: New enum values: GuiTextAlignment, GuiTextAlignmentVertical, GuiTextWrapMode +* ADDED: Support loading styles with custom font charset from external file +* REDESIGNED: GuiTextBox(), support mouse cursor positioning +* REDESIGNED: GuiDrawText(), support multiline and word-wrap modes (read only) +* REDESIGNED: GuiProgressBar() to be more visual, progress affects border color +* REDESIGNED: Global alpha consideration moved to GuiDrawRectangle() and GuiDrawText() +* REDESIGNED: GuiScrollPanel(), get parameters by reference and return result value +* REDESIGNED: GuiToggleGroup(), get parameters by reference and return result value +* REDESIGNED: GuiComboBox(), get parameters by reference and return result value +* REDESIGNED: GuiCheckBox(), get parameters by reference and return result value +* REDESIGNED: GuiSlider(), get parameters by reference and return result value +* REDESIGNED: GuiSliderBar(), get parameters by reference and return result value +* REDESIGNED: GuiProgressBar(), get parameters by reference and return result value +* REDESIGNED: GuiListView(), get parameters by reference and return result value +* REDESIGNED: GuiColorPicker(), get parameters by reference and return result value +* REDESIGNED: GuiColorPanel(), get parameters by reference and return result value +* REDESIGNED: GuiColorBarAlpha(), get parameters by reference and return result value +* REDESIGNED: GuiColorBarHue(), get parameters by reference and return result value +* REDESIGNED: GuiGrid(), get parameters by reference and return result value +* REDESIGNED: GuiGrid(), added extra parameter +* REDESIGNED: GuiListViewEx(), change parameters order +* REDESIGNED: All controls return result as int value +* REVIEWED: GuiScrollPanel() to avoid smallish scroll-bars +* REVIEWED: All examples and specially controls_test_suite +* RENAMED: gui_file_dialog module to gui_window_file_dialog +* UPDATED: All styles to include ISO-8859-15 charset (as much as possible) +* +* 3.6 (10-May-2023) ADDED: New icon: SAND_TIMER +* ADDED: GuiLoadStyleFromMemory() (binary only) +* REVIEWED: GuiScrollBar() horizontal movement key +* REVIEWED: GuiTextBox() crash on cursor movement +* REVIEWED: GuiTextBox(), additional inputs support +* REVIEWED: GuiLabelButton(), avoid text cut +* REVIEWED: GuiTextInputBox(), password input +* REVIEWED: Local GetCodepointNext(), aligned with raylib +* REDESIGNED: GuiSlider*()/GuiScrollBar() to support out-of-bounds +* +* 3.5 (20-Apr-2023) ADDED: GuiTabBar(), based on GuiToggle() +* ADDED: Helper functions to split text in separate lines +* ADDED: Multiple new icons, useful for code editing tools +* REMOVED: Unneeded icon editing functions +* REMOVED: GuiTextBoxMulti(), very limited and broken +* REMOVED: MeasureTextEx() dependency, logic directly implemented +* REMOVED: DrawTextEx() dependency, logic directly implemented +* REVIEWED: GuiScrollBar(), improve mouse-click behaviour +* REVIEWED: Library header info, more info, better organized +* REDESIGNED: GuiTextBox() to support cursor movement +* REDESIGNED: GuiDrawText() to divide drawing by lines +* +* 3.2 (22-May-2022) RENAMED: Some enum values, for unification, avoiding prefixes +* REMOVED: GuiScrollBar(), only internal +* REDESIGNED: GuiPanel() to support text parameter +* REDESIGNED: GuiScrollPanel() to support text parameter +* REDESIGNED: GuiColorPicker() to support text parameter +* REDESIGNED: GuiColorPanel() to support text parameter +* REDESIGNED: GuiColorBarAlpha() to support text parameter +* REDESIGNED: GuiColorBarHue() to support text parameter +* REDESIGNED: GuiTextInputBox() to support password +* +* 3.1 (12-Jan-2022) REVIEWED: Default style for consistency (aligned with rGuiLayout v2.5 tool) +* REVIEWED: GuiLoadStyle() to support compressed font atlas image data and unload previous textures +* REVIEWED: External icons usage logic +* REVIEWED: GuiLine() for centered alignment when including text +* RENAMED: Multiple controls properties definitions to prepend RAYGUI_ +* RENAMED: RICON_ references to RAYGUI_ICON_ for library consistency +* Projects updated and multiple tweaks +* +* 3.0 (04-Nov-2021) Integrated ricons data to avoid external file +* REDESIGNED: GuiTextBoxMulti() +* REMOVED: GuiImageButton*() +* Multiple minor tweaks and bugs corrected +* +* 2.9 (17-Mar-2021) REMOVED: Tooltip API +* 2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle() +* 2.7 (20-Feb-2020) ADDED: Possible tooltips API +* 2.6 (09-Sep-2019) ADDED: GuiTextInputBox() +* REDESIGNED: GuiListView*(), GuiDropdownBox(), GuiSlider*(), GuiProgressBar(), GuiMessageBox() +* REVIEWED: GuiTextBox(), GuiSpinner(), GuiValueBox(), GuiLoadStyle() +* Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties +* ADDED: 8 new custom styles ready to use +* Multiple minor tweaks and bugs corrected +* +* 2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner() +* 2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed +* Refactor all controls drawing mechanism to use control state +* 2.2 (05-Feb-2019) ADDED: GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls +* 2.1 (26-Dec-2018) REDESIGNED: GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string +* REDESIGNED: Style system (breaking change) +* 2.0 (08-Nov-2018) ADDED: Support controls guiLock and custom fonts +* REVIEWED: GuiComboBox(), GuiListView()... +* 1.9 (09-Oct-2018) REVIEWED: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()... +* 1.8 (01-May-2018) Lot of rework and redesign to align with rGuiStyler and rGuiLayout +* 1.5 (21-Jun-2017) Working in an improved styles system +* 1.4 (15-Jun-2017) Rewritten all GUI functions (removed useless ones) +* 1.3 (12-Jun-2017) Complete redesign of style system +* 1.1 (01-Jun-2017) Complete review of the library +* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria. +* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria. +* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria. +* +* DEPENDENCIES: +* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing +* +* STANDALONE MODE: +* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled +* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs. +* +* The following functions should be redefined for a custom backend: +* +* - Vector2 GetMousePosition(void); +* - float GetMouseWheelMove(void); +* - bool IsMouseButtonDown(int button); +* - bool IsMouseButtonPressed(int button); +* - bool IsMouseButtonReleased(int button); +* - bool IsKeyDown(int key); +* - bool IsKeyPressed(int key); +* - int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +* +* - void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +* - void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() +* +* - Font GetFontDefault(void); // -- GuiLoadStyleDefault() +* - Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // -- GuiLoadStyle() +* - Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle(), required to load texture from embedded font atlas image +* - void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle(), required to set shapes rec to font white rec (optimization) +* - char *LoadFileText(const char *fileName); // -- GuiLoadStyle(), required to load charset data +* - void UnloadFileText(char *text); // -- GuiLoadStyle(), required to unload charset data +* - const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle(), required to find charset/font file from text .rgs +* - int *LoadCodepoints(const char *text, int *count); // -- GuiLoadStyle(), required to load required font codepoints list +* - void UnloadCodepoints(int *codepoints); // -- GuiLoadStyle(), required to unload codepoints list +* - unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // -- GuiLoadStyle() +* +* CONTRIBUTORS: +* Ramon Santamaria: Supervision, review, redesign, update and maintenance +* Vlad Adrian: Complete rewrite of GuiTextBox() to support extended features (2019) +* Sergio Martinez: Review, testing (2015) and redesign of multiple controls (2018) +* Adria Arranz: Testing and implementation of additional controls (2018) +* Jordi Jorba: Testing and implementation of additional controls (2018) +* Albert Martos: Review and testing of the library (2015) +* Ian Eito: Review and testing of the library (2015) +* Kevin Gato: Initial implementation of basic components (2014) +* Daniel Nicolas: Initial implementation of basic components (2014) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RAYGUI_H +#define RAYGUI_H + +#define RAYGUI_VERSION_MAJOR 4 +#define RAYGUI_VERSION_MINOR 5 +#define RAYGUI_VERSION_PATCH 0 +#define RAYGUI_VERSION "4.5-dev" + +#if !defined(RAYGUI_STANDALONE) + #include "raylib.h" +#endif + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll +#if defined(_WIN32) + #if defined(BUILD_LIBTYPE_SHARED) + #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #elif defined(USE_LIBTYPE_SHARED) + #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #endif +#endif + +// Function specifiers definition +#ifndef RAYGUIAPI + #define RAYGUIAPI // Functions defined as 'extern' by default (implicit specifiers) +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// Allow custom memory allocators +#ifndef RAYGUI_MALLOC + #define RAYGUI_MALLOC(sz) malloc(sz) +#endif +#ifndef RAYGUI_CALLOC + #define RAYGUI_CALLOC(n,sz) calloc(n,sz) +#endif +#ifndef RAYGUI_FREE + #define RAYGUI_FREE(p) free(p) +#endif + +// Simple log system to avoid printf() calls if required +// NOTE: Avoiding those calls, also avoids const strings memory usage +#define RAYGUI_SUPPORT_LOG_INFO +#if defined(RAYGUI_SUPPORT_LOG_INFO) + #define RAYGUI_LOG(...) printf(__VA_ARGS__) +#else + #define RAYGUI_LOG(...) +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +// NOTE: Some types are required for RAYGUI_STANDALONE usage +//---------------------------------------------------------------------------------- +#if defined(RAYGUI_STANDALONE) + #ifndef __cplusplus + // Boolean type + #ifndef true + typedef enum { false, true } bool; + #endif + #endif + + // Vector2 type + typedef struct Vector2 { + float x; + float y; + } Vector2; + + // Vector3 type // -- ConvertHSVtoRGB(), ConvertRGBtoHSV() + typedef struct Vector3 { + float x; + float y; + float z; + } Vector3; + + // Color type, RGBA (32bit) + typedef struct Color { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + } Color; + + // Rectangle type + typedef struct Rectangle { + float x; + float y; + float width; + float height; + } Rectangle; + + // TODO: Texture2D type is very coupled to raylib, required by Font type + // It should be redesigned to be provided by user + typedef struct Texture2D { + unsigned int id; // OpenGL texture id + int width; // Texture base width + int height; // Texture base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) + } Texture2D; + + // Image, pixel data stored in CPU memory (RAM) + typedef struct Image { + void *data; // Image raw data + int width; // Image base width + int height; // Image base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) + } Image; + + // GlyphInfo, font characters glyphs info + typedef struct GlyphInfo { + int value; // Character value (Unicode) + int offsetX; // Character offset X when drawing + int offsetY; // Character offset Y when drawing + int advanceX; // Character advance position X + Image image; // Character image data + } GlyphInfo; + + // TODO: Font type is very coupled to raylib, mostly required by GuiLoadStyle() + // It should be redesigned to be provided by user + typedef struct Font { + int baseSize; // Base size (default chars height) + int glyphCount; // Number of glyph characters + int glyphPadding; // Padding around the glyph characters + Texture2D texture; // Texture atlas containing the glyphs + Rectangle *recs; // Rectangles in texture for the glyphs + GlyphInfo *glyphs; // Glyphs info data + } Font; +#endif + +// Style property +// NOTE: Used when exporting style as code for convenience +typedef struct GuiStyleProp { + unsigned short controlId; // Control identifier + unsigned short propertyId; // Property identifier + int propertyValue; // Property value +} GuiStyleProp; + +/* +// Controls text style -NOT USED- +// NOTE: Text style is defined by control +typedef struct GuiTextStyle { + unsigned int size; + int charSpacing; + int lineSpacing; + int alignmentH; + int alignmentV; + int padding; +} GuiTextStyle; +*/ + +// Gui control state +typedef enum { + STATE_NORMAL = 0, + STATE_FOCUSED, + STATE_PRESSED, + STATE_DISABLED +} GuiState; + +// Gui control text alignment +typedef enum { + TEXT_ALIGN_LEFT = 0, + TEXT_ALIGN_CENTER, + TEXT_ALIGN_RIGHT +} GuiTextAlignment; + +// Gui control text alignment vertical +// NOTE: Text vertical position inside the text bounds +typedef enum { + TEXT_ALIGN_TOP = 0, + TEXT_ALIGN_MIDDLE, + TEXT_ALIGN_BOTTOM +} GuiTextAlignmentVertical; + +// Gui control text wrap mode +// NOTE: Useful for multiline text +typedef enum { + TEXT_WRAP_NONE = 0, + TEXT_WRAP_CHAR, + TEXT_WRAP_WORD +} GuiTextWrapMode; + +// Gui controls +typedef enum { + // Default -> populates to all controls when set + DEFAULT = 0, + + // Basic controls + LABEL, // Used also for: LABELBUTTON + BUTTON, + TOGGLE, // Used also for: TOGGLEGROUP + SLIDER, // Used also for: SLIDERBAR, TOGGLESLIDER + PROGRESSBAR, + CHECKBOX, + COMBOBOX, + DROPDOWNBOX, + TEXTBOX, // Used also for: TEXTBOXMULTI + VALUEBOX, + SPINNER, // Uses: BUTTON, VALUEBOX + LISTVIEW, + COLORPICKER, + SCROLLBAR, + STATUSBAR +} GuiControl; + +// Gui base properties for every control +// NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties) +typedef enum { + BORDER_COLOR_NORMAL = 0, // Control border color in STATE_NORMAL + BASE_COLOR_NORMAL, // Control base color in STATE_NORMAL + TEXT_COLOR_NORMAL, // Control text color in STATE_NORMAL + BORDER_COLOR_FOCUSED, // Control border color in STATE_FOCUSED + BASE_COLOR_FOCUSED, // Control base color in STATE_FOCUSED + TEXT_COLOR_FOCUSED, // Control text color in STATE_FOCUSED + BORDER_COLOR_PRESSED, // Control border color in STATE_PRESSED + BASE_COLOR_PRESSED, // Control base color in STATE_PRESSED + TEXT_COLOR_PRESSED, // Control text color in STATE_PRESSED + BORDER_COLOR_DISABLED, // Control border color in STATE_DISABLED + BASE_COLOR_DISABLED, // Control base color in STATE_DISABLED + TEXT_COLOR_DISABLED, // Control text color in STATE_DISABLED + BORDER_WIDTH, // Control border size, 0 for no border + //TEXT_SIZE, // Control text size (glyphs max height) -> GLOBAL for all controls + //TEXT_SPACING, // Control text spacing between glyphs -> GLOBAL for all controls + //TEXT_LINE_SPACING // Control text spacing between lines -> GLOBAL for all controls + TEXT_PADDING, // Control text padding, not considering border + TEXT_ALIGNMENT, // Control text horizontal alignment inside control text bound (after border and padding) + //TEXT_WRAP_MODE // Control text wrap-mode inside text bounds -> GLOBAL for all controls +} GuiControlProperty; + +// TODO: Which text styling properties should be global or per-control? +// At this moment TEXT_PADDING and TEXT_ALIGNMENT is configured and saved per control while +// TEXT_SIZE, TEXT_SPACING, TEXT_LINE_SPACING, TEXT_ALIGNMENT_VERTICAL, TEXT_WRAP_MODE are global and +// should be configured by user as needed while defining the UI layout + +// Gui extended properties depend on control +// NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties) +//---------------------------------------------------------------------------------- +// DEFAULT extended properties +// NOTE: Those properties are common to all controls or global +// WARNING: We only have 8 slots for those properties by default!!! -> New global control: TEXT? +typedef enum { + TEXT_SIZE = 16, // Text size (glyphs max height) + TEXT_SPACING, // Text spacing between glyphs + LINE_COLOR, // Line control color + BACKGROUND_COLOR, // Background color + TEXT_LINE_SPACING, // Text spacing between lines + TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) + TEXT_WRAP_MODE // Text wrap-mode inside text bounds + //TEXT_DECORATION // Text decoration: 0-None, 1-Underline, 2-Line-through, 3-Overline + //TEXT_DECORATION_THICK // Text decoration line thickness +} GuiDefaultProperty; + +// Other possible text properties: +// TEXT_WEIGHT // Normal, Italic, Bold -> Requires specific font change +// TEXT_INDENT // Text indentation -> Now using TEXT_PADDING... + +// Label +//typedef enum { } GuiLabelProperty; + +// Button/Spinner +//typedef enum { } GuiButtonProperty; + +// Toggle/ToggleGroup +typedef enum { + GROUP_PADDING = 16, // ToggleGroup separation between toggles +} GuiToggleProperty; + +// Slider/SliderBar +typedef enum { + SLIDER_WIDTH = 16, // Slider size of internal bar + SLIDER_PADDING // Slider/SliderBar internal bar padding +} GuiSliderProperty; + +// ProgressBar +typedef enum { + PROGRESS_PADDING = 16, // ProgressBar internal padding +} GuiProgressBarProperty; + +// ScrollBar +typedef enum { + ARROWS_SIZE = 16, // ScrollBar arrows size + ARROWS_VISIBLE, // ScrollBar arrows visible + SCROLL_SLIDER_PADDING, // ScrollBar slider internal padding + SCROLL_SLIDER_SIZE, // ScrollBar slider size + SCROLL_PADDING, // ScrollBar scroll padding from arrows + SCROLL_SPEED, // ScrollBar scrolling speed +} GuiScrollBarProperty; + +// CheckBox +typedef enum { + CHECK_PADDING = 16 // CheckBox internal check padding +} GuiCheckBoxProperty; + +// ComboBox +typedef enum { + COMBO_BUTTON_WIDTH = 16, // ComboBox right button width + COMBO_BUTTON_SPACING // ComboBox button separation +} GuiComboBoxProperty; + +// DropdownBox +typedef enum { + ARROW_PADDING = 16, // DropdownBox arrow separation from border and items + DROPDOWN_ITEMS_SPACING, // DropdownBox items separation + DROPDOWN_ARROW_HIDDEN, // DropdownBox arrow hidden + DROPDOWN_ROLL_UP // DropdownBox roll up flag (default rolls down) +} GuiDropdownBoxProperty; + +// TextBox/TextBoxMulti/ValueBox/Spinner +typedef enum { + TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable +} GuiTextBoxProperty; + +// Spinner +typedef enum { + SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width + SPIN_BUTTON_SPACING, // Spinner buttons separation +} GuiSpinnerProperty; + +// ListView +typedef enum { + LIST_ITEMS_HEIGHT = 16, // ListView items height + LIST_ITEMS_SPACING, // ListView items separation + SCROLLBAR_WIDTH, // ListView scrollbar size (usually width) + SCROLLBAR_SIDE, // ListView scrollbar side (0-SCROLLBAR_LEFT_SIDE, 1-SCROLLBAR_RIGHT_SIDE) + LIST_ITEMS_BORDER_WIDTH // ListView items border width +} GuiListViewProperty; + +// ColorPicker +typedef enum { + COLOR_SELECTOR_SIZE = 16, + HUEBAR_WIDTH, // ColorPicker right hue bar width + HUEBAR_PADDING, // ColorPicker right hue bar separation from panel + HUEBAR_SELECTOR_HEIGHT, // ColorPicker right hue bar selector height + HUEBAR_SELECTOR_OVERFLOW // ColorPicker right hue bar selector overflow +} GuiColorPickerProperty; + +#define SCROLLBAR_LEFT_SIDE 0 +#define SCROLLBAR_RIGHT_SIDE 1 + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- + +#if defined(__cplusplus) +extern "C" { // Prevents name mangling of functions +#endif + +// Global gui state control functions +RAYGUIAPI void GuiEnable(void); // Enable gui controls (global state) +RAYGUIAPI void GuiDisable(void); // Disable gui controls (global state) +RAYGUIAPI void GuiLock(void); // Lock gui controls (global state) +RAYGUIAPI void GuiUnlock(void); // Unlock gui controls (global state) +RAYGUIAPI bool GuiIsLocked(void); // Check if gui is locked (global state) +RAYGUIAPI void GuiSetAlpha(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f +RAYGUIAPI void GuiSetState(int state); // Set gui state (global state) +RAYGUIAPI int GuiGetState(void); // Get gui state (global state) + +// Font set/get functions +RAYGUIAPI void GuiSetFont(Font font); // Set gui custom font (global state) +RAYGUIAPI Font GuiGetFont(void); // Get gui custom font (global state) + +// Style set/get functions +RAYGUIAPI void GuiSetStyle(int control, int property, int value); // Set one style property +RAYGUIAPI int GuiGetStyle(int control, int property); // Get one style property + +// Styles loading functions +RAYGUIAPI void GuiLoadStyle(const char *fileName); // Load style file over global style variable (.rgs) +RAYGUIAPI void GuiLoadStyleDefault(void); // Load style default over global style + +// Tooltips management functions +RAYGUIAPI void GuiEnableTooltip(void); // Enable gui tooltips (global state) +RAYGUIAPI void GuiDisableTooltip(void); // Disable gui tooltips (global state) +RAYGUIAPI void GuiSetTooltip(const char *tooltip); // Set tooltip string + +// Icons functionality +RAYGUIAPI const char *GuiIconText(int iconId, const char *text); // Get text with icon id prepended (if supported) +#if !defined(RAYGUI_NO_ICONS) +RAYGUIAPI void GuiSetIconScale(int scale); // Set default icon drawing size +RAYGUIAPI unsigned int *GuiGetIcons(void); // Get raygui icons data pointer +RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load raygui icons file (.rgi) into internal icons data +RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color); // Draw icon using pixel size at specified position +#endif + +// Controls +//---------------------------------------------------------------------------------------------------------- +// Container/separator controls, useful for controls organization +RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title); // Window Box control, shows a window that can be closed +RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name +RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text +RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls +RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 +RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control + +// Basic controls set +RAYGUIAPI int GuiLabel(Rectangle bounds, const char *text); // Label control +RAYGUIAPI int GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked +RAYGUIAPI int GuiLabelButton(Rectangle bounds, const char *text); // Label button control, returns true when clicked +RAYGUIAPI int GuiToggle(Rectangle bounds, const char *text, bool *active); // Toggle Button control +RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int *active); // Toggle Group control +RAYGUIAPI int GuiToggleSlider(Rectangle bounds, const char *text, int *active); // Toggle Slider control +RAYGUIAPI int GuiCheckBox(Rectangle bounds, const char *text, bool *checked); // Check Box control, returns true when active +RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int *active); // Combo Box control + +RAYGUIAPI int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control +RAYGUIAPI int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control +RAYGUIAPI int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers +RAYGUIAPI int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float *value, bool editMode); // Value box control for float values +RAYGUIAPI int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text + +RAYGUIAPI int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider control +RAYGUIAPI int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Slider Bar control +RAYGUIAPI int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue); // Progress Bar control +RAYGUIAPI int GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text +RAYGUIAPI int GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders +RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell); // Grid control + +// Advance controls set +RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control +RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters +RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message +RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret +RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) +RAYGUIAPI int GuiColorPanel(Rectangle bounds, const char *text, Color *color); // Color Panel control +RAYGUIAPI int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha); // Color Bar Alpha control +RAYGUIAPI int GuiColorBarHue(Rectangle bounds, const char *text, float *value); // Color Bar Hue control +RAYGUIAPI int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Picker control that avoids conversion to RGB on each call (multiple color controls) +RAYGUIAPI int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv); // Color Panel control that updates Hue-Saturation-Value color value, used by GuiColorPickerHSV() +//---------------------------------------------------------------------------------------------------------- + +#if !defined(RAYGUI_NO_ICONS) + +#if !defined(RAYGUI_CUSTOM_ICONS) +//---------------------------------------------------------------------------------- +// Icons enumeration +//---------------------------------------------------------------------------------- +typedef enum { + ICON_NONE = 0, + ICON_FOLDER_FILE_OPEN = 1, + ICON_FILE_SAVE_CLASSIC = 2, + ICON_FOLDER_OPEN = 3, + ICON_FOLDER_SAVE = 4, + ICON_FILE_OPEN = 5, + ICON_FILE_SAVE = 6, + ICON_FILE_EXPORT = 7, + ICON_FILE_ADD = 8, + ICON_FILE_DELETE = 9, + ICON_FILETYPE_TEXT = 10, + ICON_FILETYPE_AUDIO = 11, + ICON_FILETYPE_IMAGE = 12, + ICON_FILETYPE_PLAY = 13, + ICON_FILETYPE_VIDEO = 14, + ICON_FILETYPE_INFO = 15, + ICON_FILE_COPY = 16, + ICON_FILE_CUT = 17, + ICON_FILE_PASTE = 18, + ICON_CURSOR_HAND = 19, + ICON_CURSOR_POINTER = 20, + ICON_CURSOR_CLASSIC = 21, + ICON_PENCIL = 22, + ICON_PENCIL_BIG = 23, + ICON_BRUSH_CLASSIC = 24, + ICON_BRUSH_PAINTER = 25, + ICON_WATER_DROP = 26, + ICON_COLOR_PICKER = 27, + ICON_RUBBER = 28, + ICON_COLOR_BUCKET = 29, + ICON_TEXT_T = 30, + ICON_TEXT_A = 31, + ICON_SCALE = 32, + ICON_RESIZE = 33, + ICON_FILTER_POINT = 34, + ICON_FILTER_BILINEAR = 35, + ICON_CROP = 36, + ICON_CROP_ALPHA = 37, + ICON_SQUARE_TOGGLE = 38, + ICON_SYMMETRY = 39, + ICON_SYMMETRY_HORIZONTAL = 40, + ICON_SYMMETRY_VERTICAL = 41, + ICON_LENS = 42, + ICON_LENS_BIG = 43, + ICON_EYE_ON = 44, + ICON_EYE_OFF = 45, + ICON_FILTER_TOP = 46, + ICON_FILTER = 47, + ICON_TARGET_POINT = 48, + ICON_TARGET_SMALL = 49, + ICON_TARGET_BIG = 50, + ICON_TARGET_MOVE = 51, + ICON_CURSOR_MOVE = 52, + ICON_CURSOR_SCALE = 53, + ICON_CURSOR_SCALE_RIGHT = 54, + ICON_CURSOR_SCALE_LEFT = 55, + ICON_UNDO = 56, + ICON_REDO = 57, + ICON_REREDO = 58, + ICON_MUTATE = 59, + ICON_ROTATE = 60, + ICON_REPEAT = 61, + ICON_SHUFFLE = 62, + ICON_EMPTYBOX = 63, + ICON_TARGET = 64, + ICON_TARGET_SMALL_FILL = 65, + ICON_TARGET_BIG_FILL = 66, + ICON_TARGET_MOVE_FILL = 67, + ICON_CURSOR_MOVE_FILL = 68, + ICON_CURSOR_SCALE_FILL = 69, + ICON_CURSOR_SCALE_RIGHT_FILL = 70, + ICON_CURSOR_SCALE_LEFT_FILL = 71, + ICON_UNDO_FILL = 72, + ICON_REDO_FILL = 73, + ICON_REREDO_FILL = 74, + ICON_MUTATE_FILL = 75, + ICON_ROTATE_FILL = 76, + ICON_REPEAT_FILL = 77, + ICON_SHUFFLE_FILL = 78, + ICON_EMPTYBOX_SMALL = 79, + ICON_BOX = 80, + ICON_BOX_TOP = 81, + ICON_BOX_TOP_RIGHT = 82, + ICON_BOX_RIGHT = 83, + ICON_BOX_BOTTOM_RIGHT = 84, + ICON_BOX_BOTTOM = 85, + ICON_BOX_BOTTOM_LEFT = 86, + ICON_BOX_LEFT = 87, + ICON_BOX_TOP_LEFT = 88, + ICON_BOX_CENTER = 89, + ICON_BOX_CIRCLE_MASK = 90, + ICON_POT = 91, + ICON_ALPHA_MULTIPLY = 92, + ICON_ALPHA_CLEAR = 93, + ICON_DITHERING = 94, + ICON_MIPMAPS = 95, + ICON_BOX_GRID = 96, + ICON_GRID = 97, + ICON_BOX_CORNERS_SMALL = 98, + ICON_BOX_CORNERS_BIG = 99, + ICON_FOUR_BOXES = 100, + ICON_GRID_FILL = 101, + ICON_BOX_MULTISIZE = 102, + ICON_ZOOM_SMALL = 103, + ICON_ZOOM_MEDIUM = 104, + ICON_ZOOM_BIG = 105, + ICON_ZOOM_ALL = 106, + ICON_ZOOM_CENTER = 107, + ICON_BOX_DOTS_SMALL = 108, + ICON_BOX_DOTS_BIG = 109, + ICON_BOX_CONCENTRIC = 110, + ICON_BOX_GRID_BIG = 111, + ICON_OK_TICK = 112, + ICON_CROSS = 113, + ICON_ARROW_LEFT = 114, + ICON_ARROW_RIGHT = 115, + ICON_ARROW_DOWN = 116, + ICON_ARROW_UP = 117, + ICON_ARROW_LEFT_FILL = 118, + ICON_ARROW_RIGHT_FILL = 119, + ICON_ARROW_DOWN_FILL = 120, + ICON_ARROW_UP_FILL = 121, + ICON_AUDIO = 122, + ICON_FX = 123, + ICON_WAVE = 124, + ICON_WAVE_SINUS = 125, + ICON_WAVE_SQUARE = 126, + ICON_WAVE_TRIANGULAR = 127, + ICON_CROSS_SMALL = 128, + ICON_PLAYER_PREVIOUS = 129, + ICON_PLAYER_PLAY_BACK = 130, + ICON_PLAYER_PLAY = 131, + ICON_PLAYER_PAUSE = 132, + ICON_PLAYER_STOP = 133, + ICON_PLAYER_NEXT = 134, + ICON_PLAYER_RECORD = 135, + ICON_MAGNET = 136, + ICON_LOCK_CLOSE = 137, + ICON_LOCK_OPEN = 138, + ICON_CLOCK = 139, + ICON_TOOLS = 140, + ICON_GEAR = 141, + ICON_GEAR_BIG = 142, + ICON_BIN = 143, + ICON_HAND_POINTER = 144, + ICON_LASER = 145, + ICON_COIN = 146, + ICON_EXPLOSION = 147, + ICON_1UP = 148, + ICON_PLAYER = 149, + ICON_PLAYER_JUMP = 150, + ICON_KEY = 151, + ICON_DEMON = 152, + ICON_TEXT_POPUP = 153, + ICON_GEAR_EX = 154, + ICON_CRACK = 155, + ICON_CRACK_POINTS = 156, + ICON_STAR = 157, + ICON_DOOR = 158, + ICON_EXIT = 159, + ICON_MODE_2D = 160, + ICON_MODE_3D = 161, + ICON_CUBE = 162, + ICON_CUBE_FACE_TOP = 163, + ICON_CUBE_FACE_LEFT = 164, + ICON_CUBE_FACE_FRONT = 165, + ICON_CUBE_FACE_BOTTOM = 166, + ICON_CUBE_FACE_RIGHT = 167, + ICON_CUBE_FACE_BACK = 168, + ICON_CAMERA = 169, + ICON_SPECIAL = 170, + ICON_LINK_NET = 171, + ICON_LINK_BOXES = 172, + ICON_LINK_MULTI = 173, + ICON_LINK = 174, + ICON_LINK_BROKE = 175, + ICON_TEXT_NOTES = 176, + ICON_NOTEBOOK = 177, + ICON_SUITCASE = 178, + ICON_SUITCASE_ZIP = 179, + ICON_MAILBOX = 180, + ICON_MONITOR = 181, + ICON_PRINTER = 182, + ICON_PHOTO_CAMERA = 183, + ICON_PHOTO_CAMERA_FLASH = 184, + ICON_HOUSE = 185, + ICON_HEART = 186, + ICON_CORNER = 187, + ICON_VERTICAL_BARS = 188, + ICON_VERTICAL_BARS_FILL = 189, + ICON_LIFE_BARS = 190, + ICON_INFO = 191, + ICON_CROSSLINE = 192, + ICON_HELP = 193, + ICON_FILETYPE_ALPHA = 194, + ICON_FILETYPE_HOME = 195, + ICON_LAYERS_VISIBLE = 196, + ICON_LAYERS = 197, + ICON_WINDOW = 198, + ICON_HIDPI = 199, + ICON_FILETYPE_BINARY = 200, + ICON_HEX = 201, + ICON_SHIELD = 202, + ICON_FILE_NEW = 203, + ICON_FOLDER_ADD = 204, + ICON_ALARM = 205, + ICON_CPU = 206, + ICON_ROM = 207, + ICON_STEP_OVER = 208, + ICON_STEP_INTO = 209, + ICON_STEP_OUT = 210, + ICON_RESTART = 211, + ICON_BREAKPOINT_ON = 212, + ICON_BREAKPOINT_OFF = 213, + ICON_BURGER_MENU = 214, + ICON_CASE_SENSITIVE = 215, + ICON_REG_EXP = 216, + ICON_FOLDER = 217, + ICON_FILE = 218, + ICON_SAND_TIMER = 219, + ICON_WARNING = 220, + ICON_HELP_BOX = 221, + ICON_INFO_BOX = 222, + ICON_PRIORITY = 223, + ICON_LAYERS_ISO = 224, + ICON_LAYERS2 = 225, + ICON_MLAYERS = 226, + ICON_MAPS = 227, + ICON_HOT = 228, + ICON_229 = 229, + ICON_230 = 230, + ICON_231 = 231, + ICON_232 = 232, + ICON_233 = 233, + ICON_234 = 234, + ICON_235 = 235, + ICON_236 = 236, + ICON_237 = 237, + ICON_238 = 238, + ICON_239 = 239, + ICON_240 = 240, + ICON_241 = 241, + ICON_242 = 242, + ICON_243 = 243, + ICON_244 = 244, + ICON_245 = 245, + ICON_246 = 246, + ICON_247 = 247, + ICON_248 = 248, + ICON_249 = 249, + ICON_250 = 250, + ICON_251 = 251, + ICON_252 = 252, + ICON_253 = 253, + ICON_254 = 254, + ICON_255 = 255, +} GuiIconName; +#endif + +#endif + +#if defined(__cplusplus) +} // Prevents name mangling of functions +#endif + +#endif // RAYGUI_H + +/*********************************************************************************** +* +* RAYGUI IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RAYGUI_IMPLEMENTATION) + +#include // required for: isspace() [GuiTextBox()] +#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()] +#include // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()] +#include // Required for: strlen() [GuiTextBox(), GuiValueBox()], memset(), memcpy() +#include // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()] +#include // Required for: roundf() [GuiColorPicker()] + +#ifdef __cplusplus + #define RAYGUI_CLITERAL(name) name +#else + #define RAYGUI_CLITERAL(name) (name) +#endif + +// Check if two rectangles are equal, used to validate a slider bounds as an id +#ifndef CHECK_BOUNDS_ID + #define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height)) +#endif + +#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS) + +// Embedded icons, no external file provided +#define RAYGUI_ICON_SIZE 16 // Size of icons in pixels (squared) +#define RAYGUI_ICON_MAX_ICONS 256 // Maximum number of icons +#define RAYGUI_ICON_MAX_NAME_LENGTH 32 // Maximum length of icon name id + +// Icons data is defined by bit array (every bit represents one pixel) +// Those arrays are stored as unsigned int data arrays, so, +// every array element defines 32 pixels (bits) of information +// One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels) +// NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels) +#define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32) + +//---------------------------------------------------------------------------------- +// Icons data for all gui possible icons (allocated on data segment by default) +// +// NOTE 1: Every icon is codified in binary form, using 1 bit per pixel, so, +// every 16x16 icon requires 8 integers (16*16/32) to be stored +// +// NOTE 2: A different icon set could be loaded over this array using GuiLoadIcons(), +// but loaded icons set must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS +// +// guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB +//---------------------------------------------------------------------------------- +static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_NONE + 0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe, // ICON_FOLDER_FILE_OPEN + 0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe, // ICON_FILE_SAVE_CLASSIC + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100, // ICON_FOLDER_OPEN + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000, // ICON_FOLDER_SAVE + 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc, // ICON_FILE_OPEN + 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc, // ICON_FILE_SAVE + 0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc, // ICON_FILE_EXPORT + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc, // ICON_FILE_ADD + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc, // ICON_FILE_DELETE + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_FILETYPE_TEXT + 0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc, // ICON_FILETYPE_AUDIO + 0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc, // ICON_FILETYPE_IMAGE + 0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc, // ICON_FILETYPE_PLAY + 0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4, // ICON_FILETYPE_VIDEO + 0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc, // ICON_FILETYPE_INFO + 0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0, // ICON_FILE_COPY + 0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000, // ICON_FILE_CUT + 0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0, // ICON_FILE_PASTE + 0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_CURSOR_HAND + 0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000, // ICON_CURSOR_POINTER + 0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000, // ICON_CURSOR_CLASSIC + 0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000, // ICON_PENCIL + 0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000, // ICON_PENCIL_BIG + 0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8, // ICON_BRUSH_CLASSIC + 0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080, // ICON_BRUSH_PAINTER + 0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000, // ICON_WATER_DROP + 0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000, // ICON_COLOR_PICKER + 0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000, // ICON_RUBBER + 0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040, // ICON_COLOR_BUCKET + 0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000, // ICON_TEXT_T + 0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f, // ICON_TEXT_A + 0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e, // ICON_SCALE + 0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe, // ICON_RESIZE + 0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_POINT + 0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_BILINEAR + 0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002, // ICON_CROP + 0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000, // ICON_CROP_ALPHA + 0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002, // ICON_SQUARE_TOGGLE + 0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000, // ICON_SYMMETRY + 0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100, // ICON_SYMMETRY_HORIZONTAL + 0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180, // ICON_SYMMETRY_VERTICAL + 0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000, // ICON_LENS + 0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000, // ICON_LENS_BIG + 0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000, // ICON_EYE_ON + 0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000, // ICON_EYE_OFF + 0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100, // ICON_FILTER_TOP + 0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0, // ICON_FILTER + 0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_POINT + 0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL + 0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG + 0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280, // ICON_TARGET_MOVE + 0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280, // ICON_CURSOR_MOVE + 0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e, // ICON_CURSOR_SCALE + 0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000, // ICON_CURSOR_SCALE_RIGHT + 0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000, // ICON_CURSOR_SCALE_LEFT + 0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO + 0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO + 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000, // ICON_REREDO + 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000, // ICON_MUTATE + 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020, // ICON_ROTATE + 0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000, // ICON_REPEAT + 0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000, // ICON_SHUFFLE + 0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe, // ICON_EMPTYBOX + 0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000, // ICON_TARGET + 0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL_FILL + 0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG_FILL + 0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380, // ICON_TARGET_MOVE_FILL + 0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380, // ICON_CURSOR_MOVE_FILL + 0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e, // ICON_CURSOR_SCALE_FILL + 0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000, // ICON_CURSOR_SCALE_RIGHT_FILL + 0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000, // ICON_CURSOR_SCALE_LEFT_FILL + 0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO_FILL + 0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO_FILL + 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000, // ICON_REREDO_FILL + 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000, // ICON_MUTATE_FILL + 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020, // ICON_ROTATE_FILL + 0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000, // ICON_REPEAT_FILL + 0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000, // ICON_SHUFFLE_FILL + 0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000, // ICON_EMPTYBOX_SMALL + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX + 0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP + 0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_RIGHT + 0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_RIGHT + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000, // ICON_BOX_BOTTOM_RIGHT + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000, // ICON_BOX_BOTTOM + 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000, // ICON_BOX_BOTTOM_LEFT + 0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_LEFT + 0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_LEFT + 0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_CENTER + 0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe, // ICON_BOX_CIRCLE_MASK + 0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff, // ICON_POT + 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe, // ICON_ALPHA_MULTIPLY + 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe, // ICON_ALPHA_CLEAR + 0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe, // ICON_DITHERING + 0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0, // ICON_MIPMAPS + 0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000, // ICON_BOX_GRID + 0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248, // ICON_GRID + 0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000, // ICON_BOX_CORNERS_SMALL + 0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e, // ICON_BOX_CORNERS_BIG + 0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000, // ICON_FOUR_BOXES + 0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000, // ICON_GRID_FILL + 0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e, // ICON_BOX_MULTISIZE + 0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_SMALL + 0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_MEDIUM + 0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e, // ICON_ZOOM_BIG + 0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e, // ICON_ZOOM_ALL + 0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000, // ICON_ZOOM_CENTER + 0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000, // ICON_BOX_DOTS_SMALL + 0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000, // ICON_BOX_DOTS_BIG + 0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe, // ICON_BOX_CONCENTRIC + 0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000, // ICON_BOX_GRID_BIG + 0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000, // ICON_OK_TICK + 0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // ICON_CROSS + 0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // ICON_ARROW_LEFT + 0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // ICON_ARROW_RIGHT + 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // ICON_ARROW_DOWN + 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP + 0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // ICON_ARROW_LEFT_FILL + 0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // ICON_ARROW_RIGHT_FILL + 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // ICON_ARROW_DOWN_FILL + 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP_FILL + 0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // ICON_AUDIO + 0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // ICON_FX + 0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // ICON_WAVE + 0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000, // ICON_WAVE_SINUS + 0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000, // ICON_WAVE_SQUARE + 0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000, // ICON_WAVE_TRIANGULAR + 0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000, // ICON_CROSS_SMALL + 0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000, // ICON_PLAYER_PREVIOUS + 0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000, // ICON_PLAYER_PLAY_BACK + 0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000, // ICON_PLAYER_PLAY + 0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000, // ICON_PLAYER_PAUSE + 0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000, // ICON_PLAYER_STOP + 0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000, // ICON_PLAYER_NEXT + 0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000, // ICON_PLAYER_RECORD + 0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000, // ICON_MAGNET + 0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_CLOSE + 0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_OPEN + 0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770, // ICON_CLOCK + 0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70, // ICON_TOOLS + 0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180, // ICON_GEAR + 0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180, // ICON_GEAR_BIG + 0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8, // ICON_BIN + 0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000, // ICON_HAND_POINTER + 0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000, // ICON_LASER + 0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000, // ICON_COIN + 0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000, // ICON_EXPLOSION + 0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000, // ICON_1UP + 0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240, // ICON_PLAYER + 0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000, // ICON_PLAYER_JUMP + 0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0, // ICON_KEY + 0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0, // ICON_DEMON + 0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000, // ICON_TEXT_POPUP + 0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000, // ICON_GEAR_EX + 0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK + 0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK_POINTS + 0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808, // ICON_STAR + 0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8, // ICON_DOOR + 0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0, // ICON_EXIT + 0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000, // ICON_MODE_2D + 0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000, // ICON_MODE_3D + 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE + 0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_TOP + 0x7fe00000, 0x50386030, 0x47c2483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe, // ICON_CUBE_FACE_LEFT + 0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe, // ICON_CUBE_FACE_FRONT + 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3bf27be2, 0x0bfe1bfa, 0x000007fe, // ICON_CUBE_FACE_BOTTOM + 0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe, // ICON_CUBE_FACE_RIGHT + 0x7fe00000, 0x6fe85ff0, 0x781e77e4, 0x7be27be2, 0x7be27be2, 0x24127be2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_BACK + 0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000, // ICON_CAMERA + 0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000, // ICON_SPECIAL + 0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800, // ICON_LINK_NET + 0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00, // ICON_LINK_BOXES + 0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000, // ICON_LINK_MULTI + 0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00, // ICON_LINK + 0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00, // ICON_LINK_BROKE + 0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_TEXT_NOTES + 0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc, // ICON_NOTEBOOK + 0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000, // ICON_SUITCASE + 0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000, // ICON_SUITCASE_ZIP + 0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000, // ICON_MAILBOX + 0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000, // ICON_MONITOR + 0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000, // ICON_PRINTER + 0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA + 0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA_FLASH + 0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000, // ICON_HOUSE + 0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000, // ICON_HEART + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000, // ICON_CORNER + 0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000, // ICON_VERTICAL_BARS + 0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000, // ICON_VERTICAL_BARS_FILL + 0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000, // ICON_LIFE_BARS + 0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc, // ICON_INFO + 0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002, // ICON_CROSSLINE + 0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000, // ICON_HELP + 0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc, // ICON_FILETYPE_ALPHA + 0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc, // ICON_FILETYPE_HOME + 0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS_VISIBLE + 0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS + 0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_WINDOW + 0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000, // ICON_HIDPI + 0x3ff00000, 0x201c2010, 0x2a842e84, 0x2e842a84, 0x2ba42004, 0x2aa42aa4, 0x20042ba4, 0x00003ffc, // ICON_FILETYPE_BINARY + 0x00000000, 0x00000000, 0x00120012, 0x4a5e4bd2, 0x485233d2, 0x00004bd2, 0x00000000, 0x00000000, // ICON_HEX + 0x01800000, 0x381c0660, 0x23c42004, 0x23c42044, 0x13c82204, 0x08101008, 0x02400420, 0x00000180, // ICON_SHIELD + 0x007e0000, 0x20023fc2, 0x40227fe2, 0x400a403a, 0x400a400a, 0x400a400a, 0x4008400e, 0x00007ff8, // ICON_FILE_NEW + 0x00000000, 0x0042007e, 0x40027fc2, 0x44024002, 0x5f024402, 0x44024402, 0x7ffe4002, 0x00000000, // ICON_FOLDER_ADD + 0x44220000, 0x12482244, 0xf3cf0000, 0x14280420, 0x48122424, 0x08100810, 0x1ff81008, 0x03c00420, // ICON_ALARM + 0x0aa00000, 0x1ff80aa0, 0x1068700e, 0x1008706e, 0x1008700e, 0x1008700e, 0x0aa01ff8, 0x00000aa0, // ICON_CPU + 0x07e00000, 0x04201db8, 0x04a01c38, 0x04a01d38, 0x04a01d38, 0x04a01d38, 0x04201d38, 0x000007e0, // ICON_ROM + 0x00000000, 0x03c00000, 0x3c382ff0, 0x3c04380c, 0x01800000, 0x03c003c0, 0x00000180, 0x00000000, // ICON_STEP_OVER + 0x01800000, 0x01800180, 0x01800180, 0x03c007e0, 0x00000180, 0x01800000, 0x03c003c0, 0x00000180, // ICON_STEP_INTO + 0x01800000, 0x07e003c0, 0x01800180, 0x01800180, 0x00000180, 0x01800000, 0x03c003c0, 0x00000180, // ICON_STEP_OUT + 0x00000000, 0x0ff003c0, 0x181c1c34, 0x303c301c, 0x30003000, 0x1c301800, 0x03c00ff0, 0x00000000, // ICON_RESTART + 0x00000000, 0x00000000, 0x07e003c0, 0x0ff00ff0, 0x0ff00ff0, 0x03c007e0, 0x00000000, 0x00000000, // ICON_BREAKPOINT_ON + 0x00000000, 0x00000000, 0x042003c0, 0x08100810, 0x08100810, 0x03c00420, 0x00000000, 0x00000000, // ICON_BREAKPOINT_OFF + 0x00000000, 0x00000000, 0x1ff81ff8, 0x1ff80000, 0x00001ff8, 0x1ff81ff8, 0x00000000, 0x00000000, // ICON_BURGER_MENU + 0x00000000, 0x00000000, 0x00880070, 0x0c880088, 0x1e8810f8, 0x3e881288, 0x00000000, 0x00000000, // ICON_CASE_SENSITIVE + 0x00000000, 0x02000000, 0x07000a80, 0x07001fc0, 0x02000a80, 0x00300030, 0x00000000, 0x00000000, // ICON_REG_EXP + 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_FOLDER + 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x00003ffc, // ICON_FILE + 0x1ff00000, 0x20082008, 0x17d02fe8, 0x05400ba0, 0x09200540, 0x23881010, 0x2fe827c8, 0x00001ff0, // ICON_SAND_TIMER + 0x01800000, 0x02400240, 0x05a00420, 0x09900990, 0x11881188, 0x21842004, 0x40024182, 0x00003ffc, // ICON_WARNING + 0x7ffe0000, 0x4ff24002, 0x4c324ff2, 0x4f824c02, 0x41824f82, 0x41824002, 0x40024182, 0x00007ffe, // ICON_HELP_BOX + 0x7ffe0000, 0x41824002, 0x40024182, 0x41824182, 0x41824182, 0x41824182, 0x40024182, 0x00007ffe, // ICON_INFO_BOX + 0x01800000, 0x04200240, 0x10080810, 0x7bde2004, 0x0a500a50, 0x08500bd0, 0x08100850, 0x00000ff0, // ICON_PRIORITY + 0x01800000, 0x18180660, 0x80016006, 0x98196006, 0x99996666, 0x19986666, 0x01800660, 0x00000000, // ICON_LAYERS_ISO + 0x07fe0000, 0x1c020402, 0x74021402, 0x54025402, 0x54025402, 0x500857fe, 0x40205ff8, 0x00007fe0, // ICON_LAYERS2 + 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x422a422a, 0x422e422a, 0x40384e28, 0x00007fe0, // ICON_MLAYERS + 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x5b2a512a, 0x512e552a, 0x40385128, 0x00007fe0, // ICON_MAPS + 0x04200000, 0x1cf00c60, 0x11f019f0, 0x0f3807b8, 0x1e3c0f3c, 0x1c1c1e1c, 0x1e3c1c1c, 0x00000f70, // ICON_HOT + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_229 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_230 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_231 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_232 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_233 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_250 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_251 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_252 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_253 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_254 + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255 +}; + +// NOTE: A pointer to current icons array should be defined +static unsigned int *guiIconsPtr = guiIcons; + +#endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS + +#ifndef RAYGUI_ICON_SIZE + #define RAYGUI_ICON_SIZE 0 +#endif + +// WARNING: Those values define the total size of the style data array, +// if changed, previous saved styles could become incompatible +#define RAYGUI_MAX_CONTROLS 16 // Maximum number of controls +#define RAYGUI_MAX_PROPS_BASE 16 // Maximum number of base properties +#define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Gui control property style color element +typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static GuiState guiState = STATE_NORMAL; // Gui global state, if !STATE_NORMAL, forces defined state + +static Font guiFont = { 0 }; // Gui current font (WARNING: highly coupled to raylib) +static bool guiLocked = false; // Gui lock state (no inputs processed) +static float guiAlpha = 1.0f; // Gui controls transparency + +static unsigned int guiIconScale = 1; // Gui icon default scale (if icons enabled) + +static bool guiTooltip = false; // Tooltip enabled/disabled +static const char *guiTooltipPtr = NULL; // Tooltip string pointer (string provided by user) + +static bool guiControlExclusiveMode = false; // Gui control exclusive mode (no inputs processed except current control) +static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds rectangle, used as an unique identifier + +static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() +//static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking +static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down +static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement + +//---------------------------------------------------------------------------------- +// Style data array for all gui style properties (allocated on data segment by default) +// +// NOTE 1: First set of BASE properties are generic to all controls but could be individually +// overwritten per control, first set of EXTENDED properties are generic to all controls and +// can not be overwritten individually but custom EXTENDED properties can be used by control +// +// NOTE 2: A new style set could be loaded over this array using GuiLoadStyle(), +// but default gui style could always be recovered with GuiLoadStyleDefault() +// +// guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB +//---------------------------------------------------------------------------------- +static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 }; + +static bool guiStyleLoaded = false; // Style loaded flag for lazy style initialization + +//---------------------------------------------------------------------------------- +// Standalone Mode Functions Declaration +// +// NOTE: raygui depend on some raylib input and drawing functions +// To use raygui as standalone library, below functions must be defined by the user +//---------------------------------------------------------------------------------- +#if defined(RAYGUI_STANDALONE) + +#define KEY_RIGHT 262 +#define KEY_LEFT 263 +#define KEY_DOWN 264 +#define KEY_UP 265 +#define KEY_BACKSPACE 259 +#define KEY_ENTER 257 + +#define MOUSE_LEFT_BUTTON 0 + +// Input required functions +//------------------------------------------------------------------------------- +static Vector2 GetMousePosition(void); +static float GetMouseWheelMove(void); +static bool IsMouseButtonDown(int button); +static bool IsMouseButtonPressed(int button); +static bool IsMouseButtonReleased(int button); + +static bool IsKeyDown(int key); +static bool IsKeyPressed(int key); +static int GetCharPressed(void); // -- GuiTextBox(), GuiValueBox() +//------------------------------------------------------------------------------- + +// Drawing required functions +//------------------------------------------------------------------------------- +static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle() +static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker() +//------------------------------------------------------------------------------- + +// Text required functions +//------------------------------------------------------------------------------- +static Font GetFontDefault(void); // -- GuiLoadStyleDefault() +static Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // -- GuiLoadStyle(), load font + +static Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle(), required to load texture from embedded font atlas image +static void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle(), required to set shapes rec to font white rec (optimization) + +static char *LoadFileText(const char *fileName); // -- GuiLoadStyle(), required to load charset data +static void UnloadFileText(char *text); // -- GuiLoadStyle(), required to unload charset data + +static const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle(), required to find charset/font file from text .rgs + +static int *LoadCodepoints(const char *text, int *count); // -- GuiLoadStyle(), required to load required font codepoints list +static void UnloadCodepoints(int *codepoints); // -- GuiLoadStyle(), required to unload codepoints list + +static unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // -- GuiLoadStyle() +//------------------------------------------------------------------------------- + +// raylib functions already implemented in raygui +//------------------------------------------------------------------------------- +static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value +static int ColorToInt(Color color); // Returns hexadecimal value for a Color +static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle +static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' +static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +static int TextToInteger(const char *text); // Get integer value from text +static float TextToFloat(const char *text); // Get float value from text + +static int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded text +static const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode codepoint into UTF-8 text (char array size returned as parameter) + +static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2); // Draw rectangle vertical gradient +//------------------------------------------------------------------------------- + +#endif // RAYGUI_STANDALONE + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only) + +static int GetTextWidth(const char *text); // Gui get text width using gui font and style +static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds +static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor + +static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font +static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style + +static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings +static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB +static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV + +static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue); // Scroll bar control, used by GuiScrollPanel() +static void GuiTooltip(Rectangle controlRec); // Draw tooltip using control rec position + +static Color GuiFade(Color color, float alpha); // Fade color by an alpha factor + +//---------------------------------------------------------------------------------- +// Gui Setup Functions Definition +//---------------------------------------------------------------------------------- +// Enable gui global state +// NOTE: We check for STATE_DISABLED to avoid messing custom global state setups +void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; } + +// Disable gui global state +// NOTE: We check for STATE_NORMAL to avoid messing custom global state setups +void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; } + +// Lock gui global state +void GuiLock(void) { guiLocked = true; } + +// Unlock gui global state +void GuiUnlock(void) { guiLocked = false; } + +// Check if gui is locked (global state) +bool GuiIsLocked(void) { return guiLocked; } + +// Set gui controls alpha global state +void GuiSetAlpha(float alpha) +{ + if (alpha < 0.0f) alpha = 0.0f; + else if (alpha > 1.0f) alpha = 1.0f; + + guiAlpha = alpha; +} + +// Set gui state (global state) +void GuiSetState(int state) { guiState = (GuiState)state; } + +// Get gui state (global state) +int GuiGetState(void) { return guiState; } + +// Set custom gui font +// NOTE: Font loading/unloading is external to raygui +void GuiSetFont(Font font) +{ + if (font.texture.id > 0) + { + // NOTE: If we try to setup a font but default style has not been + // lazily loaded before, it will be overwritten, so we need to force + // default style loading first + if (!guiStyleLoaded) GuiLoadStyleDefault(); + + guiFont = font; + } +} + +// Get custom gui font +Font GuiGetFont(void) +{ + return guiFont; +} + +// Set control style property value +void GuiSetStyle(int control, int property, int value) +{ + if (!guiStyleLoaded) GuiLoadStyleDefault(); + guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value; + + // Default properties are propagated to all controls + if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE)) + { + for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value; + } +} + +// Get control style property value +int GuiGetStyle(int control, int property) +{ + if (!guiStyleLoaded) GuiLoadStyleDefault(); + return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property]; +} + +//---------------------------------------------------------------------------------- +// Gui Controls Functions Definition +//---------------------------------------------------------------------------------- + +// Window Box control +int GuiWindowBox(Rectangle bounds, const char *title) +{ + // Window title bar height (including borders) + // NOTE: This define is also used by GuiMessageBox() and GuiTextInputBox() + #if !defined(RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT) + #define RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT 24 + #endif + + int result = 0; + //GuiState state = guiState; + + int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT; + + Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight }; + if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f; + + Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - 1, bounds.width, bounds.height - (float)statusBarHeight + 1 }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - 20, + statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18 }; + + // Update control + //-------------------------------------------------------------------- + // NOTE: Logic is directly managed by button + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiStatusBar(statusBar, title); // Draw window header as status bar + GuiPanel(windowPanel, NULL); // Draw window base + + // Draw window close button + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); +#if defined(RAYGUI_NO_ICONS) + result = GuiButton(closeButtonRec, "x"); +#else + result = GuiButton(closeButtonRec, GuiIconText(ICON_CROSS_SMALL, NULL)); +#endif + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment); + //-------------------------------------------------------------------- + + return result; // Window close button clicked: result = 1 +} + +// Group Box control with text name +int GuiGroupBox(Rectangle bounds, const char *text) +{ + #if !defined(RAYGUI_GROUPBOX_LINE_THICK) + #define RAYGUI_GROUPBOX_LINE_THICK 1 + #endif + + int result = 0; + GuiState state = guiState; + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, RAYGUI_GROUPBOX_LINE_THICK }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR))); + + GuiLine(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, bounds.width, (float)GuiGetStyle(DEFAULT, TEXT_SIZE) }, text); + //-------------------------------------------------------------------- + + return result; +} + +// Line control +int GuiLine(Rectangle bounds, const char *text) +{ + #if !defined(RAYGUI_LINE_ORIGIN_SIZE) + #define RAYGUI_LINE_MARGIN_TEXT 12 + #endif + #if !defined(RAYGUI_LINE_TEXT_PADDING) + #define RAYGUI_LINE_TEXT_PADDING 4 + #endif + + int result = 0; + GuiState state = guiState; + + Color color = GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED : (int)LINE_COLOR)); + + // Draw control + //-------------------------------------------------------------------- + if (text == NULL) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, bounds.width, 1 }, 0, BLANK, color); + else + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.height = bounds.height; + textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT; + textBounds.y = bounds.y; + + // Draw line with embedded text label: "--- text --------------" + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color); + GuiDrawText(text, textBounds, TEXT_ALIGN_LEFT, color); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + 12 + textBounds.width + 4, bounds.y + bounds.height/2, bounds.width - textBounds.width - RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color); + } + //-------------------------------------------------------------------- + + return result; +} + +// Panel control +int GuiPanel(Rectangle bounds, const char *text) +{ + #if !defined(RAYGUI_PANEL_BORDER_WIDTH) + #define RAYGUI_PANEL_BORDER_WIDTH 1 + #endif + + int result = 0; + GuiState state = guiState; + + // Text will be drawn as a header bar (if provided) + Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }; + if ((text != NULL) && (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f)) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f; + + if (text != NULL) + { + // Move panel bounds after the header bar + bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1; + bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1; + } + + // Draw control + //-------------------------------------------------------------------- + if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar + + GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED: (int)LINE_COLOR)), + GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR))); + //-------------------------------------------------------------------- + + return result; +} + +// Tab Bar control +// NOTE: Using GuiToggle() for the TABS +int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) +{ + #define RAYGUI_TABBAR_ITEM_WIDTH 160 + + int result = -1; + //GuiState state = guiState; + + Rectangle tabBounds = { bounds.x, bounds.y, RAYGUI_TABBAR_ITEM_WIDTH, bounds.height }; + + if (*active < 0) *active = 0; + else if (*active > count - 1) *active = count - 1; + + int offsetX = 0; // Required in case tabs go out of screen + offsetX = (*active + 2)*RAYGUI_TABBAR_ITEM_WIDTH - GetScreenWidth(); + if (offsetX < 0) offsetX = 0; + + bool toggle = false; // Required for individual toggles + + // Draw control + //-------------------------------------------------------------------- + for (int i = 0; i < count; i++) + { + tabBounds.x = bounds.x + (RAYGUI_TABBAR_ITEM_WIDTH + 4)*i - offsetX; + + if (tabBounds.x < GetScreenWidth()) + { + // Draw tabs as toggle controls + int textAlignment = GuiGetStyle(TOGGLE, TEXT_ALIGNMENT); + int textPadding = GuiGetStyle(TOGGLE, TEXT_PADDING); + GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(TOGGLE, TEXT_PADDING, 8); + + if (i == (*active)) + { + toggle = true; + GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + } + else + { + toggle = false; + GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + if (toggle) *active = i; + } + + // Close tab with middle mouse button pressed + if (CheckCollisionPointRec(GetMousePosition(), tabBounds) && IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) result = i; + + GuiSetStyle(TOGGLE, TEXT_PADDING, textPadding); + GuiSetStyle(TOGGLE, TEXT_ALIGNMENT, textAlignment); + + // Draw tab close button + // NOTE: Only draw close button for current tab: if (CheckCollisionPointRec(mousePosition, tabBounds)) + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); +#if defined(RAYGUI_NO_ICONS) + if (GuiButton(RAYGUI_CLITERAL(Rectangle){ tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 }, "x")) result = i; +#else + if (GuiButton(RAYGUI_CLITERAL(Rectangle){ tabBounds.x + tabBounds.width - 14 - 5, tabBounds.y + 5, 14, 14 }, GuiIconText(ICON_CROSS_SMALL, NULL))) result = i; +#endif + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment); + } + } + + // Draw tab-bar bottom line + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, 1 }, 0, BLANK, GetColor(GuiGetStyle(TOGGLE, BORDER_COLOR_NORMAL))); + //-------------------------------------------------------------------- + + return result; // Return as result the current TAB closing requested +} + +// Scroll Panel control +int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view) +{ + #define RAYGUI_MIN_SCROLLBAR_WIDTH 40 + #define RAYGUI_MIN_SCROLLBAR_HEIGHT 40 + #define RAYGUI_MIN_MOUSE_WHEEL_SPEED 20 + + int result = 0; + GuiState state = guiState; + + Rectangle temp = { 0 }; + if (view == NULL) view = &temp; + + Vector2 scrollPos = { 0.0f, 0.0f }; + if (scroll != NULL) scrollPos = *scroll; + + // Text will be drawn as a header bar (if provided) + Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT }; + if (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f; + + if (text != NULL) + { + // Move panel bounds after the header bar + bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1; + bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + 1; + } + + bool hasHorizontalScrollBar = (content.width > bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false; + bool hasVerticalScrollBar = (content.height > bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false; + + // Recheck to account for the other scrollbar being visible + if (!hasHorizontalScrollBar) hasHorizontalScrollBar = (hasVerticalScrollBar && (content.width > (bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false; + if (!hasVerticalScrollBar) hasVerticalScrollBar = (hasHorizontalScrollBar && (content.height > (bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false; + + int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0; + int verticalScrollBarWidth = hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0; + Rectangle horizontalScrollBar = { + (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)horizontalScrollBarWidth + }; + Rectangle verticalScrollBar = { + (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)), + (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), + (float)verticalScrollBarWidth, + (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) + }; + + // Make sure scroll bars have a minimum width/height + if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH) horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH; + if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT) verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT; + + // Calculate view area (area without the scrollbars) + *view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? + RAYGUI_CLITERAL(Rectangle){ bounds.x + verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth } : + RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth }; + + // Clip view area to the actual content size + if (view->width > content.width) view->width = content.width; + if (view->height > content.height) view->height = content.height; + + float horizontalMin = hasHorizontalScrollBar? ((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH); + float horizontalMax = hasHorizontalScrollBar? content.width - bounds.width + (float)verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH) - (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)verticalScrollBarWidth : 0) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH); + float verticalMin = hasVerticalScrollBar? 0.0f : -1.0f; + float verticalMax = hasVerticalScrollBar? content.height - bounds.height + (float)horizontalScrollBarWidth + (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH); + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + +#if defined(SUPPORT_SCROLLBAR_KEY_INPUT) + if (hasHorizontalScrollBar) + { + if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + } + + if (hasVerticalScrollBar) + { + if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + } +#endif + float wheelMove = GetMouseWheelMove(); + + // Set scrolling speed with mouse wheel based on ratio between bounds and content + Vector2 mouseWheelSpeed = { content.width/bounds.width, content.height/bounds.height }; + if (mouseWheelSpeed.x < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.x = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + if (mouseWheelSpeed.y < RAYGUI_MIN_MOUSE_WHEEL_SPEED) mouseWheelSpeed.y = RAYGUI_MIN_MOUSE_WHEEL_SPEED; + + // Horizontal and vertical scrolling with mouse wheel + if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_LEFT_SHIFT))) scrollPos.x += wheelMove*mouseWheelSpeed.x; + else scrollPos.y += wheelMove*mouseWheelSpeed.y; // Vertical scroll + } + } + + // Normalize scroll values + if (scrollPos.x > -horizontalMin) scrollPos.x = -horizontalMin; + if (scrollPos.x < -horizontalMax) scrollPos.x = -horizontalMax; + if (scrollPos.y > -verticalMin) scrollPos.y = -verticalMin; + if (scrollPos.y < -verticalMax) scrollPos.y = -verticalMax; + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar + + GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background + + // Save size of the scrollbar slider + const int slider = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); + + // Draw horizontal scrollbar if visible + if (hasHorizontalScrollBar) + { + // Change scrollbar slider size to show the diff in size between the content width and the widget width + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)/(int)content.width)*((int)bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth))); + scrollPos.x = (float)-GuiScrollBar(horizontalScrollBar, (int)-scrollPos.x, (int)horizontalMin, (int)horizontalMax); + } + else scrollPos.x = 0.0f; + + // Draw vertical scrollbar if visible + if (hasVerticalScrollBar) + { + // Change scrollbar slider size to show the diff in size between the content height and the widget height + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)/(int)content.height)*((int)bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth))); + scrollPos.y = (float)-GuiScrollBar(verticalScrollBar, (int)-scrollPos.y, (int)verticalMin, (int)verticalMax); + } + else scrollPos.y = 0.0f; + + // Draw detail corner rectangle if both scroll bars are visible + if (hasHorizontalScrollBar && hasVerticalScrollBar) + { + Rectangle corner = { (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) + 2) : (horizontalScrollBar.x + horizontalScrollBar.width + 2), verticalScrollBar.y + verticalScrollBar.height + 2, (float)horizontalScrollBarWidth - 4, (float)verticalScrollBarWidth - 4 }; + GuiDrawRectangle(corner, 0, BLANK, GetColor(GuiGetStyle(LISTVIEW, TEXT + (state*3)))); + } + + // Draw scrollbar lines depending on current state + GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), BLANK); + + // Set scrollbar slider size back to the way it was before + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider); + //-------------------------------------------------------------------- + + if (scroll != NULL) *scroll = scrollPos; + + return result; +} + +// Label control +int GuiLabel(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Update control + //-------------------------------------------------------------------- + //... + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Button control, returns true when clicked +int GuiButton(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), GetColor(GuiGetStyle(BUTTON, BASE + (state*3)))); + GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), GetColor(GuiGetStyle(BUTTON, TEXT + (state*3)))); + + if (state == STATE_FOCUSED) GuiTooltip(bounds); + //------------------------------------------------------------------ + + return result; // Button pressed: result = 1 +} + +// Label button control +int GuiLabelButton(Rectangle bounds, const char *text) +{ + GuiState state = guiState; + bool pressed = false; + + // NOTE: We force bounds.width to be all text + float textWidth = (float)GetTextWidth(text); + if ((bounds.width - 2*GuiGetStyle(LABEL, BORDER_WIDTH) - 2*GuiGetStyle(LABEL, TEXT_PADDING)) < textWidth) bounds.width = textWidth + 2*GuiGetStyle(LABEL, BORDER_WIDTH) + 2*GuiGetStyle(LABEL, TEXT_PADDING) + 2; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + // Check checkbox state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return pressed; +} + +// Toggle Button control +int GuiToggle(Rectangle bounds, const char *text, bool *active) +{ + int result = 0; + GuiState state = guiState; + + bool temp = false; + if (active == NULL) active = &temp; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + // Check toggle button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + { + state = STATE_NORMAL; + *active = !(*active); + } + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_NORMAL) + { + GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, ((*active)? BORDER_COLOR_PRESSED : (BORDER + state*3)))), GetColor(GuiGetStyle(TOGGLE, ((*active)? BASE_COLOR_PRESSED : (BASE + state*3))))); + GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, ((*active)? TEXT_COLOR_PRESSED : (TEXT + state*3))))); + } + else + { + GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, BORDER + state*3)), GetColor(GuiGetStyle(TOGGLE, BASE + state*3))); + GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TOGGLE, TEXT + state*3))); + } + + if (state == STATE_FOCUSED) GuiTooltip(bounds); + //-------------------------------------------------------------------- + + return result; +} + +// Toggle Group control +int GuiToggleGroup(Rectangle bounds, const char *text, int *active) +{ + #if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS) + #define RAYGUI_TOGGLEGROUP_MAX_ITEMS 32 + #endif + + int result = 0; + float initBoundsX = bounds.x; + + int temp = 0; + if (active == NULL) active = &temp; + + bool toggle = false; // Required for individual toggles + + // Get substrings items from text (items pointers) + int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, rows); + + int prevRow = rows[0]; + + for (int i = 0; i < itemCount; i++) + { + if (prevRow != rows[i]) + { + bounds.x = initBoundsX; + bounds.y += (bounds.height + GuiGetStyle(TOGGLE, GROUP_PADDING)); + prevRow = rows[i]; + } + + if (i == (*active)) + { + toggle = true; + GuiToggle(bounds, items[i], &toggle); + } + else + { + toggle = false; + GuiToggle(bounds, items[i], &toggle); + if (toggle) *active = i; + } + + bounds.x += (bounds.width + GuiGetStyle(TOGGLE, GROUP_PADDING)); + } + + return result; +} + +// Toggle Slider control extended +int GuiToggleSlider(Rectangle bounds, const char *text, int *active) +{ + int result = 0; + GuiState state = guiState; + + int temp = 0; + if (active == NULL) active = &temp; + + //bool toggle = false; // Required for individual toggles + + // Get substrings items from text (items pointers) + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + + Rectangle slider = { + 0, // Calculated later depending on the active toggle + bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING), + (bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - (itemCount + 1)*GuiGetStyle(SLIDER, SLIDER_PADDING))/itemCount, + bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + { + state = STATE_PRESSED; + (*active)++; + result = 1; + } + else state = STATE_FOCUSED; + } + + if ((*active) && (state != STATE_FOCUSED)) state = STATE_PRESSED; + } + + if (*active >= itemCount) *active = 0; + slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH) + (*active + 1)*GuiGetStyle(SLIDER, SLIDER_PADDING) + (*active)*slider.width; + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), GetColor(GuiGetStyle(TOGGLE, BORDER + (state*3))), + GetColor(GuiGetStyle(TOGGLE, BASE_COLOR_NORMAL))); + + // Draw internal slider + if (state == STATE_NORMAL) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED))); + else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_FOCUSED))); + else if (state == STATE_PRESSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED))); + + // Draw text in slider + if (text != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GetTextWidth(text); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = slider.x + slider.width/2 - textBounds.width/2; + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(items[*active], textBounds, GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, TEXT + (state*3))), guiAlpha)); + } + //-------------------------------------------------------------------- + + return result; +} + +// Check Box control, returns 1 when state changed +int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) +{ + int result = 0; + GuiState state = guiState; + + bool temp = false; + if (checked == NULL) checked = &temp; + + Rectangle textBounds = { 0 }; + + if (text != NULL) + { + textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(CHECKBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + Rectangle totalBounds = { + (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x, + bounds.y, + bounds.width + textBounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING), + bounds.height, + }; + + // Check checkbox state + if (CheckCollisionPointRec(mousePoint, totalBounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + { + *checked = !(*checked); + result = 1; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(CHECKBOX, BORDER_WIDTH), GetColor(GuiGetStyle(CHECKBOX, BORDER + (state*3))), BLANK); + + if (*checked) + { + Rectangle check = { bounds.x + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING), + bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING), + bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)), + bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)) }; + GuiDrawRectangle(check, 0, BLANK, GetColor(GuiGetStyle(CHECKBOX, TEXT + state*3))); + } + + GuiDrawText(text, textBounds, (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Combo Box control +int GuiComboBox(Rectangle bounds, const char *text, int *active) +{ + int result = 0; + GuiState state = guiState; + + int temp = 0; + if (active == NULL) active = &temp; + + bounds.width -= (GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH) + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING)); + + Rectangle selector = { (float)bounds.x + bounds.width + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING), + (float)bounds.y, (float)GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH), (float)bounds.height }; + + // Get substrings items from text (items pointers, lengths and count) + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + + if (*active < 0) *active = 0; + else if (*active > (itemCount - 1)) *active = itemCount - 1; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1) && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + if (CheckCollisionPointRec(mousePoint, bounds) || + CheckCollisionPointRec(mousePoint, selector)) + { + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + *active += 1; + if (*active >= itemCount) *active = 0; // Cyclic combobox + } + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + // Draw combo box main + GuiDrawRectangle(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), GetColor(GuiGetStyle(COMBOBOX, BORDER + (state*3))), GetColor(GuiGetStyle(COMBOBOX, BASE + (state*3)))); + GuiDrawText(items[*active], GetTextBounds(COMBOBOX, bounds), GuiGetStyle(COMBOBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(COMBOBOX, TEXT + (state*3)))); + + // Draw selector using a custom button + // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 1); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + GuiButton(selector, TextFormat("%i/%i", *active + 1, itemCount)); + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign); + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + //-------------------------------------------------------------------- + + return result; +} + +// Dropdown Box control +// NOTE: Returns mouse click +int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode) +{ + int result = 0; + GuiState state = guiState; + + int temp = 0; + if (active == NULL) active = &temp; + + int itemSelected = *active; + int itemFocused = -1; + + int direction = 0; // Dropdown box open direction: down (default) + if (GuiGetStyle(DROPDOWNBOX, DROPDOWN_ROLL_UP) == 1) direction = 1; // Up + + // Get substrings items from text (items pointers, lengths and count) + int itemCount = 0; + const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + + Rectangle boundsOpen = bounds; + boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + if (direction == 1) boundsOpen.y -= itemCount*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)) + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING); + + Rectangle itemBounds = bounds; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1) && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + if (editMode) + { + state = STATE_PRESSED; + + // Check if mouse has been pressed or released outside limits + if (!CheckCollisionPointRec(mousePoint, boundsOpen)) + { + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) result = 1; + } + + // Check if already selected item has been pressed again + if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + + // Check focused and selected item + for (int i = 0; i < itemCount; i++) + { + // Update item rectangle y position for next item + if (direction == 0) itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + else itemBounds.y -= (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + + if (CheckCollisionPointRec(mousePoint, itemBounds)) + { + itemFocused = i; + if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) + { + itemSelected = i; + result = 1; // Item selected + } + break; + } + } + + itemBounds = bounds; + } + else + { + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + result = 1; + state = STATE_PRESSED; + } + else state = STATE_FOCUSED; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (editMode) GuiPanel(boundsOpen, NULL); + + GuiDrawRectangle(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER + state*3)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE + state*3))); + GuiDrawText(items[itemSelected], GetTextBounds(DROPDOWNBOX, bounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + state*3))); + + if (editMode) + { + // Draw visible items + for (int i = 0; i < itemCount; i++) + { + // Update item rectangle y position for next item + if (direction == 0) itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + else itemBounds.y -= (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); + + if (i == itemSelected) + { + GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_PRESSED))); + GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_PRESSED))); + } + else if (i == itemFocused) + { + GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_FOCUSED))); + GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_FOCUSED))); + } + else GuiDrawText(items[i], GetTextBounds(DROPDOWNBOX, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_NORMAL))); + } + } + + if (!GuiGetStyle(DROPDOWNBOX, DROPDOWN_ARROW_HIDDEN)) + { + // Draw arrows (using icon if available) +#if defined(RAYGUI_NO_ICONS) + GuiDrawText("v", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10 }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); +#else + GuiDrawText(direction? "#121#" : "#120#", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 6, 10, 10 }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); // ICON_ARROW_DOWN_FILL +#endif + } + //-------------------------------------------------------------------- + + *active = itemSelected; + + // TODO: Use result to return more internal states: mouse-press out-of-bounds, mouse-press over selected-item... + return result; // Mouse click: result = 1 +} + +// Text Box control +// NOTE: Returns true on ENTER pressed (useful for data validation) +int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) +{ + #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) + #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement + #endif + #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) + #define RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY 1 // Frames delay for autocursor movement + #endif + + int result = 0; + GuiState state = guiState; + + bool multiline = false; // TODO: Consider multiline text input + int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); + + Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); + int textLength = (int)strlen(text); // Get current text length + int thisCursorIndex = textBoxCursorIndex; + if (thisCursorIndex > textLength) thisCursorIndex = textLength; + int textWidth = GetTextWidth(text) - GetTextWidth(text + thisCursorIndex); + int textIndexOffset = 0; // Text index offset to start drawing in the box + + // Cursor rectangle + // NOTE: Position X value should be updated + Rectangle cursor = { + textBounds.x + textWidth + GuiGetStyle(DEFAULT, TEXT_SPACING), + textBounds.y + textBounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE), + 2, + (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2 + }; + + if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2; + if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH); + + // Mouse cursor rectangle + // NOTE: Initialized outside of screen + Rectangle mouseCursor = cursor; + mouseCursor.x = -1; + mouseCursor.width = 1; + + // Auto-cursor movement logic + // NOTE: Cursor moves automatically when key down after some time + if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCooldownCounter++; + else + { + autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter + autoCursorDelayCounter = 0; // GLOBAL: Cursor delay counter + } + + // Blink-cursor frame counter + //if (!autoCursorMode) blinkCursorFrameCounter++; + //else blinkCursorFrameCounter = 0; + + // Update control + //-------------------------------------------------------------------- + // WARNING: Text editing is only supported under certain conditions: + if ((state != STATE_DISABLED) && // Control not disabled + !GuiGetStyle(TEXTBOX, TEXT_READONLY) && // TextBox not on read-only mode + !guiLocked && // Gui not locked + !guiControlExclusiveMode && // No gui slider on dragging + (wrapMode == TEXT_WRAP_NONE)) // No wrap mode + { + Vector2 mousePosition = GetMousePosition(); + + if (editMode) + { + state = STATE_PRESSED; + + if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; + + // If text does not fit in the textbox and current cursor position is out of bounds, + // we add an index offset to text for drawing only what requires depending on cursor + while (textWidth >= textBounds.width) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textIndexOffset, &nextCodepointSize); + + textIndexOffset += nextCodepointSize; + + textWidth = GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex); + } + + int codepoint = GetCharPressed(); // Get Unicode codepoint + if (multiline && IsKeyPressed(KEY_ENTER)) codepoint = (int)'\n'; + + // Encode codepoint as UTF-8 + int codepointSize = 0; + const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); + + // Add codepoint to text, at current cursor position + // NOTE: Make sure we do not overflow buffer size + if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) + { + // Move forward data from cursor position + for (int i = (textLength + codepointSize); i > textBoxCursorIndex; i--) text[i] = text[i - codepointSize]; + + // Add new codepoint in current cursor position + for (int i = 0; i < codepointSize; i++) text[textBoxCursorIndex + i] = charEncoded[i]; + + textBoxCursorIndex += codepointSize; + textLength += codepointSize; + + // Make sure text last character is EOL + text[textLength] = '\0'; + } + + // Move cursor to start + if ((textLength > 0) && IsKeyPressed(KEY_HOME)) textBoxCursorIndex = 0; + + // Move cursor to end + if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; + + // Delete codepoint from text, after current cursor position + if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + { + autoCursorDelayCounter++; + + if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + // Move backward text from cursor position + for (int i = textBoxCursorIndex; i < textLength; i++) text[i] = text[i + nextCodepointSize]; + + textLength -= codepointSize; + if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; + + // Make sure text last character is EOL + text[textLength] = '\0'; + } + } + + // Delete related codepoints from text, before current cursor position + if ((textLength > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + { + int i = textBoxCursorIndex - 1; + int accCodepointSize = 0; + + // Move cursor to the end of word if on space already + while ((i > 0) && isspace(text[i])) + { + int prevCodepointSize = 0; + GetCodepointPrevious(text + i, &prevCodepointSize); + i -= prevCodepointSize; + accCodepointSize += prevCodepointSize; + } + + // Move cursor to the start of the word + while ((i > 0) && !isspace(text[i])) + { + int prevCodepointSize = 0; + GetCodepointPrevious(text + i, &prevCodepointSize); + i -= prevCodepointSize; + accCodepointSize += prevCodepointSize; + } + + // Move forward text from cursor position + for (int j = (textBoxCursorIndex - accCodepointSize); j < textLength; j++) text[j] = text[j + accCodepointSize]; + + // Prevent cursor index from decrementing past 0 + if (textBoxCursorIndex > 0) + { + textBoxCursorIndex -= accCodepointSize; + textLength -= accCodepointSize; + } + + // Make sure text last character is EOL + text[textLength] = '\0'; + } + else if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + { + autoCursorDelayCounter++; + + if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + { + int prevCodepointSize = 0; + + // Prevent cursor index from decrementing past 0 + if (textBoxCursorIndex > 0) + { + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + + // Move backward text from cursor position + for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize]; + + textBoxCursorIndex -= codepointSize; + textLength -= codepointSize; + } + + // Make sure text last character is EOL + text[textLength] = '\0'; + } + } + + // Move cursor position with keys + if (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + { + autoCursorDelayCounter++; + + if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + { + int prevCodepointSize = 0; + if (textBoxCursorIndex > 0) GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + + if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize; + } + } + else if (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + { + autoCursorDelayCounter++; + + if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + if ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize; + } + } + + // Move cursor position with mouse + if (CheckCollisionPointRec(mousePosition, textBounds)) // Mouse hover text + { + float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize; + int codepointIndex = 0; + float glyphWidth = 0.0f; + float widthToMouseX = 0; + int mouseCursorIndex = 0; + + for (int i = textIndexOffset; i < textLength; i++) + { + codepoint = GetCodepointNext(&text[i], &codepointSize); + codepointIndex = GetGlyphIndex(guiFont, codepoint); + + if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); + else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); + + if (mousePosition.x <= (textBounds.x + (widthToMouseX + glyphWidth/2))) + { + mouseCursor.x = textBounds.x + widthToMouseX; + mouseCursorIndex = i; + break; + } + + widthToMouseX += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + + // Check if mouse cursor is at the last position + int textEndWidth = GetTextWidth(text + textIndexOffset); + if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) + { + mouseCursor.x = textBounds.x + textEndWidth; + mouseCursorIndex = textLength; + } + + // Place cursor at required index on mouse click + if ((mouseCursor.x >= 0) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + cursor.x = mouseCursor.x; + textBoxCursorIndex = mouseCursorIndex; + } + } + else mouseCursor.x = -1; + + // Recalculate cursor position.y depending on textBoxCursorIndex + cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING); + //if (multiline) cursor.y = GetTextLines() + + // Finish text editing on ENTER or mouse click outside bounds + if ((!multiline && IsKeyPressed(KEY_ENTER)) || + (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + { + textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index + result = 1; + } + } + else + { + if (CheckCollisionPointRec(mousePosition, bounds)) + { + state = STATE_FOCUSED; + + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text + result = 1; + } + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_PRESSED) + { + GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED))); + } + else if (state == STATE_DISABLED) + { + GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED))); + } + else GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), BLANK); + + // Draw text considering index offset if required + // NOTE: Text index offset depends on cursor position + GuiDrawText(text + textIndexOffset, textBounds, GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3)))); + + // Draw cursor + if (editMode && !GuiGetStyle(TEXTBOX, TEXT_READONLY)) + { + //if (autoCursorMode || ((blinkCursorFrameCounter/40)%2 == 0)) + GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED))); + + // Draw mouse position cursor (if required) + if (mouseCursor.x >= 0) GuiDrawRectangle(mouseCursor, 0, BLANK, GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED))); + } + else if (state == STATE_FOCUSED) GuiTooltip(bounds); + //-------------------------------------------------------------------- + + return result; // Mouse button pressed: result = 1 +} + +/* +// Text Box control with multiple lines and word-wrap +// NOTE: This text-box is readonly, no editing supported by default +bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode) +{ + bool pressed = false; + + GuiSetStyle(TEXTBOX, TEXT_READONLY, 1); + GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // WARNING: If wrap mode enabled, text editing is not supported + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_TOP); + + // TODO: Implement methods to calculate cursor position properly + pressed = GuiTextBox(bounds, text, textSize, editMode); + + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); + GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE); + GuiSetStyle(TEXTBOX, TEXT_READONLY, 0); + + return pressed; +} +*/ + +// Spinner control, returns selected value +int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode) +{ + int result = 1; + GuiState state = guiState; + + int tempValue = *value; + + Rectangle spinner = { bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING), bounds.y, + bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING)), bounds.height }; + Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; + Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; + + Rectangle textBounds = { 0 }; + if (text != NULL) + { + textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + // Check spinner state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + } + } + +#if defined(RAYGUI_NO_ICONS) + if (GuiButton(leftButtonBound, "<")) tempValue--; + if (GuiButton(rightButtonBound, ">")) tempValue++; +#else + if (GuiButton(leftButtonBound, GuiIconText(ICON_ARROW_LEFT_FILL, NULL))) tempValue--; + if (GuiButton(rightButtonBound, GuiIconText(ICON_ARROW_RIGHT_FILL, NULL))) tempValue++; +#endif + + if (!editMode) + { + if (tempValue < minValue) tempValue = minValue; + if (tempValue > maxValue) tempValue = maxValue; + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + result = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode); + + // Draw value selector custom buttons + // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values + int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH); + int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, BORDER_WIDTH, GuiGetStyle(SPINNER, BORDER_WIDTH)); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign); + GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth); + + // Draw text label if provided + GuiDrawText(text, textBounds, (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + *value = tempValue; + return result; +} + +// Value Box control, updates input text with numbers +// NOTE: Requires static variables: frameCounter +int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode) +{ + #if !defined(RAYGUI_VALUEBOX_MAX_CHARS) + #define RAYGUI_VALUEBOX_MAX_CHARS 32 + #endif + + int result = 0; + GuiState state = guiState; + + char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; + sprintf(textValue, "%i", *value); + + Rectangle textBounds = { 0 }; + if (text != NULL) + { + textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + bool valueHasChanged = false; + + if (editMode) + { + state = STATE_PRESSED; + + int keyCount = (int)strlen(textValue); + + // Only allow keys in range [48..57] + if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + { + if (GetTextWidth(textValue) < bounds.width) + { + int key = GetCharPressed(); + if ((key >= 48) && (key <= 57)) + { + textValue[keyCount] = (char)key; + keyCount++; + valueHasChanged = true; + } + } + } + + // Delete text + if (keyCount > 0) + { + if (IsKeyPressed(KEY_BACKSPACE)) + { + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; + } + } + + if (valueHasChanged) *value = TextToInteger(textValue); + + // NOTE: We are not clamp values until user input finishes + //if (*value > maxValue) *value = maxValue; + //else if (*value < minValue) *value = minValue; + + if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) + { + if (*value > maxValue) *value = maxValue; + else if (*value < minValue) *value = minValue; + + result = 1; + } + } + else + { + if (*value > maxValue) *value = maxValue; + else if (*value < minValue) *value = minValue; + + if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + Color baseColor = BLANK; + if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED)); + else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED)); + + GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), baseColor); + GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3)))); + + // Draw cursor + if (editMode) + { + // NOTE: ValueBox internal text is always centered + Rectangle cursor = { bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) }; + GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED))); + } + + // Draw text label if provided + GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Floating point Value Box control, updates input val_str with numbers +// NOTE: Requires static variables: frameCounter +int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float *value, bool editMode) +{ + #if !defined(RAYGUI_VALUEBOX_MAX_CHARS) + #define RAYGUI_VALUEBOX_MAX_CHARS 32 + #endif + + int result = 0; + GuiState state = guiState; + + //char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; + //sprintf(textValue, "%2.2f", *value); + + Rectangle textBounds = {0}; + if (text != NULL) + { + textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + bool valueHasChanged = false; + + if (editMode) + { + state = STATE_PRESSED; + + int keyCount = (int)strlen(textValue); + + // Only allow keys in range [48..57] + if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + { + if (GetTextWidth(textValue) < bounds.width) + { + int key = GetCharPressed(); + if (((key >= 48) && (key <= 57)) || + (key == '.') || + ((keyCount == 0) && (key == '+')) || // NOTE: Sign can only be in first position + ((keyCount == 0) && (key == '-'))) + { + textValue[keyCount] = (char)key; + keyCount++; + + valueHasChanged = true; + } + } + } + + // Pressed backspace + if (IsKeyPressed(KEY_BACKSPACE)) + { + if (keyCount > 0) + { + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; + } + } + + if (valueHasChanged) *value = TextToFloat(textValue); + + if ((IsKeyPressed(KEY_ENTER) || IsKeyPressed(KEY_KP_ENTER)) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) result = 1; + } + else + { + if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) result = 1; + } + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + Color baseColor = BLANK; + if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED)); + else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED)); + + GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), baseColor); + GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3)))); + + // Draw cursor + if (editMode) + { + // NOTE: ValueBox internal text is always centered + Rectangle cursor = {bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, + bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, + bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH)}; + GuiDrawRectangle(cursor, 0, BLANK, GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED))); + } + + // Draw text label if provided + GuiDrawText(text, textBounds, + (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, + GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Slider control with pro parameters +// NOTE: Other GuiSlider*() controls use this one +int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth) +{ + int result = 0; + GuiState state = guiState; + + float temp = (maxValue - minValue)/2.0f; + if (value == NULL) value = &temp; + float oldValue = *value; + + Rectangle slider = { bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING), + 0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + // Get equivalent value and slider position from mousePosition.x + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width-sliderWidth)) + minValue; + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + if (!CheckCollisionPointRec(mousePoint, slider)) + { + // Get equivalent value and slider position from mousePosition.x + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width-sliderWidth)) + minValue; + } + } + else state = STATE_FOCUSED; + } + + if (*value > maxValue) *value = maxValue; + else if (*value < minValue) *value = minValue; + } + + // Control value change check + if (oldValue == *value) result = 0; + else result = 1; + + // Slider bar limits check + float sliderValue = (((*value - minValue)/(maxValue - minValue))*(bounds.width - sliderWidth - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))); + if (sliderWidth > 0) // Slider + { + slider.x += sliderValue; + slider.width = (float)sliderWidth; + if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH); + else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH); + } + else if (sliderWidth == 0) // SliderBar + { + slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH); + slider.width = sliderValue; + if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH); + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), GetColor(GuiGetStyle(SLIDER, BORDER + (state*3))), GetColor(GuiGetStyle(SLIDER, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED))); + + // Draw slider internal bar (depends on state) + if (state == STATE_NORMAL) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED))); + else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_FOCUSED))); + else if (state == STATE_PRESSED) GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_PRESSED))); + + // Draw left/right text if provided + if (textLeft != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GetTextWidth(textLeft); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SLIDER, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(SLIDER, TEXT + (state*3)))); + } + + if (textRight != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GetTextWidth(textRight); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(SLIDER, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(SLIDER, TEXT + (state*3)))); + } + //-------------------------------------------------------------------- + + return result; +} + +// Slider control extended, returns selected value and has text +int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) +{ + return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH)); +} + +// Slider Bar control extended, returns selected value +int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) +{ + return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0); +} + +// Progress Bar control extended, shows current progress value +int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) +{ + int result = 0; + GuiState state = guiState; + + float temp = (maxValue - minValue)/2.0f; + if (value == NULL) value = &temp; + + // Progress bar + Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), + bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0, + bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) }; + + // Update control + //-------------------------------------------------------------------- + if (*value > maxValue) *value = maxValue; + + // WARNING: Working with floats could lead to rounding issues + if ((state != STATE_DISABLED)) progress.width = (float)(*value/(maxValue - minValue))*bounds.width - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f); + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_DISABLED) + { + GuiDrawRectangle(bounds, GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), GetColor(GuiGetStyle(PROGRESSBAR, BORDER + (state*3))), BLANK); + } + else + { + if (*value > minValue) + { + // Draw progress bar with colored border, more visual + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + } + else GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + + if (*value >= maxValue) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + progress.width + 1, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + else + { + // Draw borders not yet reached by value + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y + bounds.height - 1, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + } + + // Draw slider internal progress bar (depends on state) + GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED))); + } + + // Draw left/right text if provided + if (textLeft != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GetTextWidth(textLeft); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x - textBounds.width - GuiGetStyle(PROGRESSBAR, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3)))); + } + + if (textRight != NULL) + { + Rectangle textBounds = { 0 }; + textBounds.width = (float)GetTextWidth(textRight); + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(PROGRESSBAR, TEXT_PADDING); + textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3)))); + } + //-------------------------------------------------------------------- + + return result; +} + +// Status Bar control +int GuiStatusBar(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(STATUSBAR, BORDER_WIDTH), GetColor(GuiGetStyle(STATUSBAR, BORDER + (state*3))), GetColor(GuiGetStyle(STATUSBAR, BASE + (state*3)))); + GuiDrawText(text, GetTextBounds(STATUSBAR, bounds), GuiGetStyle(STATUSBAR, TEXT_ALIGNMENT), GetColor(GuiGetStyle(STATUSBAR, TEXT + (state*3)))); + //-------------------------------------------------------------------- + + return result; +} + +// Dummy rectangle control, intended for placeholding +int GuiDummyRec(Rectangle bounds, const char *text) +{ + int result = 0; + GuiState state = guiState; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + // Check button state + if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED; + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED))); + GuiDrawText(text, GetTextBounds(DEFAULT, bounds), TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(BUTTON, (state != STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED))); + //------------------------------------------------------------------ + + return result; +} + +// List View control +int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active) +{ + int result = 0; + int itemCount = 0; + const char **items = NULL; + + if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); + + result = GuiListViewEx(bounds, items, itemCount, scrollIndex, active, NULL); + + return result; +} + +// List View control with extended parameters +int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) +{ + int result = 0; + GuiState state = guiState; + + int itemFocused = (focus == NULL)? -1 : *focus; + int itemSelected = (active == NULL)? -1 : *active; + + // Check if we need a scroll bar + bool useScrollBar = false; + if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true; + + // Define base item rectangle [0] + Rectangle itemBounds = { 0 }; + itemBounds.x = bounds.x + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING); + itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH); + itemBounds.width = bounds.width - 2*GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) - GuiGetStyle(DEFAULT, BORDER_WIDTH); + itemBounds.height = (float)GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT); + if (useScrollBar) itemBounds.width -= GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH); + + // Get items on the list + int visibleItems = (int)bounds.height/(GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING)); + if (visibleItems > count) visibleItems = count; + + int startIndex = (scrollIndex == NULL)? 0 : *scrollIndex; + if ((startIndex < 0) || (startIndex > (count - visibleItems))) startIndex = 0; + int endIndex = startIndex + visibleItems; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + Vector2 mousePoint = GetMousePosition(); + + // Check mouse inside list view + if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + + // Check focused and selected item + for (int i = 0; i < visibleItems; i++) + { + if (CheckCollisionPointRec(mousePoint, itemBounds)) + { + itemFocused = startIndex + i; + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + if (itemSelected == (startIndex + i)) itemSelected = -1; + else itemSelected = startIndex + i; + } + break; + } + + // Update item rectangle y position for next item + itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING)); + } + + if (useScrollBar) + { + int wheelMove = (int)GetMouseWheelMove(); + startIndex -= wheelMove; + + if (startIndex < 0) startIndex = 0; + else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems; + + endIndex = startIndex + visibleItems; + if (endIndex > count) endIndex = count; + } + } + else itemFocused = -1; + + // Reset item rectangle y to [0] + itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH); + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background + + // Draw visible items + for (int i = 0; ((i < visibleItems) && (text != NULL)); i++) + { + GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), BLANK); + + if (state == STATE_DISABLED) + { + if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED))); + + GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); + } + else + { + if (((startIndex + i) == itemSelected) && (active != NULL)) + { + // Draw item selected + GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED))); + } + else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! + { + // Draw item focused + GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); + GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED))); + } + else + { + // Draw item normal + GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); + } + } + + // Update item rectangle y position for next item + itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING)); + } + + if (useScrollBar) + { + Rectangle scrollBarBounds = { + bounds.x + bounds.width - GuiGetStyle(LISTVIEW, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH), + bounds.y + GuiGetStyle(LISTVIEW, BORDER_WIDTH), (float)GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH), + bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) + }; + + // Calculate percentage of visible items and apply same percentage to scrollbar + float percentVisible = (float)(endIndex - startIndex)/count; + float sliderSize = bounds.height*percentVisible; + + int prevSliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); // Save default slider size + int prevScrollSpeed = GuiGetStyle(SCROLLBAR, SCROLL_SPEED); // Save default scroll speed + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)sliderSize); // Change slider size + GuiSetStyle(SCROLLBAR, SCROLL_SPEED, count - visibleItems); // Change scroll speed + + startIndex = GuiScrollBar(scrollBarBounds, startIndex, 0, count - visibleItems); + + GuiSetStyle(SCROLLBAR, SCROLL_SPEED, prevScrollSpeed); // Reset scroll speed to default + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, prevSliderSize); // Reset slider size to default + } + //-------------------------------------------------------------------- + + if (active != NULL) *active = itemSelected; + if (focus != NULL) *focus = itemFocused; + if (scrollIndex != NULL) *scrollIndex = startIndex; + + return result; +} + +// Color Panel control - Color (RGBA) variant. +int GuiColorPanel(Rectangle bounds, const char *text, Color *color) +{ + int result = 0; + + Vector3 vcolor = { (float)color->r/255.0f, (float)color->g/255.0f, (float)color->b/255.0f }; + Vector3 hsv = ConvertRGBtoHSV(vcolor); + Vector3 prevHsv = hsv; // workaround to see if GuiColorPanelHSV modifies the hsv. + + GuiColorPanelHSV(bounds, text, &hsv); + + // Check if the hsv was changed, only then change the color. + // This is required, because the Color->HSV->Color conversion has precision errors. + // Thus the assignment from HSV to Color should only be made, if the HSV has a new user-entered value. + // Otherwise GuiColorPanel would often modify it's color without user input. + // TODO: GuiColorPanelHSV could return 1 if the slider was dragged, to simplify this check. + if (hsv.x != prevHsv.x || hsv.y != prevHsv.y || hsv.z != prevHsv.z) + { + Vector3 rgb = ConvertHSVtoRGB(hsv); + + // NOTE: Vector3ToColor() only available on raylib 1.8.1 + *color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x), + (unsigned char)(255.0f*rgb.y), + (unsigned char)(255.0f*rgb.z), + color->a }; + } + return result; +} + +// Color Bar Alpha control +// NOTE: Returns alpha value normalized [0..1] +int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) +{ + #if !defined(RAYGUI_COLORBARALPHA_CHECKED_SIZE) + #define RAYGUI_COLORBARALPHA_CHECKED_SIZE 10 + #endif + + int result = 0; + GuiState state = guiState; + Rectangle selector = { (float)bounds.x + (*alpha)*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), (float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2 }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + + *alpha = (mousePoint.x - bounds.x)/bounds.width; + if (*alpha <= 0.0f) *alpha = 0.0f; + if (*alpha >= 1.0f) *alpha = 1.0f; + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + *alpha = (mousePoint.x - bounds.x)/bounds.width; + if (*alpha <= 0.0f) *alpha = 0.0f; + if (*alpha >= 1.0f) *alpha = 1.0f; + //selector.x = bounds.x + (int)(((alpha - 0)/(100 - 0))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))) - selector.width/2; + } + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + + // Draw alpha bar: checked background + if (state != STATE_DISABLED) + { + int checksX = (int)bounds.width/RAYGUI_COLORBARALPHA_CHECKED_SIZE; + int checksY = (int)bounds.height/RAYGUI_COLORBARALPHA_CHECKED_SIZE; + + for (int x = 0; x < checksX; x++) + { + for (int y = 0; y < checksY; y++) + { + Rectangle check = { bounds.x + x*RAYGUI_COLORBARALPHA_CHECKED_SIZE, bounds.y + y*RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE }; + GuiDrawRectangle(check, 0, BLANK, ((x + y)%2)? Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.4f) : Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.4f)); + } + } + + DrawRectangleGradientEx(bounds, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha)); + } + else DrawRectangleGradientEx(bounds, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha)); + + GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK); + + // Draw alpha bar: selector + GuiDrawRectangle(selector, 0, BLANK, GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3))); + //-------------------------------------------------------------------- + + return result; +} + +// Color Bar Hue control +// Returns hue value normalized [0..1] +// NOTE: Other similar bars (for reference): +// Color GuiColorBarSat() [WHITE->color] +// Color GuiColorBarValue() [BLACK->color], HSV/HSL +// float GuiColorBarLuminance() [BLACK->WHITE] +int GuiColorBarHue(Rectangle bounds, const char *text, float *hue) +{ + int result = 0; + GuiState state = guiState; + Rectangle selector = { (float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y + (*hue)/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT) }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + + *hue = (mousePoint.y - bounds.y)*360/bounds.height; + if (*hue <= 0.0f) *hue = 0.0f; + if (*hue >= 359.0f) *hue = 359.0f; + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds) || CheckCollisionPointRec(mousePoint, selector)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + *hue = (mousePoint.y - bounds.y)*360/bounds.height; + if (*hue <= 0.0f) *hue = 0.0f; + if (*hue >= 359.0f) *hue = 359.0f; + + } + else state = STATE_FOCUSED; + + /*if (IsKeyDown(KEY_UP)) + { + hue -= 2.0f; + if (hue <= 0.0f) hue = 0.0f; + } + else if (IsKeyDown(KEY_DOWN)) + { + hue += 2.0f; + if (hue >= 360.0f) hue = 360.0f; + }*/ + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state != STATE_DISABLED) + { + // Draw hue bar:color bars + // TODO: Use directly DrawRectangleGradientEx(bounds, color1, color2, color2, color1); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + bounds.height/6), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 2*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 3*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 4*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha)); + DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 5*(bounds.height/6)), (int)bounds.width, (int)(bounds.height/6), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 255, 0, 0, 255 }, guiAlpha)); + } + else DrawRectangleGradientV((int)bounds.x, (int)bounds.y, (int)bounds.width, (int)bounds.height, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha)); + + GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK); + + // Draw hue bar: selector + GuiDrawRectangle(selector, 0, BLANK, GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3))); + //-------------------------------------------------------------------- + + return result; +} + +// Color Picker control +// NOTE: It's divided in multiple controls: +// Color GuiColorPanel(Rectangle bounds, Color color) +// float GuiColorBarAlpha(Rectangle bounds, float alpha) +// float GuiColorBarHue(Rectangle bounds, float value) +// NOTE: bounds define GuiColorPanel() size +// NOTE: this picker converts RGB to HSV, which can cause the Hue control to jump. If you have this problem, consider using the HSV variant instead +int GuiColorPicker(Rectangle bounds, const char *text, Color *color) +{ + int result = 0; + + Color temp = { 200, 0, 0, 255 }; + if (color == NULL) color = &temp; + + GuiColorPanel(bounds, NULL, color); + + Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height }; + //Rectangle boundsAlpha = { bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK) }; + + // NOTE: this conversion can cause low hue-resolution, if the r, g and b value are very similar, which causes the hue bar to shift around when only the GuiColorPanel is used. + Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ (*color).r/255.0f, (*color).g/255.0f, (*color).b/255.0f }); + + GuiColorBarHue(boundsHue, NULL, &hsv.x); + + //color.a = (unsigned char)(GuiColorBarAlpha(boundsAlpha, (float)color.a/255.0f)*255.0f); + Vector3 rgb = ConvertHSVtoRGB(hsv); + + *color = RAYGUI_CLITERAL(Color){ (unsigned char)roundf(rgb.x*255.0f), (unsigned char)roundf(rgb.y*255.0f), (unsigned char)roundf(rgb.z*255.0f), (*color).a }; + + return result; +} + +// Color Picker control that avoids conversion to RGB and back to HSV on each call, thus avoiding jittering. +// The user can call ConvertHSVtoRGB() to convert *colorHsv value to RGB. +// NOTE: It's divided in multiple controls: +// int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) +// int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) +// float GuiColorBarHue(Rectangle bounds, float value) +// NOTE: bounds define GuiColorPanelHSV() size +int GuiColorPickerHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) +{ + int result = 0; + + Vector3 tempHsv = { 0 }; + + if (colorHsv == NULL) + { + const Vector3 tempColor = { 200.0f/255.0f, 0.0f, 0.0f }; + tempHsv = ConvertRGBtoHSV(tempColor); + colorHsv = &tempHsv; + } + + GuiColorPanelHSV(bounds, NULL, colorHsv); + + const Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height }; + + GuiColorBarHue(boundsHue, NULL, &colorHsv->x); + + return result; +} + +// Color Panel control - HSV variant +int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv) +{ + int result = 0; + GuiState state = guiState; + Vector2 pickerSelector = { 0 }; + + const Color colWhite = { 255, 255, 255, 255 }; + const Color colBlack = { 0, 0, 0, 255 }; + + pickerSelector.x = bounds.x + (float)colorHsv->y*bounds.width; // HSV: Saturation + pickerSelector.y = bounds.y + (1.0f - (float)colorHsv->z)*bounds.height; // HSV: Value + + Vector3 maxHue = { colorHsv->x, 1.0f, 1.0f }; + Vector3 rgbHue = ConvertHSVtoRGB(maxHue); + Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x), + (unsigned char)(255.0f*rgbHue.y), + (unsigned char)(255.0f*rgbHue.z), 255 }; + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + pickerSelector = mousePoint; + + if (pickerSelector.x < bounds.x) pickerSelector.x = bounds.x; + if (pickerSelector.x > bounds.x + bounds.width) pickerSelector.x = bounds.x + bounds.width; + if (pickerSelector.y < bounds.y) pickerSelector.y = bounds.y; + if (pickerSelector.y > bounds.y + bounds.height) pickerSelector.y = bounds.y + bounds.height; + + // Calculate color from picker + Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y }; + + colorPick.x /= (float)bounds.width; // Get normalized value on x + colorPick.y /= (float)bounds.height; // Get normalized value on y + + colorHsv->y = colorPick.x; + colorHsv->z = 1.0f - colorPick.y; + + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds)) + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + state = STATE_PRESSED; + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; + pickerSelector = mousePoint; + + // Calculate color from picker + Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y }; + + colorPick.x /= (float)bounds.width; // Get normalized value on x + colorPick.y /= (float)bounds.height; // Get normalized value on y + + colorHsv->y = colorPick.x; + colorHsv->z = 1.0f - colorPick.y; + } + else state = STATE_FOCUSED; + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state != STATE_DISABLED) + { + DrawRectangleGradientEx(bounds, Fade(colWhite, guiAlpha), Fade(colWhite, guiAlpha), Fade(maxHueCol, guiAlpha), Fade(maxHueCol, guiAlpha)); + DrawRectangleGradientEx(bounds, Fade(colBlack, 0), Fade(colBlack, guiAlpha), Fade(colBlack, guiAlpha), Fade(colBlack, 0)); + + // Draw color picker: selector + Rectangle selector = { pickerSelector.x - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, pickerSelector.y - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE), (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE) }; + GuiDrawRectangle(selector, 0, BLANK, colWhite); + } + else + { + DrawRectangleGradientEx(bounds, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.6f), guiAlpha)); + } + + GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), BLANK); + //-------------------------------------------------------------------- + + return result; +} + +// Message Box control +int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons) +{ + #if !defined(RAYGUI_MESSAGEBOX_BUTTON_HEIGHT) + #define RAYGUI_MESSAGEBOX_BUTTON_HEIGHT 24 + #endif + #if !defined(RAYGUI_MESSAGEBOX_BUTTON_PADDING) + #define RAYGUI_MESSAGEBOX_BUTTON_PADDING 12 + #endif + + int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button + + int buttonCount = 0; + const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + Rectangle buttonBounds = { 0 }; + buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; + buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; + buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; + buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; + + //int textWidth = GetTextWidth(message) + 2; + + Rectangle textBounds = { 0 }; + textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; + textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING; + textBounds.width = bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*2; + textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; + + // Draw control + //-------------------------------------------------------------------- + if (GuiWindowBox(bounds, title)) result = 0; + + int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(textBounds, message); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); + + prevTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + for (int i = 0; i < buttonCount; i++) + { + if (GuiButton(buttonBounds, buttonsText[i])) result = i + 1; + buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING); + } + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevTextAlignment); + //-------------------------------------------------------------------- + + return result; +} + +// Text Input Box control, ask for text +int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive) +{ + #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT) + #define RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT 24 + #endif + #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_PADDING) + #define RAYGUI_TEXTINPUTBOX_BUTTON_PADDING 12 + #endif + #if !defined(RAYGUI_TEXTINPUTBOX_HEIGHT) + #define RAYGUI_TEXTINPUTBOX_HEIGHT 26 + #endif + + // Used to enable text edit mode + // WARNING: No more than one GuiTextInputBox() should be open at the same time + static bool textEditMode = false; + + int result = -1; + + int buttonCount = 0; + const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); + Rectangle buttonBounds = { 0 }; + buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + buttonBounds.width = (bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; + buttonBounds.height = RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT; + + int messageInputHeight = (int)bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - 2*RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + + Rectangle textBounds = { 0 }; + if (message != NULL) + { + int textSize = GetTextWidth(message) + 2; + + textBounds.x = bounds.x + bounds.width/2 - textSize/2; + textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/2; + textBounds.width = (float)textSize; + textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + } + + Rectangle textBoxBounds = { 0 }; + textBoxBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + textBoxBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_TEXTINPUTBOX_HEIGHT/2; + if (message == NULL) textBoxBounds.y = bounds.y + 24 + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; + else textBoxBounds.y += (messageInputHeight/2 + messageInputHeight/4); + textBoxBounds.width = bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*2; + textBoxBounds.height = RAYGUI_TEXTINPUTBOX_HEIGHT; + + // Draw control + //-------------------------------------------------------------------- + if (GuiWindowBox(bounds, title)) result = 0; + + // Draw message if available + if (message != NULL) + { + int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(textBounds, message); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment); + } + + if (secretViewActive != NULL) + { + static char stars[] = "****************"; + if (GuiTextBox(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x, textBoxBounds.y, textBoxBounds.width - 4 - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.height }, + ((*secretViewActive == 1) || textEditMode)? text : stars, textMaxSize, textEditMode)) textEditMode = !textEditMode; + + GuiToggle(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x + textBoxBounds.width - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.y, RAYGUI_TEXTINPUTBOX_HEIGHT, RAYGUI_TEXTINPUTBOX_HEIGHT }, (*secretViewActive == 1)? "#44#" : "#45#", secretViewActive); + } + else + { + if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode; + } + + int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT); + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + for (int i = 0; i < buttonCount; i++) + { + if (GuiButton(buttonBounds, buttonsText[i])) result = i + 1; + buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING); + } + + if (result >= 0) textEditMode = false; + + GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment); + //-------------------------------------------------------------------- + + return result; // Result is the pressed button index +} + +// Grid control +// NOTE: Returns grid mouse-hover selected cell +// About drawing lines at subpixel spacing, simple put, not easy solution: +// https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster +int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vector2 *mouseCell) +{ + // Grid lines alpha amount + #if !defined(RAYGUI_GRID_ALPHA) + #define RAYGUI_GRID_ALPHA 0.15f + #endif + + int result = 0; + GuiState state = guiState; + + Vector2 mousePoint = GetMousePosition(); + Vector2 currentMouseCell = { -1, -1 }; + + float spaceWidth = spacing/(float)subdivs; + int linesV = (int)(bounds.width/spaceWidth) + 1; + int linesH = (int)(bounds.height/spaceWidth) + 1; + + int color = GuiGetStyle(DEFAULT, LINE_COLOR); + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) + { + if (CheckCollisionPointRec(mousePoint, bounds)) + { + // NOTE: Cell values must be the upper left of the cell the mouse is in + currentMouseCell.x = floorf((mousePoint.x - bounds.x)/spacing); + currentMouseCell.y = floorf((mousePoint.y - bounds.y)/spacing); + } + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + if (state == STATE_DISABLED) color = GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED); + + if (subdivs > 0) + { + // Draw vertical grid lines + for (int i = 0; i < linesV; i++) + { + Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height + 1 }; + GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA)); + } + + // Draw horizontal grid lines + for (int i = 0; i < linesH; i++) + { + Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width + 1, 1 }; + GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA)); + } + } + + if (mouseCell != NULL) *mouseCell = currentMouseCell; + return result; +} + +//---------------------------------------------------------------------------------- +// Tooltip management functions +// NOTE: Tooltips requires some global variables: tooltipPtr +//---------------------------------------------------------------------------------- +// Enable gui tooltips (global state) +void GuiEnableTooltip(void) { guiTooltip = true; } + +// Disable gui tooltips (global state) +void GuiDisableTooltip(void) { guiTooltip = false; } + +// Set tooltip string +void GuiSetTooltip(const char *tooltip) { guiTooltipPtr = tooltip; } + +//---------------------------------------------------------------------------------- +// Styles loading functions +//---------------------------------------------------------------------------------- + +// Load raygui style file (.rgs) +// NOTE: By default a binary file is expected, that file could contain a custom font, +// in that case, custom font image atlas is GRAY+ALPHA and pixel data can be compressed (DEFLATE) +void GuiLoadStyle(const char *fileName) +{ + #define MAX_LINE_BUFFER_SIZE 256 + + bool tryBinary = false; + if (!guiStyleLoaded) GuiLoadStyleDefault(); + + // Try reading the files as text file first + FILE *rgsFile = fopen(fileName, "rt"); + + if (rgsFile != NULL) + { + char buffer[MAX_LINE_BUFFER_SIZE] = { 0 }; + fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile); + + if (buffer[0] == '#') + { + int controlId = 0; + int propertyId = 0; + unsigned int propertyValue = 0; + + while (!feof(rgsFile)) + { + switch (buffer[0]) + { + case 'p': + { + // Style property: p + + sscanf(buffer, "p %d %d 0x%x", &controlId, &propertyId, &propertyValue); + GuiSetStyle(controlId, propertyId, (int)propertyValue); + + } break; + case 'f': + { + // Style font: f + + int fontSize = 0; + char charmapFileName[256] = { 0 }; + char fontFileName[256] = { 0 }; + sscanf(buffer, "f %d %s %[^\r\n]s", &fontSize, charmapFileName, fontFileName); + + Font font = { 0 }; + int *codepoints = NULL; + int codepointCount = 0; + + if (charmapFileName[0] != '0') + { + // Load text data from file + // NOTE: Expected an UTF-8 array of codepoints, no separation + char *textData = LoadFileText(TextFormat("%s/%s", GetDirectoryPath(fileName), charmapFileName)); + codepoints = LoadCodepoints(textData, &codepointCount); + UnloadFileText(textData); + } + + if (fontFileName[0] != '\0') + { + // In case a font is already loaded and it is not default internal font, unload it + if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture); + + if (codepointCount > 0) font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, codepoints, codepointCount); + else font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, NULL, 0); // Default to 95 standard codepoints + } + + // If font texture not properly loaded, revert to default font and size/spacing + if (font.texture.id == 0) + { + font = GetFontDefault(); + GuiSetStyle(DEFAULT, TEXT_SIZE, 10); + GuiSetStyle(DEFAULT, TEXT_SPACING, 1); + } + + UnloadCodepoints(codepoints); + + if ((font.texture.id > 0) && (font.glyphCount > 0)) GuiSetFont(font); + + } break; + default: break; + } + + fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile); + } + } + else tryBinary = true; + + fclose(rgsFile); + } + + if (tryBinary) + { + rgsFile = fopen(fileName, "rb"); + + if (rgsFile != NULL) + { + fseek(rgsFile, 0, SEEK_END); + int fileDataSize = ftell(rgsFile); + fseek(rgsFile, 0, SEEK_SET); + + if (fileDataSize > 0) + { + unsigned char *fileData = (unsigned char *)RAYGUI_MALLOC(fileDataSize*sizeof(unsigned char)); + fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); + + GuiLoadStyleFromMemory(fileData, fileDataSize); + + RAYGUI_FREE(fileData); + } + + fclose(rgsFile); + } + } +} + +// Load style default over global style +void GuiLoadStyleDefault(void) +{ + // We set this variable first to avoid cyclic function calls + // when calling GuiSetStyle() and GuiGetStyle() + guiStyleLoaded = true; + + // Initialize default LIGHT style property values + // WARNING: Default value are applied to all controls on set but + // they can be overwritten later on for every custom control + GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x838383ff); + GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0xc9c9c9ff); + GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0x686868ff); + GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x5bb2d9ff); + GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0xc9effeff); + GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0x6c9bbcff); + GuiSetStyle(DEFAULT, BORDER_COLOR_PRESSED, 0x0492c7ff); + GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x97e8ffff); + GuiSetStyle(DEFAULT, TEXT_COLOR_PRESSED, 0x368bafff); + GuiSetStyle(DEFAULT, BORDER_COLOR_DISABLED, 0xb5c1c2ff); + GuiSetStyle(DEFAULT, BASE_COLOR_DISABLED, 0xe6e9e9ff); + GuiSetStyle(DEFAULT, TEXT_COLOR_DISABLED, 0xaeb7b8ff); + GuiSetStyle(DEFAULT, BORDER_WIDTH, 1); + GuiSetStyle(DEFAULT, TEXT_PADDING, 0); + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + + // Initialize default extended property values + // NOTE: By default, extended property values are initialized to 0 + GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls + GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls + GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property + GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property + GuiSetStyle(DEFAULT, TEXT_LINE_SPACING, 15); // DEFAULT, 15 pixels between lines + GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE); // DEFAULT, text aligned vertically to middle of text-bounds + + // Initialize control-specific property values + // NOTE: Those properties are in default list but require specific values by control type + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(BUTTON, BORDER_WIDTH, 2); + GuiSetStyle(SLIDER, TEXT_PADDING, 4); + GuiSetStyle(PROGRESSBAR, TEXT_PADDING, 4); + GuiSetStyle(CHECKBOX, TEXT_PADDING, 4); + GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_RIGHT); + GuiSetStyle(DROPDOWNBOX, TEXT_PADDING, 0); + GuiSetStyle(DROPDOWNBOX, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiSetStyle(TEXTBOX, TEXT_PADDING, 4); + GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(VALUEBOX, TEXT_PADDING, 0); + GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(SPINNER, TEXT_PADDING, 0); + GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + GuiSetStyle(STATUSBAR, TEXT_PADDING, 8); + GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); + + // Initialize extended property values + // NOTE: By default, extended property values are initialized to 0 + GuiSetStyle(TOGGLE, GROUP_PADDING, 2); + GuiSetStyle(SLIDER, SLIDER_WIDTH, 16); + GuiSetStyle(SLIDER, SLIDER_PADDING, 1); + GuiSetStyle(PROGRESSBAR, PROGRESS_PADDING, 1); + GuiSetStyle(CHECKBOX, CHECK_PADDING, 1); + GuiSetStyle(COMBOBOX, COMBO_BUTTON_WIDTH, 32); + GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2); + GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16); + GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2); + GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24); + GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2); + GuiSetStyle(SCROLLBAR, BORDER_WIDTH, 0); + GuiSetStyle(SCROLLBAR, ARROWS_VISIBLE, 0); + GuiSetStyle(SCROLLBAR, ARROWS_SIZE, 6); + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING, 0); + GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, 16); + GuiSetStyle(SCROLLBAR, SCROLL_PADDING, 0); + GuiSetStyle(SCROLLBAR, SCROLL_SPEED, 12); + GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 28); + GuiSetStyle(LISTVIEW, LIST_ITEMS_SPACING, 2); + GuiSetStyle(LISTVIEW, SCROLLBAR_WIDTH, 12); + GuiSetStyle(LISTVIEW, SCROLLBAR_SIDE, SCROLLBAR_RIGHT_SIDE); + GuiSetStyle(COLORPICKER, COLOR_SELECTOR_SIZE, 8); + GuiSetStyle(COLORPICKER, HUEBAR_WIDTH, 16); + GuiSetStyle(COLORPICKER, HUEBAR_PADDING, 8); + GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT, 8); + GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW, 2); + + if (guiFont.texture.id != GetFontDefault().texture.id) + { + // Unload previous font texture + UnloadTexture(guiFont.texture); + RL_FREE(guiFont.recs); + RL_FREE(guiFont.glyphs); + guiFont.recs = NULL; + guiFont.glyphs = NULL; + + // Setup default raylib font + guiFont = GetFontDefault(); + + // NOTE: Default raylib font character 95 is a white square + Rectangle whiteChar = guiFont.recs[95]; + + // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering + SetShapesTexture(guiFont.texture, RAYGUI_CLITERAL(Rectangle){ whiteChar.x + 1, whiteChar.y + 1, whiteChar.width - 2, whiteChar.height - 2 }); + } +} + +// Get text with icon id prepended +// NOTE: Useful to add icons by name id (enum) instead of +// a number that can change between ricon versions +const char *GuiIconText(int iconId, const char *text) +{ +#if defined(RAYGUI_NO_ICONS) + return NULL; +#else + static char buffer[1024] = { 0 }; + static char iconBuffer[16] = { 0 }; + + if (text != NULL) + { + memset(buffer, 0, 1024); + sprintf(buffer, "#%03i#", iconId); + + for (int i = 5; i < 1024; i++) + { + buffer[i] = text[i - 5]; + if (text[i - 5] == '\0') break; + } + + return buffer; + } + else + { + sprintf(iconBuffer, "#%03i#", iconId); + + return iconBuffer; + } +#endif +} + +#if !defined(RAYGUI_NO_ICONS) +// Get full icons data pointer +unsigned int *GuiGetIcons(void) { return guiIconsPtr; } + +// Load raygui icons file (.rgi) +// NOTE: In case nameIds are required, they can be requested with loadIconsName, +// they are returned as a guiIconsName[iconCount][RAYGUI_ICON_MAX_NAME_LENGTH], +// WARNING: guiIconsName[]][] memory should be manually freed! +char **GuiLoadIcons(const char *fileName, bool loadIconsName) +{ + // Style File Structure (.rgi) + // ------------------------------------------------------ + // Offset | Size | Type | Description + // ------------------------------------------------------ + // 0 | 4 | char | Signature: "rGI " + // 4 | 2 | short | Version: 100 + // 6 | 2 | short | reserved + + // 8 | 2 | short | Num icons (N) + // 10 | 2 | short | Icons size (Options: 16, 32, 64) (S) + + // Icons name id (32 bytes per name id) + // foreach (icon) + // { + // 12+32*i | 32 | char | Icon NameId + // } + + // Icons data: One bit per pixel, stored as unsigned int array (depends on icon size) + // S*S pixels/32bit per unsigned int = K unsigned int per icon + // foreach (icon) + // { + // ... | K | unsigned int | Icon Data + // } + + FILE *rgiFile = fopen(fileName, "rb"); + + char **guiIconsName = NULL; + + if (rgiFile != NULL) + { + char signature[5] = { 0 }; + short version = 0; + short reserved = 0; + short iconCount = 0; + short iconSize = 0; + + fread(signature, 1, 4, rgiFile); + fread(&version, sizeof(short), 1, rgiFile); + fread(&reserved, sizeof(short), 1, rgiFile); + fread(&iconCount, sizeof(short), 1, rgiFile); + fread(&iconSize, sizeof(short), 1, rgiFile); + + if ((signature[0] == 'r') && + (signature[1] == 'G') && + (signature[2] == 'I') && + (signature[3] == ' ')) + { + if (loadIconsName) + { + guiIconsName = (char **)RAYGUI_MALLOC(iconCount*sizeof(char **)); + for (int i = 0; i < iconCount; i++) + { + guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH); + fread(guiIconsName[i], 1, RAYGUI_ICON_MAX_NAME_LENGTH, rgiFile); + } + } + else fseek(rgiFile, iconCount*RAYGUI_ICON_MAX_NAME_LENGTH, SEEK_CUR); + + // Read icons data directly over internal icons array + fread(guiIconsPtr, sizeof(unsigned int), iconCount*(iconSize*iconSize/32), rgiFile); + } + + fclose(rgiFile); + } + + return guiIconsName; +} + +// Draw selected icon using rectangles pixel-by-pixel +void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color) +{ + #define BIT_CHECK(a,b) ((a) & (1u<<(b))) + + for (int i = 0, y = 0; i < RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32; i++) + { + for (int k = 0; k < 32; k++) + { + if (BIT_CHECK(guiIconsPtr[iconId*RAYGUI_ICON_DATA_ELEMENTS + i], k)) + { + #if !defined(RAYGUI_STANDALONE) + GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ (float)posX + (k%RAYGUI_ICON_SIZE)*pixelSize, (float)posY + y*pixelSize, (float)pixelSize, (float)pixelSize }, 0, BLANK, color); + #endif + } + + if ((k == 15) || (k == 31)) y++; + } + } +} + +// Set icon drawing size +void GuiSetIconScale(int scale) +{ + if (scale >= 1) guiIconScale = scale; +} + +#endif // !RAYGUI_NO_ICONS + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- + +// Load style from memory +// WARNING: Binary files only +static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) +{ + unsigned char *fileDataPtr = (unsigned char *)fileData; + + char signature[5] = { 0 }; + short version = 0; + short reserved = 0; + int propertyCount = 0; + + memcpy(signature, fileDataPtr, 4); + memcpy(&version, fileDataPtr + 4, sizeof(short)); + memcpy(&reserved, fileDataPtr + 4 + 2, sizeof(short)); + memcpy(&propertyCount, fileDataPtr + 4 + 2 + 2, sizeof(int)); + fileDataPtr += 12; + + if ((signature[0] == 'r') && + (signature[1] == 'G') && + (signature[2] == 'S') && + (signature[3] == ' ')) + { + short controlId = 0; + short propertyId = 0; + unsigned int propertyValue = 0; + + for (int i = 0; i < propertyCount; i++) + { + memcpy(&controlId, fileDataPtr, sizeof(short)); + memcpy(&propertyId, fileDataPtr + 2, sizeof(short)); + memcpy(&propertyValue, fileDataPtr + 2 + 2, sizeof(unsigned int)); + fileDataPtr += 8; + + if (controlId == 0) // DEFAULT control + { + // If a DEFAULT property is loaded, it is propagated to all controls + // NOTE: All DEFAULT properties should be defined first in the file + GuiSetStyle(0, (int)propertyId, propertyValue); + + if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int j = 1; j < RAYGUI_MAX_CONTROLS; j++) GuiSetStyle(j, (int)propertyId, propertyValue); + } + else GuiSetStyle((int)controlId, (int)propertyId, propertyValue); + } + + // Font loading is highly dependant on raylib API to load font data and image + +#if !defined(RAYGUI_STANDALONE) + // Load custom font if available + int fontDataSize = 0; + memcpy(&fontDataSize, fileDataPtr, sizeof(int)); + fileDataPtr += 4; + + if (fontDataSize > 0) + { + Font font = { 0 }; + int fontType = 0; // 0-Normal, 1-SDF + + memcpy(&font.baseSize, fileDataPtr, sizeof(int)); + memcpy(&font.glyphCount, fileDataPtr + 4, sizeof(int)); + memcpy(&fontType, fileDataPtr + 4 + 4, sizeof(int)); + fileDataPtr += 12; + + // Load font white rectangle + Rectangle fontWhiteRec = { 0 }; + memcpy(&fontWhiteRec, fileDataPtr, sizeof(Rectangle)); + fileDataPtr += 16; + + // Load font image parameters + int fontImageUncompSize = 0; + int fontImageCompSize = 0; + memcpy(&fontImageUncompSize, fileDataPtr, sizeof(int)); + memcpy(&fontImageCompSize, fileDataPtr + 4, sizeof(int)); + fileDataPtr += 8; + + Image imFont = { 0 }; + imFont.mipmaps = 1; + memcpy(&imFont.width, fileDataPtr, sizeof(int)); + memcpy(&imFont.height, fileDataPtr + 4, sizeof(int)); + memcpy(&imFont.format, fileDataPtr + 4 + 4, sizeof(int)); + fileDataPtr += 12; + + if ((fontImageCompSize > 0) && (fontImageCompSize != fontImageUncompSize)) + { + // Compressed font atlas image data (DEFLATE), it requires DecompressData() + int dataUncompSize = 0; + unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize); + memcpy(compData, fileDataPtr, fontImageCompSize); + fileDataPtr += fontImageCompSize; + + imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize); + + // Security check, dataUncompSize must match the provided fontImageUncompSize + if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted"); + + RAYGUI_FREE(compData); + } + else + { + // Font atlas image data is not compressed + imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize); + memcpy(imFont.data, fileDataPtr, fontImageUncompSize); + fileDataPtr += fontImageUncompSize; + } + + if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture); + font.texture = LoadTextureFromImage(imFont); + + RAYGUI_FREE(imFont.data); + + // Validate font atlas texture was loaded correctly + if (font.texture.id != 0) + { + // Load font recs data + int recsDataSize = font.glyphCount*sizeof(Rectangle); + int recsDataCompressedSize = 0; + + // WARNING: Version 400 adds the compression size parameter + if (version >= 400) + { + // RGS files version 400 support compressed recs data + memcpy(&recsDataCompressedSize, fileDataPtr, sizeof(int)); + fileDataPtr += sizeof(int); + } + + if ((recsDataCompressedSize > 0) && (recsDataCompressedSize != recsDataSize)) + { + // Recs data is compressed, uncompress it + unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_MALLOC(recsDataCompressedSize); + + memcpy(recsDataCompressed, fileDataPtr, recsDataCompressedSize); + fileDataPtr += recsDataCompressedSize; + + int recsDataUncompSize = 0; + font.recs = (Rectangle *)DecompressData(recsDataCompressed, recsDataCompressedSize, &recsDataUncompSize); + + // Security check, data uncompressed size must match the expected original data size + if (recsDataUncompSize != recsDataSize) RAYGUI_LOG("WARNING: Uncompressed font recs data could be corrupted"); + + RAYGUI_FREE(recsDataCompressed); + } + else + { + // Recs data is uncompressed + font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle)); + for (int i = 0; i < font.glyphCount; i++) + { + memcpy(&font.recs[i], fileDataPtr, sizeof(Rectangle)); + fileDataPtr += sizeof(Rectangle); + } + } + + // Load font glyphs info data + int glyphsDataSize = font.glyphCount*16; // 16 bytes data per glyph + int glyphsDataCompressedSize = 0; + + // WARNING: Version 400 adds the compression size parameter + if (version >= 400) + { + // RGS files version 400 support compressed glyphs data + memcpy(&glyphsDataCompressedSize, fileDataPtr, sizeof(int)); + fileDataPtr += sizeof(int); + } + + // Allocate required glyphs space to fill with data + font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo)); + + if ((glyphsDataCompressedSize > 0) && (glyphsDataCompressedSize != glyphsDataSize)) + { + // Glyphs data is compressed, uncompress it + unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_MALLOC(glyphsDataCompressedSize); + + memcpy(glypsDataCompressed, fileDataPtr, glyphsDataCompressedSize); + fileDataPtr += glyphsDataCompressedSize; + + int glyphsDataUncompSize = 0; + unsigned char *glyphsDataUncomp = DecompressData(glypsDataCompressed, glyphsDataCompressedSize, &glyphsDataUncompSize); + + // Security check, data uncompressed size must match the expected original data size + if (glyphsDataUncompSize != glyphsDataSize) RAYGUI_LOG("WARNING: Uncompressed font glyphs data could be corrupted"); + + unsigned char *glyphsDataUncompPtr = glyphsDataUncomp; + + for (int i = 0; i < font.glyphCount; i++) + { + memcpy(&font.glyphs[i].value, glyphsDataUncompPtr, sizeof(int)); + memcpy(&font.glyphs[i].offsetX, glyphsDataUncompPtr + 4, sizeof(int)); + memcpy(&font.glyphs[i].offsetY, glyphsDataUncompPtr + 8, sizeof(int)); + memcpy(&font.glyphs[i].advanceX, glyphsDataUncompPtr + 12, sizeof(int)); + glyphsDataUncompPtr += 16; + } + + RAYGUI_FREE(glypsDataCompressed); + RAYGUI_FREE(glyphsDataUncomp); + } + else + { + // Glyphs data is uncompressed + for (int i = 0; i < font.glyphCount; i++) + { + memcpy(&font.glyphs[i].value, fileDataPtr, sizeof(int)); + memcpy(&font.glyphs[i].offsetX, fileDataPtr + 4, sizeof(int)); + memcpy(&font.glyphs[i].offsetY, fileDataPtr + 8, sizeof(int)); + memcpy(&font.glyphs[i].advanceX, fileDataPtr + 12, sizeof(int)); + fileDataPtr += 16; + } + } + } + else font = GetFontDefault(); // Fallback in case of errors loading font atlas texture + + GuiSetFont(font); + + // Set font texture source rectangle to be used as white texture to draw shapes + // NOTE: It makes possible to draw shapes and text (full UI) in a single draw call + if ((fontWhiteRec.x > 0) && + (fontWhiteRec.y > 0) && + (fontWhiteRec.width > 0) && + (fontWhiteRec.height > 0)) SetShapesTexture(font.texture, fontWhiteRec); + } +#endif + } +} + +// Gui get text width considering icon +static int GetTextWidth(const char *text) +{ + #if !defined(ICON_TEXT_PADDING) + #define ICON_TEXT_PADDING 4 + #endif + + Vector2 textSize = { 0 }; + int textIconOffset = 0; + + if ((text != NULL) && (text[0] != '\0')) + { + if (text[0] == '#') + { + for (int i = 1; (i < 5) && (text[i] != '\0'); i++) + { + if (text[i] == '#') + { + textIconOffset = i; + break; + } + } + } + + text += textIconOffset; + + // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly + float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); + + // Custom MeasureText() implementation + if ((guiFont.texture.id > 0) && (text != NULL)) + { + // Get size in bytes of text, considering end of line and line break + int size = 0; + for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++) + { + if ((text[i] != '\0') && (text[i] != '\n')) size++; + else break; + } + + float scaleFactor = fontSize/(float)guiFont.baseSize; + textSize.y = (float)guiFont.baseSize*scaleFactor; + float glyphWidth = 0.0f; + + for (int i = 0, codepointSize = 0; i < size; i += codepointSize) + { + int codepoint = GetCodepointNext(&text[i], &codepointSize); + int codepointIndex = GetGlyphIndex(guiFont, codepoint); + + if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); + else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); + + textSize.x += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + } + + if (textIconOffset > 0) textSize.x += (RAYGUI_ICON_SIZE + ICON_TEXT_PADDING); + } + + return (int)textSize.x; +} + +// Get text bounds considering control bounds +static Rectangle GetTextBounds(int control, Rectangle bounds) +{ + Rectangle textBounds = bounds; + + textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH); + textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH) + GuiGetStyle(control, TEXT_PADDING); + textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING); + textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING); // NOTE: Text is processed line per line! + + // Depending on control, TEXT_PADDING and TEXT_ALIGNMENT properties could affect the text-bounds + switch (control) + { + case COMBOBOX: + case DROPDOWNBOX: + case LISTVIEW: + // TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW + case SLIDER: + case CHECKBOX: + case VALUEBOX: + case SPINNER: + // TODO: More special cases (label on side): SLIDER, CHECKBOX, VALUEBOX, SPINNER + default: + { + // TODO: WARNING: TEXT_ALIGNMENT is already considered in GuiDrawText() + if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING); + else textBounds.x += GuiGetStyle(control, TEXT_PADDING); + } + break; + } + + return textBounds; +} + +// Get text icon if provided and move text cursor +// NOTE: We support up to 999 values for iconId +static const char *GetTextIcon(const char *text, int *iconId) +{ +#if !defined(RAYGUI_NO_ICONS) + *iconId = -1; + if (text[0] == '#') // Maybe we have an icon! + { + char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0' + + int pos = 1; + while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9')) + { + iconValue[pos - 1] = text[pos]; + pos++; + } + + if (text[pos] == '#') + { + *iconId = TextToInteger(iconValue); + + // Move text pointer after icon + // WARNING: If only icon provided, it could point to EOL character: '\0' + if (*iconId >= 0) text += (pos + 1); + } + } +#endif + + return text; +} + +// Get text divided into lines (by line-breaks '\n') +const char **GetTextLines(const char *text, int *count) +{ + #define RAYGUI_MAX_TEXT_LINES 128 + + static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; + for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings + + int textSize = (int)strlen(text); + + lines[0] = text; + int len = 0; + *count = 1; + //int lineSize = 0; // Stores current line size, not returned + + for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) + { + if (text[i] == '\n') + { + //lineSize = len; + k++; + lines[k] = &text[i + 1]; // WARNING: next value is valid? + len = 0; + *count += 1; + } + else len++; + } + + //lines[*count - 1].size = len; + + return lines; +} + +// Get text width to next space for provided string +static float GetNextSpaceWidth(const char *text, int *nextSpaceIndex) +{ + float width = 0; + int codepointByteCount = 0; + int codepoint = 0; + int index = 0; + float glyphWidth = 0; + float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize; + + for (int i = 0; text[i] != '\0'; i++) + { + if (text[i] != ' ') + { + codepoint = GetCodepoint(&text[i], &codepointByteCount); + index = GetGlyphIndex(guiFont, codepoint); + glyphWidth = (guiFont.glyphs[index].advanceX == 0)? guiFont.recs[index].width*scaleFactor : guiFont.glyphs[index].advanceX*scaleFactor; + width += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + else + { + *nextSpaceIndex = i; + break; + } + } + + return width; +} + +// Gui draw text using default font +static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint) +{ + #define TEXT_VALIGN_PIXEL_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect + + #if !defined(ICON_TEXT_PADDING) + #define ICON_TEXT_PADDING 4 + #endif + + if ((text == NULL) || (text[0] == '\0')) return; // Security check + + // PROCEDURE: + // - Text is processed line per line + // - For every line, horizontal alignment is defined + // - For all text, vertical alignment is defined (multiline text only) + // - For every line, wordwrap mode is checked (useful for GuitextBox(), read-only) + + // Get text lines (using '\n' as delimiter) to be processed individually + // WARNING: We can't use GuiTextSplit() function because it can be already used + // before the GuiDrawText() call and its buffer is static, it would be overriden :( + int lineCount = 0; + const char **lines = GetTextLines(text, &lineCount); + + // Text style variables + //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); + int alignmentVertical = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL); + int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); // Wrap-mode only available in read-only mode, no for text editing + + // TODO: WARNING: This totalHeight is not valid for vertical alignment in case of word-wrap + float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2); + float posOffsetY = 0.0f; + + for (int i = 0; i < lineCount; i++) + { + int iconId = 0; + lines[i] = GetTextIcon(lines[i], &iconId); // Check text for icon and move cursor + + // Get text position depending on alignment and iconId + //--------------------------------------------------------------------------------- + Vector2 textBoundsPosition = { textBounds.x, textBounds.y }; + float textBoundsWidthOffset = 0.0f; + + // NOTE: We get text size after icon has been processed + // WARNING: GetTextWidth() also processes text icon to get width! -> Really needed? + int textSizeX = GetTextWidth(lines[i]); + + // If text requires an icon, add size to measure + if (iconId >= 0) + { + textSizeX += RAYGUI_ICON_SIZE*guiIconScale; + + // WARNING: If only icon provided, text could be pointing to EOF character: '\0' +#if !defined(RAYGUI_NO_ICONS) + if ((lines[i] != NULL) && (lines[i][0] != '\0')) textSizeX += ICON_TEXT_PADDING; +#endif + } + + // Check guiTextAlign global variables + switch (alignment) + { + case TEXT_ALIGN_LEFT: textBoundsPosition.x = textBounds.x; break; + case TEXT_ALIGN_CENTER: textBoundsPosition.x = textBounds.x + textBounds.width/2 - textSizeX/2; break; + case TEXT_ALIGN_RIGHT: textBoundsPosition.x = textBounds.x + textBounds.width - textSizeX; break; + default: break; + } + + if (textSizeX > textBounds.width && (lines[i] != NULL) && (lines[i][0] != '\0')) textBoundsPosition.x = textBounds.x; + + switch (alignmentVertical) + { + // Only valid in case of wordWrap = 0; + case TEXT_ALIGN_TOP: textBoundsPosition.y = textBounds.y + posOffsetY; break; + case TEXT_ALIGN_MIDDLE: textBoundsPosition.y = textBounds.y + posOffsetY + textBounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height); break; + case TEXT_ALIGN_BOTTOM: textBoundsPosition.y = textBounds.y + posOffsetY + textBounds.height - totalHeight + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height); break; + default: break; + } + + // NOTE: Make sure we get pixel-perfect coordinates, + // In case of decimals we got weird text positioning + textBoundsPosition.x = (float)((int)textBoundsPosition.x); + textBoundsPosition.y = (float)((int)textBoundsPosition.y); + //--------------------------------------------------------------------------------- + + // Draw text (with icon if available) + //--------------------------------------------------------------------------------- +#if !defined(RAYGUI_NO_ICONS) + if (iconId >= 0) + { + // NOTE: We consider icon height, probably different than text size + GuiDrawIcon(iconId, (int)textBoundsPosition.x, (int)(textBounds.y + textBounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(textBounds.height)), guiIconScale, tint); + textBoundsPosition.x += (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); + textBoundsWidthOffset = (float)(RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING); + } +#endif + // Get size in bytes of text, + // considering end of line and line break + int lineSize = 0; + for (int c = 0; (lines[i][c] != '\0') && (lines[i][c] != '\n') && (lines[i][c] != '\r'); c++, lineSize++){ } + float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize; + + int lastSpaceIndex = 0; + bool tempWrapCharMode = false; + + int textOffsetY = 0; + float textOffsetX = 0.0f; + float glyphWidth = 0; + + int ellipsisWidth = GetTextWidth("..."); + bool textOverflow = false; + for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) + { + int codepoint = GetCodepointNext(&lines[i][c], &codepointSize); + int index = GetGlyphIndex(guiFont, codepoint); + + // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) + // but we need to draw all of the bad bytes using the '?' symbol moving one byte + if (codepoint == 0x3f) codepointSize = 1; // TODO: Review not recognized codepoints size + + // Get glyph width to check if it goes out of bounds + if (guiFont.glyphs[index].advanceX == 0) glyphWidth = ((float)guiFont.recs[index].width*scaleFactor); + else glyphWidth = (float)guiFont.glyphs[index].advanceX*scaleFactor; + + // Wrap mode text measuring, to validate if + // it can be drawn or a new line is required + if (wrapMode == TEXT_WRAP_CHAR) + { + // Jump to next line if current character reach end of the box limits + if ((textOffsetX + glyphWidth) > textBounds.width - textBoundsWidthOffset) + { + textOffsetX = 0.0f; + textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + + if (tempWrapCharMode) // Wrap at char level when too long words + { + wrapMode = TEXT_WRAP_WORD; + tempWrapCharMode = false; + } + } + } + else if (wrapMode == TEXT_WRAP_WORD) + { + if (codepoint == 32) lastSpaceIndex = c; + + // Get width to next space in line + int nextSpaceIndex = 0; + float nextSpaceWidth = GetNextSpaceWidth(lines[i] + c, &nextSpaceIndex); + + int nextSpaceIndex2 = 0; + float nextWordSize = GetNextSpaceWidth(lines[i] + lastSpaceIndex + 1, &nextSpaceIndex2); + + if (nextWordSize > textBounds.width - textBoundsWidthOffset) + { + // Considering the case the next word is longer than bounds + tempWrapCharMode = true; + wrapMode = TEXT_WRAP_CHAR; + } + else if ((textOffsetX + nextSpaceWidth) > textBounds.width - textBoundsWidthOffset) + { + textOffsetX = 0.0f; + textOffsetY += GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + } + } + + if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint + else + { + // TODO: There are multiple types of spaces in Unicode, + // maybe it's a good idea to add support for more: http://jkorpela.fi/chars/spaces.html + if ((codepoint != ' ') && (codepoint != '\t')) // Do not draw codepoints with no glyph + { + if (wrapMode == TEXT_WRAP_NONE) + { + // Draw only required text glyphs fitting the textBounds.width + if (textSizeX > textBounds.width) + { + if (textOffsetX <= (textBounds.width - glyphWidth - textBoundsWidthOffset - ellipsisWidth)) + { + DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + else if (!textOverflow) + { + textOverflow = true; + + for (int j = 0; j < ellipsisWidth; j += ellipsisWidth/3) + { + DrawTextCodepoint(guiFont, '.', RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX + j, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + } + } + else + { + DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + } + else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) + { + // Draw only glyphs inside the bounds + if ((textBoundsPosition.y + textOffsetY) <= (textBounds.y + textBounds.height - GuiGetStyle(DEFAULT, TEXT_SIZE))) + { + DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha)); + } + } + } + + if (guiFont.glyphs[index].advanceX == 0) textOffsetX += ((float)guiFont.recs[index].width*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + else textOffsetX += ((float)guiFont.glyphs[index].advanceX*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + } + } + + if (wrapMode == TEXT_WRAP_NONE) posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING); + else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD)) posOffsetY += (textOffsetY + (float)GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)); + //--------------------------------------------------------------------------------- + } + +#if defined(RAYGUI_DEBUG_TEXT_BOUNDS) + GuiDrawRectangle(textBounds, 0, WHITE, Fade(BLUE, 0.4f)); +#endif +} + +// Gui draw rectangle using default raygui plain style with borders +static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color) +{ + if (color.a > 0) + { + // Draw rectangle filled with color + DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, GuiFade(color, guiAlpha)); + } + + if (borderWidth > 0) + { + // Draw rectangle border lines with color + DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, borderWidth, GuiFade(borderColor, guiAlpha)); + DrawRectangle((int)rec.x, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, GuiFade(borderColor, guiAlpha)); + DrawRectangle((int)rec.x + (int)rec.width - borderWidth, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, GuiFade(borderColor, guiAlpha)); + DrawRectangle((int)rec.x, (int)rec.y + (int)rec.height - borderWidth, (int)rec.width, borderWidth, GuiFade(borderColor, guiAlpha)); + } + +#if defined(RAYGUI_DEBUG_RECS_BOUNDS) + DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, Fade(RED, 0.4f)); +#endif +} + +// Draw tooltip using control bounds +static void GuiTooltip(Rectangle controlRec) +{ + if (!guiLocked && guiTooltip && (guiTooltipPtr != NULL) && !guiControlExclusiveMode) + { + Vector2 textSize = MeasureTextEx(GuiGetFont(), guiTooltipPtr, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); + + if ((controlRec.x + textSize.x + 16) > GetScreenWidth()) controlRec.x -= (textSize.x + 16 - controlRec.width); + + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, NULL); + + int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); + int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); + GuiSetStyle(LABEL, TEXT_PADDING, 0); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, guiTooltipPtr); + GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); + GuiSetStyle(LABEL, TEXT_PADDING, textPadding); + } +} + +// Split controls text into multiple strings +// Also check for multiple columns (required by GuiToggleGroup()) +static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) +{ + // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) + // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, + // all used memory is static... it has some limitations: + // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS + // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE + // NOTE: Those definitions could be externally provided if required + + // TODO: HACK: GuiTextSplit() - Review how textRows are returned to user + // textRow is an externally provided array of integers that stores row number for every splitted string + + #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS) + #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128 + #endif + #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE) + #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 + #endif + + static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) + memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); + + result[0] = buffer; + int counter = 1; + + if (textRow != NULL) textRow[0] = 0; + + // Count how many substrings we have on text and point to every one + for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) + { + buffer[i] = text[i]; + if (buffer[i] == '\0') break; + else if ((buffer[i] == delimiter) || (buffer[i] == '\n')) + { + result[counter] = buffer + i + 1; + + if (textRow != NULL) + { + if (buffer[i] == '\n') textRow[counter] = textRow[counter - 1] + 1; + else textRow[counter] = textRow[counter - 1]; + } + + buffer[i] = '\0'; // Set an end of string at this point + + counter++; + if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + } + } + + *count = counter; + + return result; +} + +// Convert color data from RGB to HSV +// NOTE: Color data should be passed normalized +static Vector3 ConvertRGBtoHSV(Vector3 rgb) +{ + Vector3 hsv = { 0 }; + float min = 0.0f; + float max = 0.0f; + float delta = 0.0f; + + min = (rgb.x < rgb.y)? rgb.x : rgb.y; + min = (min < rgb.z)? min : rgb.z; + + max = (rgb.x > rgb.y)? rgb.x : rgb.y; + max = (max > rgb.z)? max : rgb.z; + + hsv.z = max; // Value + delta = max - min; + + if (delta < 0.00001f) + { + hsv.y = 0.0f; + hsv.x = 0.0f; // Undefined, maybe NAN? + return hsv; + } + + if (max > 0.0f) + { + // NOTE: If max is 0, this divide would cause a crash + hsv.y = (delta/max); // Saturation + } + else + { + // NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined + hsv.y = 0.0f; + hsv.x = 0.0f; // Undefined, maybe NAN? + return hsv; + } + + // NOTE: Comparing float values could not work properly + if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta; // Between yellow & magenta + else + { + if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta; // Between cyan & yellow + else hsv.x = 4.0f + (rgb.x - rgb.y)/delta; // Between magenta & cyan + } + + hsv.x *= 60.0f; // Convert to degrees + + if (hsv.x < 0.0f) hsv.x += 360.0f; + + return hsv; +} + +// Convert color data from HSV to RGB +// NOTE: Color data should be passed normalized +static Vector3 ConvertHSVtoRGB(Vector3 hsv) +{ + Vector3 rgb = { 0 }; + float hh = 0.0f, p = 0.0f, q = 0.0f, t = 0.0f, ff = 0.0f; + long i = 0; + + // NOTE: Comparing float values could not work properly + if (hsv.y <= 0.0f) + { + rgb.x = hsv.z; + rgb.y = hsv.z; + rgb.z = hsv.z; + return rgb; + } + + hh = hsv.x; + if (hh >= 360.0f) hh = 0.0f; + hh /= 60.0f; + + i = (long)hh; + ff = hh - i; + p = hsv.z*(1.0f - hsv.y); + q = hsv.z*(1.0f - (hsv.y*ff)); + t = hsv.z*(1.0f - (hsv.y*(1.0f - ff))); + + switch (i) + { + case 0: + { + rgb.x = hsv.z; + rgb.y = t; + rgb.z = p; + } break; + case 1: + { + rgb.x = q; + rgb.y = hsv.z; + rgb.z = p; + } break; + case 2: + { + rgb.x = p; + rgb.y = hsv.z; + rgb.z = t; + } break; + case 3: + { + rgb.x = p; + rgb.y = q; + rgb.z = hsv.z; + } break; + case 4: + { + rgb.x = t; + rgb.y = p; + rgb.z = hsv.z; + } break; + case 5: + default: + { + rgb.x = hsv.z; + rgb.y = p; + rgb.z = q; + } break; + } + + return rgb; +} + +// Scroll bar control (used by GuiScrollPanel()) +static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue) +{ + GuiState state = guiState; + + // Is the scrollbar horizontal or vertical? + bool isVertical = (bounds.width > bounds.height)? false : true; + + // The size (width or height depending on scrollbar type) of the spinner buttons + const int spinnerSize = GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE)? + (isVertical? (int)bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) : + (int)bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH)) : 0; + + // Arrow buttons [<] [>] [∧] [∨] + Rectangle arrowUpLeft = { 0 }; + Rectangle arrowDownRight = { 0 }; + + // Actual area of the scrollbar excluding the arrow buttons + Rectangle scrollbar = { 0 }; + + // Slider bar that moves --[///]----- + Rectangle slider = { 0 }; + + // Normalize value + if (value > maxValue) value = maxValue; + if (value < minValue) value = minValue; + + int valueRange = maxValue - minValue; + if (valueRange <= 0) valueRange = 1; + + int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); + if (sliderSize < 1) sliderSize = 1; // TODO: Consider a minimum slider size + + // Calculate rectangles for all of the components + arrowUpLeft = RAYGUI_CLITERAL(Rectangle){ + (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), + (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), + (float)spinnerSize, (float)spinnerSize }; + + if (isVertical) + { + arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize }; + scrollbar = RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) }; + + // Make sure the slider won't get outside of the scrollbar + sliderSize = (sliderSize >= scrollbar.height)? ((int)scrollbar.height - 2) : sliderSize; + slider = RAYGUI_CLITERAL(Rectangle){ + bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), + scrollbar.y + (int)(((float)(value - minValue)/valueRange)*(scrollbar.height - sliderSize)), + bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)), + (float)sliderSize }; + } + else // horizontal + { + arrowDownRight = RAYGUI_CLITERAL(Rectangle){ (float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize }; + scrollbar = RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)) }; + + // Make sure the slider won't get outside of the scrollbar + sliderSize = (sliderSize >= scrollbar.width)? ((int)scrollbar.width - 2) : sliderSize; + slider = RAYGUI_CLITERAL(Rectangle){ + scrollbar.x + (int)(((float)(value - minValue)/valueRange)*(scrollbar.width - sliderSize)), + bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), + (float)sliderSize, + bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)) }; + } + + // Update control + //-------------------------------------------------------------------- + if ((state != STATE_DISABLED) && !guiLocked) + { + Vector2 mousePoint = GetMousePosition(); + + if (guiControlExclusiveMode) // Allows to keep dragging outside of bounds + { + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && + !CheckCollisionPointRec(mousePoint, arrowUpLeft) && + !CheckCollisionPointRec(mousePoint, arrowDownRight)) + { + if (CHECK_BOUNDS_ID(bounds, guiControlExclusiveRec)) + { + state = STATE_PRESSED; + + if (isVertical) value = (int)(((float)(mousePoint.y - scrollbar.y - slider.height/2)*valueRange)/(scrollbar.height - slider.height) + minValue); + else value = (int)(((float)(mousePoint.x - scrollbar.x - slider.width/2)*valueRange)/(scrollbar.width - slider.width) + minValue); + } + } + else + { + guiControlExclusiveMode = false; + guiControlExclusiveRec = RAYGUI_CLITERAL(Rectangle){ 0, 0, 0, 0 }; + } + } + else if (CheckCollisionPointRec(mousePoint, bounds)) + { + state = STATE_FOCUSED; + + // Handle mouse wheel + int wheel = (int)GetMouseWheelMove(); + if (wheel != 0) value += wheel; + + // Handle mouse button down + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + guiControlExclusiveMode = true; + guiControlExclusiveRec = bounds; // Store bounds as an identifier when dragging starts + + // Check arrows click + if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += valueRange/GuiGetStyle(SCROLLBAR, SCROLL_SPEED); + else if (!CheckCollisionPointRec(mousePoint, slider)) + { + // If click on scrollbar position but not on slider, place slider directly on that position + if (isVertical) value = (int)(((float)(mousePoint.y - scrollbar.y - slider.height/2)*valueRange)/(scrollbar.height - slider.height) + minValue); + else value = (int)(((float)(mousePoint.x - scrollbar.x - slider.width/2)*valueRange)/(scrollbar.width - slider.width) + minValue); + } + + state = STATE_PRESSED; + } + + // Keyboard control on mouse hover scrollbar + /* + if (isVertical) + { + if (IsKeyDown(KEY_DOWN)) value += 5; + else if (IsKeyDown(KEY_UP)) value -= 5; + } + else + { + if (IsKeyDown(KEY_RIGHT)) value += 5; + else if (IsKeyDown(KEY_LEFT)) value -= 5; + } + */ + } + + // Normalize value + if (value > maxValue) value = maxValue; + if (value < minValue) value = minValue; + } + //-------------------------------------------------------------------- + + // Draw control + //-------------------------------------------------------------------- + GuiDrawRectangle(bounds, GuiGetStyle(SCROLLBAR, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), GetColor(GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED))); // Draw the background + + GuiDrawRectangle(scrollbar, 0, BLANK, GetColor(GuiGetStyle(BUTTON, BASE_COLOR_NORMAL))); // Draw the scrollbar active area background + GuiDrawRectangle(slider, 0, BLANK, GetColor(GuiGetStyle(SLIDER, BORDER + state*3))); // Draw the slider bar + + // Draw arrows (using icon if available) + if (GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE)) + { +#if defined(RAYGUI_NO_ICONS) + GuiDrawText(isVertical? "^" : "<", + RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); + GuiDrawText(isVertical? "v" : ">", + RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3)))); +#else + GuiDrawText(isVertical? "#121#" : "#118#", + RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3))); // ICON_ARROW_UP_FILL / ICON_ARROW_LEFT_FILL + GuiDrawText(isVertical? "#120#" : "#119#", + RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical? bounds.width : bounds.height, isVertical? bounds.width : bounds.height }, + TEXT_ALIGN_CENTER, GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3))); // ICON_ARROW_DOWN_FILL / ICON_ARROW_RIGHT_FILL +#endif + } + //-------------------------------------------------------------------- + + return value; +} + +// Color fade-in or fade-out, alpha goes from 0.0f to 1.0f +// WARNING: It multiplies current alpha by alpha scale factor +static Color GuiFade(Color color, float alpha) +{ + if (alpha < 0.0f) alpha = 0.0f; + else if (alpha > 1.0f) alpha = 1.0f; + + Color result = { color.r, color.g, color.b, (unsigned char)(color.a*alpha) }; + + return result; +} + +#if defined(RAYGUI_STANDALONE) +// Returns a Color struct from hexadecimal value +static Color GetColor(int hexValue) +{ + Color color; + + color.r = (unsigned char)(hexValue >> 24) & 0xFF; + color.g = (unsigned char)(hexValue >> 16) & 0xFF; + color.b = (unsigned char)(hexValue >> 8) & 0xFF; + color.a = (unsigned char)hexValue & 0xFF; + + return color; +} + +// Returns hexadecimal value for a Color +static int ColorToInt(Color color) +{ + return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a); +} + +// Check if point is inside rectangle +static bool CheckCollisionPointRec(Vector2 point, Rectangle rec) +{ + bool collision = false; + + if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) && + (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true; + + return collision; +} + +// Formatting of text with variables to 'embed' +static const char *TextFormat(const char *text, ...) +{ + #if !defined(RAYGUI_TEXTFORMAT_MAX_SIZE) + #define RAYGUI_TEXTFORMAT_MAX_SIZE 256 + #endif + + static char buffer[RAYGUI_TEXTFORMAT_MAX_SIZE]; + + va_list args; + va_start(args, text); + vsprintf(buffer, text, args); + va_end(args); + + return buffer; +} + +// Draw rectangle with vertical gradient fill color +// NOTE: This function is only used by GuiColorPicker() +static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2) +{ + Rectangle bounds = { (float)posX, (float)posY, (float)width, (float)height }; + DrawRectangleGradientEx(bounds, color1, color2, color2, color1); +} + +// Split string into multiple strings +const char **TextSplit(const char *text, char delimiter, int *count) +{ + // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) + // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, + // all used memory is static... it has some limitations: + // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS + // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE + + #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS) + #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128 + #endif + #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE) + #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 + #endif + + static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; + static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; + memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); + + result[0] = buffer; + int counter = 0; + + if (text != NULL) + { + counter = 1; + + // Count how many substrings we have on text and point to every one + for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++) + { + buffer[i] = text[i]; + if (buffer[i] == '\0') break; + else if (buffer[i] == delimiter) + { + buffer[i] = '\0'; // Set an end of string at this point + result[counter] = buffer + i + 1; + counter++; + + if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + } + } + } + + *count = counter; + return result; +} + +// Get integer value from text +// NOTE: This function replaces atoi() [stdlib.h] +static int TextToInteger(const char *text) +{ + int value = 0; + int sign = 1; + + if ((text[0] == '+') || (text[0] == '-')) + { + if (text[0] == '-') sign = -1; + text++; + } + + for (int i = 0; ((text[i] >= '0') && (text[i] <= '9')); ++i) value = value*10 + (int)(text[i] - '0'); + + return value*sign; +} + +// Get float value from text +// NOTE: This function replaces atof() [stdlib.h] +// WARNING: Only '.' character is understood as decimal point +static float TextToFloat(const char *text) +{ + float value = 0.0f; + float sign = 1.0f; + + if ((text[0] == '+') || (text[0] == '-')) + { + if (text[0] == '-') sign = -1.0f; + text++; + } + + int i = 0; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) value = value*10.0f + (float)(text[i] - '0'); + + if (text[i++] != '.') value *= sign; + else + { + float divisor = 10.0f; + for (; ((text[i] >= '0') && (text[i] <= '9')); i++) + { + value += ((float)(text[i] - '0'))/divisor; + divisor = divisor*10.0f; + } + } + + return value; +} + +// Encode codepoint into UTF-8 text (char array size returned as parameter) +static const char *CodepointToUTF8(int codepoint, int *byteSize) +{ + static char utf8[6] = { 0 }; + int size = 0; + + if (codepoint <= 0x7f) + { + utf8[0] = (char)codepoint; + size = 1; + } + else if (codepoint <= 0x7ff) + { + utf8[0] = (char)(((codepoint >> 6) & 0x1f) | 0xc0); + utf8[1] = (char)((codepoint & 0x3f) | 0x80); + size = 2; + } + else if (codepoint <= 0xffff) + { + utf8[0] = (char)(((codepoint >> 12) & 0x0f) | 0xe0); + utf8[1] = (char)(((codepoint >> 6) & 0x3f) | 0x80); + utf8[2] = (char)((codepoint & 0x3f) | 0x80); + size = 3; + } + else if (codepoint <= 0x10ffff) + { + utf8[0] = (char)(((codepoint >> 18) & 0x07) | 0xf0); + utf8[1] = (char)(((codepoint >> 12) & 0x3f) | 0x80); + utf8[2] = (char)(((codepoint >> 6) & 0x3f) | 0x80); + utf8[3] = (char)((codepoint & 0x3f) | 0x80); + size = 4; + } + + *byteSize = size; + + return utf8; +} + +// Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found +// When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned +// Total number of bytes processed are returned as a parameter +// NOTE: the standard says U+FFFD should be returned in case of errors +// but that character is not supported by the default font in raylib +static int GetCodepointNext(const char *text, int *codepointSize) +{ + const char *ptr = text; + int codepoint = 0x3f; // Codepoint (defaults to '?') + *codepointSize = 1; + + // Get current codepoint and bytes processed + if (0xf0 == (0xf8 & ptr[0])) + { + // 4 byte UTF-8 codepoint + if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]); + *codepointSize = 4; + } + else if (0xe0 == (0xf0 & ptr[0])) + { + // 3 byte UTF-8 codepoint */ + if (((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks + codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]); + *codepointSize = 3; + } + else if (0xc0 == (0xe0 & ptr[0])) + { + // 2 byte UTF-8 codepoint + if ((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks + codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]); + *codepointSize = 2; + } + else if (0x00 == (0x80 & ptr[0])) + { + // 1 byte UTF-8 codepoint + codepoint = ptr[0]; + *codepointSize = 1; + } + + return codepoint; +} +#endif // RAYGUI_STANDALONE + +#endif // RAYGUI_IMPLEMENTATION diff --git a/examples/shaders/resources/LICENSE.md b/examples/shaders/resources/LICENSE.md index 7210e34b2..078036df7 100644 --- a/examples/shaders/resources/LICENSE.md +++ b/examples/shaders/resources/LICENSE.md @@ -10,4 +10,7 @@ | space.png | ❔ | ❔ | - | | texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) | | cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - | -| spark_flame.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) | \ No newline at end of file +| spark_flame.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) | +| parrots.png | [Kodak set](http://r0k.us/graphics/kodak/) | ❔ | Original name: `kodim23.png` | +| cat.png | ❔ | ❔ | - | +| mandrill.png | ❔ | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Mandrill (a.k.a. Baboon) | \ No newline at end of file diff --git a/examples/shaders/resources/cat.png b/examples/shaders/resources/cat.png new file mode 100644 index 0000000000000000000000000000000000000000..db56b9eadbcbe2a750734fd1bc1b5f9b416d2e95 GIT binary patch literal 388467 zcmeAS@N?(olHy`uVBq!ia0y~yU~FJuU}E54Vqjok`Kz;*f%UDGr;B4q#jTRRw~9eC|W{4YUg(I;Y(QBAF?0#Bcbl992K%EaC2%Vu^q%{)9u!!_lc zlr-&l^@{r`YJ!5zGhcsK5)yoO?u?StM5WxlUsKA}7gb5x z+^bOwOi8=U&EYw-^UN>Frb9Drl#f{?%}G&yE?8!C({Rnc#WSx;2dJfeyU=mMhoSS= zky$ehm+yZ6d!A=7miNSdJ`AWVZ$7d4E z4#H=B7O5=a=qTILckM#i#n`PYwF=Ll@map1r*n?sc|*P(y|)d|-QE%RFztEchXVgx zmnZLP?=J`lO*U$xRA_A!duwUF|CJVz+Wj{5zouHAT$VOX z@U_gWbhor~9lLx=J>;&7IK;j%>F>A}HADEKNBQ^M+YBpK?cRRv*<EQQaJVtL6vJ z=*)22d+AqFSmHISV>31HOqzJa>iM2Gvv1z6jdNe6CnRVpseGw?X}b(9EQF7gPMIlrXMzh06Z>ZNrR_6+ z&NyW9+-1_LdCv`>-wCaHy}e^sx<-+l@^+RD-_J_AtdPE>v@JLJS?=w9H9w1PelPWR z(^$WH{gi$8R$Z}mD>nPS@9o!SgU!~$SD&VpSKD+kT>0I<#nLVN(3v$8?)|#Ab^C&j zj(gQkMzOct5@%NY`jE4Iy^2qw0N3IZDGClgD;{?}dA>ZIeg5;Czn0!h5nB74W%*3| zd25s|MM)>0u?*kYDKPPjOmfPz)Z4wEE&5J>zFawPPD*iD?yE(yCJv$U4k}7D`pSF1 zXE8BER4ku1^LZs##O!ysj~bnE`nUf7_y3pQT1-;vP`adiciGIP>>VwZ5qno91_h+3 zX}i0zZ0y)wJ@>4KV!#Afx0ExTOL{y`sd-6G)VakZbiknKfU&Y*qNnHgSCeNtdMflw zzMLqQ=^(_O>LyXyz`(TGXM3@qfrpAMgIJ*8IS;QDMjbkqwi**X*Z43P3Qsg+kbF61 z$tsr>w<~%kYjoZdcgga-oIb-?P>^%;?5mBX9UBCG+|y^(kYwRd)o}dEvc6tW)BMyD z1pz|^o~ZaIGtV`B-ZSsHuVCK0%M!0HZ`-z0Rn@RNdd~3`(go)V=b3w@U#Prew8m3> zT49txhr`K)b3SE@Ph8uU!YZ|~r8-EB(dC`6h)dswEhnc)O1``OZOX|zvs5irCON!V zRXlGmr}577Dnfw^b1rqN7;(O478IKwKKr>vdYaG-hiPTD`Alj}J1YeaycBz;FTJZ|fqzaXcwX!e3?wZ^$d4vv{-chwj_?=f<{_2Kr_=a&7>E^f~r zXHI{@FyRQVpx=&wq6)R82Gv#$6TkfV^Tw2SgUMUR7q#;*C(pb3FXR0hUDw;+RMt*r zVBmIcX?&rVJ>Lk zD5;h8@QBdEnd`J3+jyE>Dt-TVlPdSZ&aBtE9t?_)UZpl0b+*jB&B`FCbjg-M?Sq8y zmFF9HHgI%T8Eq6Q4`k$SbdA1W<}V(4Ug5i?TQKW_TSl5ThYo8fF=jM1bj*=_H}7PE z;CYoKf!BpHq0YxL_m&H|s;K*J?+HkK$#vk)Cp(W7>J1xAIL~M32Jo-+Q1A@<{m@YP z5Zl?8I!(vk$z`tT@F@zJe09nqsm0~Y-lnqe+r*nb{OUi^!Em5-=}xt_2kx(D?2B6H z;L?$?rmyp!FMHAMy;xR{gl`V>-}dWod{39l z*RKTu>WRMn#XPTcZ+KdHufC>c9Qb$h#Av_SJrB+tfAjOp7nW-b*Tt{z6ffvq=TaiW zzS(H=Ow)x99bBwRN{1NPf(1gXAIzLloVJYP{cpd^%5!GUk76(Ai=H8vnLT^=?(5-P z4D-bV_r72IecRhrvy?a$7e!o-R9Urf9rGhI|8o}Si(}T;$vj!7^e)pZyN@GaR(Afo zdCT+9pTFF;O06)8rM;sdSa4=>K$}5vP+HshlqAJ3ybZgBkJv7DYxijs(Gl){TSI%mMGt7OidFhPY+r9U>mAR)(?YMC!X_m>BYb(E3Z8wfNKH9i>JSSeLekp{{H`0FJEp~S>eUUuF4=^!)7m1{)lw5~5IDy~r#A{QK9UVrUn+>*Ik#sWGoH-(S>}O?f@{Rl<^7j~EI3b2oY~{%l9~7Hu&>7Z zx%y2rXHHF>6Wr1~Ln&gxsU^Q1aw_Q8WKhG84=(Aj5BAe?hM1B+Bp^6-UbflxB`In@um6Abe}Z7%vHWJz5lbvJ=6Fs!<%{H)(szVEZO?(R){wJL0p(}LrI z{#AQCj2>S+cV%_u-sRSP3=8JDKfG97UA;$O@A0*-L|<9kSs4jN%G(C=W<;*{o+-%? z`gyWs3ybo5uLKan8dka(~9yow;3;+c>yHhGt- z-%EElw1#l@%u?hizcJC3WzWCB*z+y!3)v^H;OO3F^+Z$YjMIr%TVG3D&p+_w-QM!= zPNp*)5>x~wcr*-j#jH+l$^E@8*67C=L*kZtcDl3OuvC>Ci#qHm` zqKBAwmzKxz9+S>Euf+Ow?^J_T8`n)UGktL>`D*CffU7M|0*q{8X=lC*{o7X%GX3K> zzSX|n6;}lBznQyiAZ#4TX zqq3)HDz#2GE&ojNWw=Qn>#`o3l zWwoAL&a}Mb_+r!A%WHfi{-W~+3U2Yul_Q7=Bihh&n@Cq%RDnDQdO?=_|Z>1r$2n~G&3!noxJDXn;n5E;afi# zsQY!Lq$O>8RW^IuwT?y8qxWfHa$_f|J;WU3+`0SE^Z2n2wc2q_wLo#jGc@h z3YJENMokhlo-j*yrp(GT4ObQ%Y3pT`Z$6B|J6By>?doExzv@Fo_kz%d4u?+_tFE3c zy=k5{uXs})gND+fEKM~fC63}24V8NfrmR_O)p5|pMQma5yyCuVQ9Tpiu_i_IR$lmC zZJ43#<+V=wjfHza7lT&pl$mFhbIbAspUgA4b7sMdz0FteM*jGFuKSQN^R4&!1z$M= zC!Bh<@Ks?%_l7l<5A9?=YB~7C%y*d6+Oy;NEXnIh^W@hwonc9L^VuGC&`-aGRp-sS z6Z`X`UoEb`;v%?q;-gy6MZc#pIs{eiQ0RP8+q$aO%tAA8viL=2_AZX@4xaW6D$jZ( z{am*8t<EE@ew_n5T?XDjTVl{Zq5?FdP ze`?5u1IG(pTE4g$H;6d0aCYA`=&s$Jb6d=D-j(m(ErBY^%?CJ>1UUnkaw7KjG$@_n z6m(#7R8nGm%61^Rt@5DfYTe#~{*Hvq+TB-vCx>1PvteZ5@s*13K6d8ImjxSm=087s z&hWf+r9q&}m6Z%ZAGCsDPF4bm3zmx?2Jmkhts4Eh3lM&&pz99 za_Me7BlGyh-uk_Fx$gQf97>roQy?#QwIY|3r@|u^MJ3~o9aTOGuGbpZ2QGN!P^;j= zl9V(fvMFS%+?Jrz6<5#5n7vwcb@9!!mW#j2`N`>dy}N9?)xI+$Eh-|^%~bl`=>EQa^{J~4FFW9}Hmtmn@Sn2o7i`C0HxRcU8 z$R4g+uxYiij-B70=B^2x-ogUUUrmy$b*y##d$uF>?(xY|;DetNJrP8t%}w;Qqr_tDdfVVAV4fb<0KvPmv=5 zV*L%p9Niw-LQ{?xuARTpulXML@#N&F^|8ONFfHkS{9+H|lQhOh$8K#kaE;P7kJ_>O z)S?dpsitjTn;CX}wLYl6Iy~vwwG_Ypg7Wk&XAIVNDsawOk~c5#d?+KUu_>$IPZRY= zJZVhELN60Uxr@9`eNk8@;vsC6yGy?);Qn?VmzH#a)MU|2PR}Tgx$Vp+N;Xe?XL#Jk zfAhy1>r5tox#g`OyhxL)-=pozvfR%xynOcqYm*k8;7L*I4l$NaoVhwkU0GQ{<&dPv zOCR0KotG}DOqjCf$`<3v(Pw7(T5rBt;2y75Y8qMDfdNBcQSGa@<`b!0lQTq<_V zFyroE6rRjK`>@}3N0*+G?;A2*e}Bq!EL@nh*RWVfeMy?}p2e&kYq-zK1a!UdjN4nB z7F3jG^uut2T%TYByP~B_|4H)|wV)uZ`84&NAbvVYN$3 z<+f{K{l`nrtz6|(v7uMtPekLz`me7IkJ$X`JHAQbGULkkL3b0h98}CZ>Gjo3L<34z3@}v!NYx^1ZoyySu(Xi?JHJ7~Y(Ty|G zmfdu17OzpRO=WibrV353gtZIvbX6-GDPS!IXojoi|G#S*y1V2A~w`%&X)CQj7 zw4`e)^2sg2jYbnCfA72Q5y-x{qWH1I-tt7HMUm}|PBWEsCRM+8kUOrcG5cM=b9H?| z+n@9QKhClNiJtwT2 zE@x#K$8T}wU;Sr#P#^j4#Vea zA2wVIo#Ln=mZaEmlz&IDU~fl6k(-^Z{r79<43&asaOy1L^v&F5`*K^et4m<2MT=0N zH#<|YuttaRBt^-iGexe>Yw>w=TiCI^I>liDujDe80`u92ICtDU=(2aahl`6MKZCKN zkmSirTT6|FBUg8*xk#p&9bQ_R=&7_}(iRr=1;6z!ad-u|F&hdRheR56INJ49?pxOX z`0LlIYT5PIEqz*_Tc+B|cv^*+C6=b#H@j=ySo(U+rd(Mae}DOBK2GU(ja^IC?{V7X zxXfV+R|)nyWISUEM~~XB)j4aVy_?_Z2)S}73p6rzg*^KrY&k_a$v`mM_`A&VZF;vl zEIT_DE*(1DVKi~#QH$;mFN3!qyJ^GxDVVr$`TQx}M}sqNELQL05M)!I$fVcAF25zK*in3r%b6)LFQgb&O)8RK zeJ!e`<^2SUr%FnvVjBhbJzJa=BmY8{J9wR(UQ(${NQi?9_o1$m?3p)9q@Pc(y?^$N zO`2_GL@IBmprhucU)ux^-JN0im)A(UC4B3?xem9TE;mPAzj}nTqrrnCwQ19V{8y_! z^2M(|bn47yw(hd2PG>bI33;A87TfJd+$^0Gpx-P%lu5m^+zrEG? zMCq(~>WW`BXLRleKQvQX^ln}5?Ma88xnwiUmYfkK>^CFw#{{R;VAoSfL!luY3ok-f4&2q6s*33AmXJM}T zqAwhuuSEr~OFF1DvoGe(!ACy?1b>C?$)9>udo8EsvzxP1mZ|S>Yx^v7dH%jirBm*@ zD|$;@RMZfl=?J;0y;d56m92vJ#^gReKaz;zf76=S0V1zqGW6O$B$2 zAFSDwVlpK=yjzSzNh@gAS!3g!R!^-NO^vzDR29zJPF|{4r7(9>h*F3^wAg07+KbVf zG74*dXbW$7zoyaWvnS8gXOdH{%)Gtr^|i@?XBX%B-`S;pz)OHTJD0nNZ~kPXpaYJx zBBSIz4J!UlR`~2O>xfp`-gn`7rI((~vEwzol)l5&Xa4ft%dG^@7Cf9QkTzMhwKHkn z<%P5Ic#;%bcK3fdd1lF*GJ!&-HNKM=I&U)yN-wwI+PVH~WVWu(mdPH)IEF6b2Bl%y? z%HFy)%`(*VkZX&Ey!CXB{W04Xq$F?dkUSI8l2RTnrrk4d(G%6c3%ZwT3(Z}uH*VXO zd%J9oy5S7h)QK6aH=}NUyCom(vP)f9$+kFG_H*vmcPw7)oN_nVXJ}^6i;L&!(7F>V zI`gI7Ooy3A75)93xH#9_+A?O`s(OEF5@$L4XX{KI`(-MjBBI6}jZc(5uX%skGqSkU zkn6?0ntQ9|?63V4>~8fq!e7hg;lk}3Z!V-7Xt86~f}7R%zuRhX-|jjpwdyBF$^Pv# zJsUQ@aO!q>{7_QCSMSAa7Ns*@S9J|eTrLi>+8L}C*mRJ8+n21%*JjO|c_^(()A7L* zm&VsGTTD(j*<9al<{Xr!!fLF(!|n9f{SAdOtgcsG*J-_PjoHSQ5S8L`J4}DimJW`z zbd9V6l|3&j-aYAg16V)b5T9=djB_U<>5727XI>ioExEnw)l>XzFKX{80<>*#P`yrEm>6MDeG`%K~JFRW`w@O;9U0E(1(D^PsyMtRmGv>nI zZxQ!(j&W|AsDb8ek zbUbtQsp9`OPY+hE58OWC6T9p}w%yiCFHh{=@phx$$;x@tPcM}+yc%ZzEZMe2YuDD3 ze1~_(n@V#To2G>=GGDNFUv;vf^hCFbBJ&dMaygTBc3kWbdM>(c&cQ8Hb|rKM@uz9s zc&xM0gYmWZd%0^{ZC5$Veq&)jdh12%KJoi^)<@aZwYaCB?R~G)9(224lJWnevliJM zaLUcrm3a12M9{a|XsLlJ2H2wQw=U49w0iiAa)0G*h4C z#F3EqyHFejsS{_%hk4~v51%x8D9mi`cq5~EYl~p;FO%(RyG(m4 zm&{gZ_)vK!;#IEFr$vt^i~Ln%F7}h3eCF*A)(Ov^f1QFJ$mu5__iZ`s%u{$Po zy!y=X$`zY8-YYx8JnO`n?Q$zh{4^Ez_79`!%k7 z!^=AE#pSF=&M0+Ud$U>Y*>lUN$=7aO`?|42dy*03%kn+FpZDGR{!1fUqpoC?>mimB z-5p_(g$D0RT&fJ%?&WD$t^O+bvrkV&wdcf_B^uijL+2;Y`CYeC-6uP@@8^rPhhkYy zdAxZ1(9y-wC+N*pxuYrKji=@Y3Gf%Nzsx?zwb@c5Y0=kvtB+K(7|)1|Fq*66F@y7E z+B=^oN_pyAHVd$xIeYE+)`m8B#;8Bxq2^jI8aqD4)w-x0(>dwQdAzI0==|cX+{K@o zm{(V>xm#r;@_c99lE!0}>V^@iwoNm7CvomI@4unvKkcAW?)_6bPAzx$ZtxacWHS5m z+k~48Ex|3#t8T8U%|7X6lhf8ag-@()oqNZLSb_Jg>6}k@MNIsv`-=OR<#wtBDoxqx)x1jVPvm3H)Sx!6PG(~WAv(on9^)w$kq5$dZ5^}6|^7+ei zN-Gveir>3;q$K3Pv@1>TZ8@zsn{yUR2WmLaO<1wu?fWPpuc{O2jz=UE=V`Jxk;wTUa$JBUa{~k!1`M6n*=9j`8GIKQ^t}eS1!&y8Kf2CYPylZ}xGx6s#eLF?Y!rXJ@>XJUcUSJo$|yZvD?px6O+e2mim>d;IR{mj~aj@ZZ;Y&T`^85rt1NpTEX#kkYB}{~oW; z$Hx@N)i^_(Rh%=8*Uv9^?cP0m-u#Z!dTzw1so#J7`gN_wwWixOl$_t&=AL`p_H9e1 zvlIu@CzVqSJHAvs`0DsR_jRs+(aT!D@T=Fn=UE?AQSqHM^J46}LznKfS8rSPbxpbot1iE(dJ6&)jN9$U_oJjGvjzk1um zD@PhXeCSxgIAbB>>7yymX$)NFmM#|7EWGo0)sEk?iCs&XnD2AC&yma%R5jN$IN#1C zK5b)eb+4AZUCoZU>B5R#B??Xl*PayGboXZeypuYs?kc;a9Q)L|Gk?06_T0@&ww!E@ zHB=6sQ8>NOM(Vw5n+oTtuZjlUM(HUMsR0%q#+RQ(I#2d6<-R&=LZqMhQma`Ji(Wlp zc~V!i(<>##OwCPcvS-WWpL=&pYjm)*+_GKIY4nJZKTc2FrETZ5oT)*x-ktaVY%zb{ zytdg40g2c4hN=Q^VIvN?3+5nZ1M)> zoS60=+?K}pb_r0CIwmf%j_Y?uzIvnlNqVJk_Oddd{8*KkvGr;Ai;%Pw^#h zA4-aBzrAwNAzfu}o;a1JLK(?@U$2Ser7z2memz0Wr`U{9*ig9h%ihThUb)#WH@BZV zbneQw?wsn|W)t(CnPyh0D5&gx@2?^?C3IWL$uj4NJA2qp^O%G+HVE$fa{PhNU(Hmm zL(gVrDygQc3eG*8{8lIFhUc7Hsk7!LD>y}*`qnPF_UpANl74;-8b zOnvziSEl}p)z)6>-Y$GmB=A|)nF%{LZ&+S_v0(mjQIWN)H?TEsUCeo{D@8dYO<9QP z`CTvlI~r<7H+()e$74(GX_cgJJnXi$KLiBVT-r8|=i?B z{Jt5hI~SF2-7s$jw_So*`ROfHADSX(8+pIx((qQkn!EeNwypb4TD6zxPyS=jT0GnI z_=~9DJ2|)?By#shp5H6=)!0Gj&aGo-;4rVdwq4?Mq^u_8qnGXmI(l z@lRI?*RJ2|7k2j;E}tvdrXuY=Bh{s1MOM&^vs>fO-l@``&%)2mUA+4G!ZTry>h5@M zSt`JNX`7(2>c+CG$8>_uhD!yvNKR~2vf+BJu%YXoxL_;m1Dp13-xBQY*tQ)1^;l23 zu4D5ik<*+#mf3&uR`KkZn>J5!Z@!YzG0BIXFO!pY=8D`@X`10WNm6CPu}cj`H>1Rt z|Kjw2yye5o;*=fd6U}mYo=N@Z^hr?i@)m!Xd;8WkhOVA{rdQ+UD!6Rfdd*7Eck@$Q zhbP(Jx4cOxdTVW~q|0$gDR$PTSCf_m=Wds5SYh(?3&Uc~V4;Yp*9

~~pm;n#;V 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

!F>hw=>_CKWxakoG~>-h5-DsFflqxUtYU2@^N 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�Jy@5uYTJft?n#27PvttQ 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

    (sMz5(2V8QvGSulXwD?IDSU?YKMqz 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 G2~7akr);bM literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/shaders/glsl100/color_correction.fs b/examples/shaders/resources/shaders/glsl100/color_correction.fs new file mode 100644 index 000000000..a678c6ed2 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl100/color_correction.fs @@ -0,0 +1,34 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +uniform float contrast; +uniform float saturation; +uniform float brightness; + +void main() +{ + // Get texel color + vec4 texel = texture2D(texture0, fragTexCoord); + + // Apply contrast + texel.rgb = (texel.rgb - 0.5)*(contrast/100.0 + 1.0) + 0.5; + + // Apply brightness + texel.rgb = texel.rgb + brightness/100.0; + + // Apply saturation + float intensity = dot(texel.rgb, vec3(0.299, 0.587, 0.114)); + texel.rgb = (texel.rgb - intensity)*saturation/100.0 + texel.rgb; + + // Output resulting color + gl_FragColor = texel; +} diff --git a/examples/shaders/resources/shaders/glsl120/color_correction.fs b/examples/shaders/resources/shaders/glsl120/color_correction.fs new file mode 100644 index 000000000..520275ca4 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl120/color_correction.fs @@ -0,0 +1,31 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +uniform float contrast; +uniform float saturation; +uniform float brightness; + +void main() +{ + vec4 texel = texture2D(texture0, fragTexCoord); // Get texel color + + // Apply contrast + texel.rgb = (texel.rgb - 0.5)*(contrast/100.0 + 1.0) + 0.5; + + // Apply brightness + texel.rgb = texel.rgb + brightness/100.0; + + // Apply saturation + float intensity = dot(texel.rgb, vec3(0.299, 0.587, 0.114)); + texel.rgb = (texel.rgb - intensity)*saturation/100.0 + texel.rgb; + + // Output resulting color + gl_FragColor = texel; +} \ No newline at end of file diff --git a/examples/shaders/resources/shaders/glsl330/color_correction.fs b/examples/shaders/resources/shaders/glsl330/color_correction.fs new file mode 100644 index 000000000..c489d6df1 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl330/color_correction.fs @@ -0,0 +1,34 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +uniform float contrast; +uniform float saturation; +uniform float brightness; + +// Output fragment color +out vec4 finalColor; + +void main() +{ + vec4 texel = texture(texture0, fragTexCoord); // Get texel color + + // Apply contrast + texel.rgb = (texel.rgb - 0.5f)*(contrast/100.0f + 1.0f) + 0.5f; + + // Apply brightness + texel.rgb = texel.rgb + brightness/100.0f; + + // Apply saturation + float intensity = dot(texel.rgb, vec3(0.299f, 0.587f, 0.114f)); + texel.rgb = (texel.rgb - intensity)*saturation/100.0f + texel.rgb; + + // Output resulting color + finalColor = texel; +} \ No newline at end of file diff --git a/examples/shaders/shaders_color_correction.c b/examples/shaders/shaders_color_correction.c new file mode 100644 index 000000000..8aee1d0e4 --- /dev/null +++ b/examples/shaders/shaders_color_correction.c @@ -0,0 +1,149 @@ +/******************************************************************************************* +* +* raylib [shaders] example - basic color correction +* +* Example complexity rating: [★★☆☆] 2/4 +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example contributed by Jordi Santonja (@JordSant) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 Jordi Santonja (@JordSant) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +#define NUMBER_TEXTURES 4 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic color correction"); + + Texture2D texture[NUMBER_TEXTURES] = { + LoadTexture("resources/parrots.png"), + LoadTexture("resources/cat.png"), + LoadTexture("resources/mandrill.png"), + LoadTexture("resources/fudesumi.png") + }; + + Shader shdrColorCorrection = LoadShader(0, TextFormat("resources/shaders/glsl%i/color_correction.fs", GLSL_VERSION)); + + int imageIndex = 0; + + int resetButtonClicked = 0; + + float contrast = 0.0f; + float saturation = 0.0f; + float brightness = 0.0f; + + // Get shader locations + int contrastLoc = GetShaderLocation(shdrColorCorrection, "contrast"); + int saturationLoc = GetShaderLocation(shdrColorCorrection, "saturation"); + int brightnessLoc = GetShaderLocation(shdrColorCorrection, "brightness"); + + // Set shader values (they can be changed later) + SetShaderValue(shdrColorCorrection, contrastLoc, &contrast, SHADER_UNIFORM_FLOAT); + SetShaderValue(shdrColorCorrection, saturationLoc, &saturation, SHADER_UNIFORM_FLOAT); + SetShaderValue(shdrColorCorrection, brightnessLoc, &brightness, SHADER_UNIFORM_FLOAT); + + 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 + //---------------------------------------------------------------------------------- + // Select texture to draw + if (IsKeyPressed(KEY_ONE)) imageIndex = 0; + else if (IsKeyPressed(KEY_TWO)) imageIndex = 1; + else if (IsKeyPressed(KEY_THREE)) imageIndex = 2; + else if (IsKeyPressed(KEY_FOUR)) imageIndex = 3; + + // Reset values to 0 + if (IsKeyPressed(KEY_R) || resetButtonClicked) + { + contrast = 0.0f; + saturation = 0.0f; + brightness = 0.0f; + } + + // Send the values to the shader + SetShaderValue(shdrColorCorrection, contrastLoc, &contrast, SHADER_UNIFORM_FLOAT); + SetShaderValue(shdrColorCorrection, saturationLoc, &saturation, SHADER_UNIFORM_FLOAT); + SetShaderValue(shdrColorCorrection, brightnessLoc, &brightness, SHADER_UNIFORM_FLOAT); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginShaderMode(shdrColorCorrection); + + DrawTexture(texture[imageIndex], 580/2 - texture[imageIndex].width/2, GetScreenHeight()/2 - texture[imageIndex].height/2, WHITE); + + EndShaderMode(); + + DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 }); + DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 }); + + // Draw some text + DrawText("Basic Color Correction", 585, 40, 19, GRAY); + + DrawText("Picture", 602, 75, 10, GRAY); + DrawText("Press [1] - [4] to Change Picture", 600, 230, 8, GRAY); + DrawText("Press [R] to Reset Values", 600, 250, 8, GRAY); + + // Draw GUI controls + //------------------------------------------------------------------------------ + GuiToggleGroup((Rectangle){ 645, 70, 20, 20 }, "1;2;3;4", &imageIndex); + + GuiSliderBar((Rectangle){ 645, 100, 120, 20 }, "Contrast", TextFormat("%.0f", contrast), &contrast, -100.0f, 100.0f); + GuiSliderBar((Rectangle){ 645, 130, 120, 20 }, "Saturation", TextFormat("%.0f", saturation), &saturation, -100.0f, 100.0f); + GuiSliderBar((Rectangle){ 645, 160, 120, 20 }, "Brightness", TextFormat("%.0f", brightness), &brightness, -100.0f, 100.0f); + + resetButtonClicked = GuiButton((Rectangle){ 645, 190, 40, 20 }, "Reset"); + + DrawFPS(710, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + for (int i = 0; i < NUMBER_TEXTURES; ++i) + UnloadTexture(texture[i]); + UnloadShader(shdrColorCorrection); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/examples/shaders/shaders_color_correction.png b/examples/shaders/shaders_color_correction.png new file mode 100644 index 0000000000000000000000000000000000000000..5bf5dcba6cbacf17e713302518dbd08fe5b73561 GIT binary patch literal 311867 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 z͝Uz7Vc`~TmESNEU$EX{F2P>tnjutGr~$A-qo2bNA!j@!`nxU2W#wtyR9Yp$O- z@UF?^l6cC4R|itfg}1wTNM>tJaK9tY&^UoxuJ4F{7RZ7?|P_pDe|B&%T4 zd6#vWryRJ23Y4E&o+`NaSVBwXV9PPZ$=Z7YdJIa1F6Tsk__Xd~wOO)eTw2}A>pRwj z2F!F;GF{YZv+%!C5J&L7h0VHqIt4Y%*{^do1{*rTTlMcU1ntT1c zQB7y_1q6fP zk%hrpGv6=bN_=H3vPgg}OVR(n(5Hs=2C5G0I2uEcyi_4JCG3&%g7+h3($`zm<- z{aZC3zl2r1Q{Mmk;q&?R-`@YZS1ez%?%xado!`tOZT)}RJZ<^PF~2#vf_Yvuo8E$0 zhcIn{9nA4fa60g` z#Fs7+TB>q;&fBkNuglG`InDp(K}BI?>;X}e3p)Q|;x`p8+jE3-XQ)1tN8F3Wy5~<$ zf2{D|L`JXQ?wf*KWocc9{E@@^YW!vDPT!q;;qcnBziGRE#q!<%em5oQV??f1s&?MA zJM*7Em{&CG#?}h1=1Q+y+ICO$B9`zk+$FWt!$|);@0`{0F{ZZ)y&PZjXkMQy`=w~F z6<6BL!&Mr812bwQ+JwAbh6Tl+s7Mz69@Kr}oXZxEby4SIjn_GyEj;pR&GHZ@{=^(52=v`9MwWSR6R`^^_ULVP| zGV-Xy@heo>>&NOR|*SD$vPMUbrlHOY$DKT`43m4dZzTEu4G_2`)2@4W^b}Z_fD#@-Td`;>6O97+C9`&1d(nB*} zT{&gcZka08#?xgOEs*mt_2nXVubKb%euz-pBF3^Q(DjaFtJdNP%v?t$6kp7l>k{F# z=C$PPb4RA1NYYh5Hu3rCR|3bhzh7_HT66sG#B7^SzoSoW-hKW44Zk&iN*3f>-cwv1 ztiR(WJONx#p^Os*?e+XA`=~2Rewpn*JQ3dE4L}YH}ZO)l)IaBVY7>Xmr6R@ z%=3q@7VZ9IZy4MXAO7a&t@J;SLl2q%o%#NO?EaM+UrYNRM*mm1e=4!QdH&CLUFrY- zy#KM}027C4>XIUspfq90xyu?JotiMCsW52)hm?Uc*UqEHK^_y?y!`uQuHWFu^s`-k zp!~rXMxl$6OrdJNQe_LwlT>(%-6Cx#M6F5NQt4Jbt1XX9Q$UzSXORGRs6zUdW#viB z>OWuc-BS^q8hBE)qw3qN2_dhpBqbdT{$Ld`VU>u=49AljGc+yB_#cO#|GRm<{r@Ky z_g*$z^W^{ElkHD8A;%#gHg=V#ii-n&NyVv--KzJAH#HR&k7T-I3czsdD ziI;-6Uo-r(+T?1rOl^7i`(R_y67c)IHK|8@Q#r z{-yd`}uRJxc$y{vnEe@vqs}UD_ zr>?k_sW)luTDhLXg)8`1o|tgn&-uc|SqjfXyS!eR+}`T7Uh3*X`%jA7Dkb{MH1n^C zUs`LrBsTNRn!Dmj99x%&=%tj%&e~-4BxvQlrydVZaf>~_Y%%j@%*xg~XNm&nDYyu# zIR(2Z9n}#2czdFgu%v=2L%v}09JQ;<_K3|~`C!|QXQx~08g$-od*cS#?bi$~Ap$DtFL>)pJW@w)v0Z>lKX8g|gTZZ@iv9sn&FJrE^e z68qyNpPcyhD_<;6-{JbwwZOwsi$R-3wMFvf%kIT%g#wD|%HtQFe!A8vYSp?Rfe#H+ zZeIEqQFP`{`^z)OSc_F3%+zvj71?uW?xQI-=EBKNhwglt-?Dncm8K-=joP{;jQL%s zUhFcmUCeW}bbsy2^zv&j9~G2u-}>sM*UFZX94baWTLXv#Gbc1cCFqO_uT2K)dEYm!t1A2y=gw` zaLwrWJ?CX!N{kx~+7y;K>ZEr^a;QF)_~mVTKU&v){eS(Pm;Cp9xupL8)cs#K<^QkT zuW@@nkN#oVjt@*6ciQuA9($JhA$irxT~hq~^8X&$ z|JeQiy#2r3H@E8Z>ufpL)b-}P`$SpQ3W3Q6(_Yoom&`o9{@-Nhcfabt>n~Il>>7(FjsVxOoiQv*t zge{+*Z+^GI^!>@)A6#Z1j8ZB%rUySuZk3nVrWo%gue0;b=M7#D-|TsHEw*8Pk-;u&gdgtxaS{go2v!G*&)BKxiuXs~a@{jPwI+yopS!v#w z`R>5G0~U{(w3B<^9bB2MbCE+WV!Zx{kA&p)DI&8qE?#prTRErx>Al4Jq0*N&9<3_2f4)Af%GWfca%z+r z`>(RH1+xQrRTih*cdmrhJi{RnnHO6hbzlFAG-*a)ivWkD zY0=Sy73bOlnI^4dUHQSNIQrGJgdK^3hD#2;x%)P+!zHm`kAPa>Tea7x+BR3uKD&A4 zk~gcBR8urnGc+~1;xZ*grA4Q%h*X)u#=Dc zFYo_<8vmp9{{#Df=J|WROg34sSMrHx;zK);M~43zKFcOA%Ch`ruw3-cLF0wXZYD{8 z;h4Aau6k*B?Z3S)h+}?iLu2g8twbRUhGBt|d+&=$o{&mBDtJak% zzWV31?c&a~BHtY%OD>&Fz5Ung`!E0XaaH_!yWD@?+&AMJdj$KI0@Zt_a=$}w1g!fe ztzUb4>#A+)eLKV7-r1`A=G3xv$GxXN`}Egj@w8>DzTFHm&pEr>;p2|o9ifZA@1C$; z-2Tn$jgnKZg)ffoGT_KgHlLs@HT|8mk5{W}O~Uo$F0I#R6e^bRx;P$^$#*y~^~s9K z3rkOll+8KO6lPq^*ugYGw0spSQ@|XB4PO}5C(P9A_l`_+P?y!_k}P6ap=LZuxjoWj zb=Dg86>|jyl)o&QWhNkhiQ{@$0qgQ5U*2T?3fOZ0**do9Uf;6w(`|iQve$n&$NcHQ zDmSHvY>Sor?3No}YB2XWoc180N4DK$x&_-V=Y_go+EVuXlij-PLl&d{3?)X*mL6-_ z9f}K5&HkisaB7s8*~XW}(UdNg9`QkR6A%Bn&?W)dl^?$3ozGtM$$#SYXDzH3<(L*u zsJXT)&8F>)>$MdjjL#L;JkPK{uBGz$a){GBc9+n!axKB>8hODYuR~vMzm(tgCCK|+ z-0Sd^J%UGEZ~t@jNZM$(Mw?$g`umAl%X%``2--{#>0iP(m(OCd@RlBjX0bn9{1LOd zzn}ckf6nxBO3ei>bGfC4XCFp&s!f`jqLN;t6ZYEw;xA>P)8^L__H9mjA-(72c2yDE zf1B=q*|2}(vahB6Z(qxOGoR7)XIa(N`F7s>-hBUU-?sgyzui_tXZA(swzW^1FimS> zVzPpa0#~6_tx?lNX%)vAi`iT?CVn-1swbq;cuH_-PY7@7F2yN7D}%X??ctp#Qr*8o zSXR(&Y1RftVJ9VXW4pCeOo5m zA6IiY{i^m#=O2@*{#Rx%&SYpzuTa?%pzL1oTWjyPkN;na@B4I2KX&)ezwv**q`!}U zbAMm`#P$e2+tmC?F;X87as)0B*wV9VsYv*BE1rWp>Z<-dmOokly8R(bTubz6j>OFd z%*)S3Z?&1ff9qG*x@Y@+{@)XCf1bN_7mxj(=4hK6LdAADpKr_G%m4qamw%u6^m~if z95I%77U^yEIH+RA<(swneC_RFLHFX{we9*8w^g|-!boyS&Y8{C+Z3*S-)XtTKqcyS zoE+cYALm{>f3gS(-|Df_s&wkFMbmG2ZPW<8>K}P5t-?M0F{9DSnNRx_n+vW^ZnZt) z6L!m~&%{ZuM^tNyfxGKYK_e{}RcXaZy>D8&P8BTH;94}L$6d<3C8hZGs%w#MGbP?N zRz~Qa%Bh=wKwzq&)x5yDcPAh0kW7%tWK+3RlF{5J(l{~gfcv(Y;#~GY2j#LZ{gq#B zr~l_!{-=%2p$Qo+%EhxArx9h>;It6R|U zo~FrFn-I%sHI021PVgsU8O!gNaR^3 z$Ff0Z=Og3&%75!W_t(8hmj89b{r}SCyM<;SY-j()bAqqBd0)X>?HK!|@rMOf3quaG zH)xm5|G75)*VF$$_gDS>oUbxbz%H_;{>5s;-i6v>lR9TsH0a26DIc-0)oO}dAH+U! zhwU7j*|)DI1?+8EoXQ_{Q1DCt&9(dH8XTPd^JxA2&Hw*A%HRKZ`NNF#oa2e^o3HKY zRJ?P(uws3I<>l4yrrmgzDAj5dHc^<vYsES|Xj73XU0p02AEGmT?c zc`WTwUM6F8>V(||3sr&eDa;2o3cu~WVw&l|6V>MF#qot(>&{$_6BeKE6)lKrV|#8E zt{@ROgN-{!GH?Y~nn$bk;)}0hK8wCsUhC1E;&gC|N`;&8TIV^BCmk1TuWAu2b>V1y zCaAM^c~!x=!?Mq3?ph`hc|&y-uYTQ(Pg1MaE&;|!?c4cYD&Z~PS7jw*1 z=~y6ac{ojfs>VgdfY$XpVtTxCJ}`2698(q%(OGc%Y=)oLwVBxq>^7UYI9%lM3S3nr z`da!j%T`qvjWhbuESw2XxI6^}zirUEC3WF{{hPg~*Q-Vs-TU4h(SK&|dCSsQrSX3! zc{DB2=$MehInAxfo$b%_Tg?7B5==SFn|veqqeWa-&K9}(z3hJU`Oi11)7NcPI@EmT zvTj9MS-gLYp_WL1#qO;1wLPLAYxnoZ*;ilQ_w&=^>rbCexATteiQIFQL-L}Ns#ET_ z;$6Alm+RlIJ-7U`FaQ6Cn>i^8Q`*XDX|3m+Ov)BLs zy1%wO{?6*3Og|o8crz)AXJ>>_VM@i4Whv9Am2~O2Ty|&|TB&}8zw`3y>;9I_(yt## z%FLIz6TW-SyL^GGe||sp|L6D5e!t}Z72BT%tY2KC_HX*a{pm%eC*}Y3e6RoizjN(> z-D{>iGZq}0{^7LGfhk`X_W5LPkJB%@Kk0eui4E?eg0epsS;<|Gep2(XJH~y@!)g8aRDqg= z6W0?Sulp^}*-kOt+~~q`@}k0mQ*x@;TX*H&n_J+upfPu2oBu<-iJ8r=aWqP$e--^X5 zs-uZx;*qC|lvR^ObDk>3pEdvgZuL&tM?b$d&k>%!uS;%M>$Z6s6O-=D`CW4L*x|K5 zAO95jx9s|PJxQ}8**C>m9yf($8OY38@uiRNlR{dJtI@Ere-_)novpq9-qKgX zOO@>BD*k(E`+KFGX~g~XsjSKIRv`ziHqE@GKcz{+vrPGPVC39~cX(ntMfFwGn+g}q zz2GCq^KeJQyM_a14jRo*HOL@a*|N*jKYOw zZJWd%O^nP~^i54vTgGS4{9_j{sV?Q(TReHw6f^#l%DP9VU08g=(R8tx?#_;t?U^S9 zGhTRn@t8a*rpv=iQ^j%CL6ch-R`1`lIsbpV{r{8YZwvk`iu(Vm|KFF*&(ANd%Va8g z2wMwq?zz3>_4<bzkQu=T3PdX-sQhWUj!@@Oyy5TBqyXbwXN1m zYhBaPwfo4#S4u+Dbd)+%OyystTH1a}tGva$uT5Ly&$fUC|DT@S|L6YwKL=mc7gc`s z-z^s&$9A;h>F1Zr`Q!ipojv{jbK@V{A1|5MfTb^%^Ov2C|EnsKT|1N_{b^w{6epd=L?th z<=sAWfbFI39^abXpBOHi8fNfH`b^!O|8v{N{{J)X8~!GKCk3SFZ+Q=qXZL>H!fw|0$eclOHV>dS`B_4OP{ACVG zVKct(&8qWKyW3VQ{VOtOe&EvO(^lVD-&*&y)Bev&J5UW!9V2MP61qY6-}w_8IM^Lq zUzmK@ce-wQr;bIBW7wA#kyT3Re7vu>Joq5=GQvGooOw!HUe0S5j@0PeIlCSR?^B&% zQJ5AI!=cDuBHhCMuEilBS$%HRf|;w&Rh;~Lyy%}9wGq;J*(^FX@i-k zHcSZP(KQw*mRMbJYSjhPoo)|~atJ#vQ(5=WQ?(>x#S#^v2`9t)o)%rVpY!JK|8JLn zKDDlY@X@ZcW&S!-FKO;Q zZ_b*pOQc#SENN0dzq(mnKXk9Vkmw_9s} z;hTJCrH?(|mC9)z@%rEQPh0YT+UkRUC$HLl;Qhh###ubBlfRypF!euuN7OfP*WJ@U z3qG3m&n~GDF5LgaQFZ-k$J;M!ZeI>E=_{-)vb<4s&8kGEd!A{;^kUltFaDx5or+^Q z{4ooKliSbCpUblPon+oBlVq=mq!g|-%@@>58WtT4`L5`3ddb;~?|U|Nuh5AQww$=I z{0hg1GX;x^a(I+m)_5%T=@7hq?2f>MBO7d!^3pD|33c%YIfk7Qi+Hod$D!&#dY0NP zJ?)_7YIioamhkh>J^tf$(eKC8XFhd_*IDSxat% zp7ZD5p3`j7o=x9%ul4+u$y=v8NCkZ8Nx3AUWbggb`?P$u%Fg7%ps%UTSAl(tRN zZhZ6Z-87Bczut4IzVhF8DSm74rza+B-f%uYes{`WXd<7TpgQUCTunn6wOxff4)m;_ zq2zbYx@QZoiF5s@_WWHx97Bp+w;%j3yUo*y`L2Uw>&CfhZW@-48M!UrFV>XY;x>1q zW9to`u-fUX{T#*Qn(QXCyxhGly!jvR-`6{3qJJ9g|GTnp!n>=BD!JzJlwV&wIlGKU zcS+0j#LdT4PX)!?<+*t0sA%AMF#$cHWm>n6c6$oVk*NH%rr>D1xth_{Awp( z{_?D5#q-bo|L#4F{~P~&xB1$q_pXO-GV0WMryO|5r&e_RGu_EYpB6-#pZrz2WyB#`-DI*UI^SU0qtIEEaj(aaq`(B=@7&zGxL1g?|r! zaj7(L{`E}Xwd?H`-7V=8dfztXPTmarRrdYUE`Pl1)qPYm;&7|8+7!EadH;lOYX>FT z3U}SI3tCuUrsga&dtz(lWn2E5$tj$n6VH?;#=dlWA-pOx!EsiC!L~2=4zxzhf76xf z9_4pz)_2?WOpPb|giIB`-ZeC1;SoJ{p%>UVs<>gO3{W^QTWnOLOvhZ7s*O>oWe(GS;=X=7v+K}&wFjKAS6yfSm3+8Wd z(qF`yK9VA;p?m68FPlH=KEB7Y(Cl^Zt$VvV6{dFB-aOW7;}EE9>-o^fQ?g~w z4!``#^4WjaoGQ=$>w3=k<>8foCYLd$Ya~rL`OECI$JaON+@az*zr|Oqjntfb(Bj5Z z?MKXqKWO*4^F|R|i4zuBr#fEhn||Zq zcjLq5o_i%}{@yQg+jnTaf3RYH+?M&Tf}6kEPRlP~X>6_7 zw3xrcIPBugLdAmzBdo2Ic@0YxytuO#ar84Ash(&KSYqhAJ6Ee^*V)aio)yde4OZNi zTawf}#lnHdO@LK$x5d?|CnX%uo#EtPRcNHMu=%*~bMx@a>1p47e2jly`f=I1WzMEk zFBWHGI0egzeqgv~4tF8t`TW?5!J{Pfe)lKw zoYMWD_w&!;^!nGcFQ1>rU)3k@N18_I<#8!LvHCr=#A)TsDHHt~BqJyEl%Hbz_9fH8)Um)%;E0p%h423q zSl+8F=SrT?68VC;*Z$MjK&=;gWw#$JYT!O8S-E_ZANS%QwrSrI7O(lup}W>+rs+h} zb*JaPx^AWGzT4|*j_ZrJPal5yx~e|h%rsJhJW`>S`^2i2z^LS?rsczD${MXd4_$b5ZDy`d#`$)Uo2NG} zoo;(~iP+zxqV*L|+;3|}&eL1`I=@%!$M-k!f6kZJ|KD5tx8UpIjU|>n*%eP7mrVI+ zYu7jX**7`A0$%>>e;!S`ChWZ=d&^_*kE}a&l*3Q*M+Lpzx8r42>PdcA?&U3gmAY0% zmkNV2cg~v?&u{zdqv7%P1D_*9vgYfz`;{wgV0P}PPP$hdFwJfL3+>477GlD)9yq9_ zSp;j}*k_xP>eI6Dl<{KG33uPUl4f!EX0um!{ZoaKREg5xr>xq2%8HztOfT@Z&73dx zv{8F?FuUQ~`V`(iCk@jVeHvLj4<~GFIA-&>R@|s7DE!XLLo@0oTrz*$X8rW`zxG-4 z|GWNsv|Rt+t~twYzyA08d;cBl(&j4NnmLi`w@wv3WAk#CIvSYH5jU}O;R)9IDw8yI z(X3^rZf&2lt$ng=D|Y7nTJF@kaVFzuy}f#!OgYuT?#*AW@ICRes4eCeTQyl$(B^$g zpnv|s5Be^3^0UpShMeWm;M;iFakDa~(8LSNpM^}Fb+XTTlBXk|(~e8+t3P%8`4r$+ zSbex?!jBiPlH%{5iJv!XQ_XUt);pax-zyB;WG+=1^6vH)3cqX^TmP?6vp8zr(!=KS zZyvtQD{R=;V_em6d-Lmz&Gp*XziE6fFPwYr+s%qOZ)$C~y#BfB#9OiGZHa-t1s$B_ zDiU4NMGj&qNfIhm7kK6sWN}^+6OjI$_Tl+;4C?4cd4 zOoz*@dQ5CMZZ=ySdD-+V-o2VNAtH(AlovKEoXI1UJik$u>s_SPw_M0csTXpah-+d`Z%S+;ye71zT*ILZqJN1IY^t6>8*H*oo z%zxz3K5DJMR~r=jRt*p5J#`H}1n9mFoY!uc!X`ef|7C-}`?ferf)$nOJw~a<1Iz zqCf9GJY%o<_Sf|1hC@F)1E#3oTl3^)iQUbW`bS;;Pa9uddQ_ip^471nZb@0zlxknT zP<`>_6oDv9Lw&1h6F2kqZGW95{b!Fm|IRq&IFo4ykJfBYJ<`Ln@j>gfz}xByI~Qnw zuTAFxQ#lR@|f&ZoHnMbutYNDMtw!h4coWmBmqIsHxcGQGT*-P3QgGGEx zUhH#!#L-b?;C5`@qR2__18w+DI$W4pa_|8|cT#SAiQfjTX%WUz_VHi&?=8vy(#G$3 z>F3ixx&4!0J`VqHaQ?CSG5MPB={4Vj#SUASi@)>V!Y$9l-IXM64_&)KJfZqmD90JtA6`2S#nJ&`$2wJqo51E4pJ(2FV6m}*;LJPR5SHukn5Ib`J3wl zjjkV`fB)6d^?m!EJwE#CVR8@iCI8R2kN1D|npb_s?9Sp8|4sYy+E%0{y?9&rp|Wjv z{hlfRq)609D!nCtFJE=l&2GMDBZndQL5ndBs` zyD)l<>tg%UoiTh%N_L*eBF zm)YhoIc)-6SUe{-FK(L`bZOG91y%1BanCBA66({Y>=~kR_8sH1jI-V6rrkNayJg80 zbJ@M#MU%c1Kbd2yX?W+TZHViUl-`NnJK87tbSTa%k-S$N;dkjZ$LdX9KW41j|L2U{ z{arG0w^Eagc4zMS^2qk;M0V4{sXLjT{a5jQqipj(*M^0ybD4d`v{bu!_wIM^T`~F2 z+S*-DQm5_i_FeLR{lQP_TwnJZu!`IS|869 XWeIo9EE{+jMj_KI)y<3It|ASh4J@IGE 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

    f*6KL7FTEmd{}LI-qmu``b8V-zq;C+ zMTfPV$Y1~ctJe0{2g92)5ApwbF;V{fhW6X_$IsO9hM&K=E&hK_-UID4yP8cqZTG%? zmmM4Oe#W}$op(RWmaYBWe)*yhe-FRue#0;IfA({(c^c%(^nvT#d85}H-_Ji;lpA8= zH{)}yfPcken*uJoc|QK{4Bt&NUB7qQ-P?~Z-Ts#=n;dz^tNTOm$|Vx+@AN2LD=f%*^em zTa9xAdr7i}0r{t#x9G#msWrxQD z%ffdl^~(}fkIhSI^xHDMxwgAd?)OoNpV>?2SNs0mw&C~5hvMbmwAl0I1JiXGE=kDF zmH1T}cepa}i{Y`38$XlQb`+S(%>1Z6>)pIvx7bad_^o)T-WAkRcg%YA*LadDTX`}2QNL4Vw8+2)@IcS7vdBRF$=7IdGjl(jznW^b!m(<0sZ z-Km1ynyaJF-Lu}xuRZy>hW|vH-s#zsq}JsIt+!lx>7=3_uX;C((#DK)LP@#zQ+irt|TT zyP?+`C9Dr0`~Lgy!%*4N>%P1;cQ@94&M{r_*1OLkI&QKlvB4*wCuM|XrfSTuW&s_+&VrPfj<-gSo%omeX`Nwyukoa2W6;jUjaGqrzxVyDe6#Iu z{kEqM{u)oKNjAxGOTWL*@^W$C+sc_Uwm-S^c?R2JRW}2nh0`Z;o#T<4;`G(~-a5%h zjjr@{TnlaH%>4GH#cJ!smd{-&pBx<3B|iM{xfXLk@G$!<&ixPOr@eo^?RAmUyPfZ* zt|8Bi4ADHmhW6rE)@nU~>Jf3~lZo4VZtIsm|!B6h$ zm1&z#IviFN>UctyeQGzmcJa*z&wTS6Z?x7bbV{&CfsXk=ewdCj3tm<EpLIf_O_gV3pvY&nt7}T% ze{qu3;NSi9!njet%2YD?^eWUr&s6tkx}aH+q4 zw@=?_=iJHar@cids&13e_0r0d>-4>Blx8JcW?uu>K zl%b<;kk|D_8UjEnnKc;ZECxBZriN6-(D&x$|VBWLo>O=Yh+nC6#j9rCvV7 zxqA6ueHH8HhF9E$Een)u%FlmiS-0(gxzL-3Tt+_P&KKg}pZfD}b^WKym-D06U4OiM z{pHOSF|)Qk{+Q8kv}9WSg~RGmMQJlXbF1on;Q9CRJnOYp>%=Ua8hPRy;x;T|mU(Ep zXZFMcAA960E0e6AhaY|4cgs8Xs9n5`&fh&eN8DhsuW&x)){| zDP8HBuMn(Vni4eW0(0Tb3E@d4FJ@}Actn?SzB$md==NLrn+!9ve`d*k-+tO9ap#SD zvb&lEcHUTfL&jR7>}Mtm%d1zj%DH-`CtaT-ac)P_DTxlRwIYta$>}e6_>6CPNS5xI zq#p8-!FX@OMeEp;6O`_K+$x#ABXF*WW#^NC+aDElS?3vlIp2Tz_V50>Z8e`3zKeVI zmw)lUh41TLS0!Z3;d-g-QC|CcAHSaSk=sY_l}Il1VGg;ojr0Fhom*s8IPxYZ`|v5XLXl8 zW?cKFLE`F--i)PE%?YYXJ50l))aUPi@^Nk4$w!xB;@=1DoX!}`BO$1M=8Nz@$$xD1 zEmlwaVi&(TsqXds9rG*G&$9Z@!z}geWQscP9iP{pTC+X=p6%6}ul8PPd}&oU?2*CplG9So+?F9lX*l=fth|Rh(IT{$8=${q^6OUeAsZJtFA7_gLO3 z2l?dg6_r=HPWsuZbn8ZZUifX+o|O?VHnyvEt52WB6LWQPrEqSy?_S|j!O-xxvx=6V zY+8O&d0|xUms`{BE;+cTY`(bkq~l7TZ+L&aWZYb-ee%)5>z4yuR2Tbp#(lWa)pBF& zqE%9Rl}kMDa;}(s<>+p=!q*EszI`tIP$NHTOBSX>0DRnL2@iQ^=-C@JrIqpV{%e zQuP&I%j^Dph_3qoQm@9cz28sB;@zJ=35VW(eVlGKljmSY`S-WXwFYdgKUn^`|5&fr z&JoviP;%aZe!abin3(35zth^zAH!O4^sVgibFc56=U#sA)x_#&`%Xl*?G89MRZPpw z@%UUZPQQ{UC97Bi_2s;(TNg3tB)f6Nto`{^K&x^=iH?xM`%b<#OOu$BjNH;*CAn{} zt}jgrpZt5(3P16`C5`q>EpELRG845wuK7`F+{Ns%z${3i#O0$KXG??h!4-$RgkQ7O za_?Q~WR#?u`s&xB2Q~uC!c&;sOqvoWUbvyDyr$yn(?*qwWDb$VE_dc1+2O(StozkI zz3b)AXX`%+|L=R^1)`UK?y!jsd+RPYp|d*5I}cUxgtk_0GxRq2rn@lgY7v*|wtzd&+4-}8 z?lq|+M-Bjc8^Wa`>3tv(U6~SSYJTnGWu{vD?J|{QC2^9-O#PvF)*ffn!U0 zL6daFq5Z5DfA9aBQfu`8xW(URXI>t5KW_hJsp#K(LdiYrf7SSfU*Fs|W6Le~&x?gh zXYRH5X)5!ezNy~hyvYxtdk5tFJ_xb>kd%4I_)c5@eMQ^{b~&-S5~Vq(jGq6DyZ2(F z{gdr?_eVH!D6KuK_M$4>t!imW&;n5vW2bVH1&4MD8a?0i*Kba9%!Vnv-bXxIB{Ggp zm@!AGrQl#_o3BA`zHy}DqucdAyP=qrDEwX<|pYD;b`rWZXH%bA8H-1z$R(A~O&1I3F+H(r|`_gY#NLT11b@0@lDS zhF1K&=X{?Qel&WydyjpmO{L}kORHbrt~dC*`1*M%ef!#{+wcFqDPLRvuji?UMu{s& zi`Lo)UyMIX#(!Kh;ig`0_@(Q6t+%Uh=SO{h@OK3)R#VD`l#rzwsAZ z+_U|&;#z!wD^qtsy3V5B2O_R4Z`|C{DsuK1COt5?_{{tM_KQl(k6k|TJkt2DKy&%C zWp-;G+T5}c`#(Xv{@07O^P_ewuRWlmQ~0_sE5XOZh5ZeKyW8ROJl|!cYzwR(i1wQ( zmUaL9Ca_cM=h50d-r?)_7Z=|te`xplRMrmBO3^m=+Q{cA-4~=eB3CqSdoa;#vI7&N z+v2c1^?Q3B+-#yC&kC;W0_Z+FMmM4#hv>gML0!Tq5e zwqFW4ZC(9O+iHHC`@ZmZn>zbDX8!ax^V08Wt5%}^VPrpc3M_mru<>qf1UboS>JBoJa_u< z=Ypk0|NYj@Klkvq+&`P!1<_fS&mT4%WUOQPKgIli1@qSX2d!5WG-+F`-EX6uzq8F> zY+CW&^(*gg)jwafZu#U_Z*xD?>CK8dmpjkUoq5^^*7+NK1Y$ZkTd!sCn(qm2sdJjD zqSGcdX<~!gntaymjFg z9SfS)a{TDhPG0=;S%#6i)0>cQQ~90$UXIn@ZE>%3?^N-9{_E%eXa0TkfdBs^cE7Lp z->>^rqJJhmNli5--s{zKt1nEAsdp8Q=2qM0PPO*hlB@sblmGsVp!S65dz|PJo3Q93X#Ktt4`W<`h)3948 zN6G9GSF%Bh<&BEsYQH!>_P?K^WAi27zi7Ny=qfWgH^4|DXr#Huq2S7sJ0QNPv1 zk$7*xj>1RJypuXrkIs*K-{<`P<7X3p??)krZvTG&^6LCHw^ux`f5!K>8^s&D7CpGf zQ7XOC$0|HNvYWjLeSp{6!5)0T>FGFxo3UTs?PqHscx&ebPh z^jLydD{bO=rgwMan~f_|z8B{!9=oKwZnD!nHOo@olS_p9&Rwbba3^W=tg5YZB`bK= z#b%~*++p{4`{Y*luQ$^&vYcNxf4LRIbazR#e{*+dX|B6YXVkPyO}n>?xQiF^$9a|~ z`=^UeUV2CN!9#?ZZrh7CY5U99{bAbnE0*tnhyGOa0R1@a#`6z(Ta5M7i=O=8 zoBi|U-nQcCY3t{f!(~srvOSd7e{>hP z<{{^y{8H}j#h$c^rEey*rkvnw-uUV5wMp;(zsdT3^Z4gI_fHpoDBvs2dJ*}jMvX7} zK)=Nj-vxTT8xkZlr7hz{!>gX0Z9KpK{CZeBYj*VGS5|LXQVmUnO7gxIPS&_F!R5-E zlsrp=_ESPfqCE=3y3=hhZ+?&=*ty(9epdPM9FM+|?kK+`mr%u!uQozfsroMu=D75A z2ANu{E_9o%V_Ws=()kFvs`u5Fq1Fkx6WWjZ+D@6*v?{rKb=Q}tRu}J{zS1S=bLil# z^0j+e{J-3>^y^`*{oD3if5)zeg-vH3R@?mTkyrU6HuFb(THOMdhyU8bkKLX)Vd31Hd(`Ut4pc+9l|&rq9# zC7B{>hnYpMybzS>7e8-)!z=my7mu|oj4ZBYo|BR2)q28|qi7=}(IRnSTji#whf@4= zA6x6V3w(1DHW3o9TEb`7Z~gV5jST-!6`Or)@8^E3e6f)~qQke`T=Pv{UGr}LP9}F9 z!AB>*Kd*?cn)Pz=k7JYKf0rCTEwNzzZqb!)Z*J?P?l1Abt|G&sm#N8D=b&^^E?Txq5=C)6UEQt$Ev4#ZI`sPG0y$-&%#>rR&e$nre|XJ6w-x?xOS3 z@h+7&Z92U-iQV4rogUdSbK9>^N@*pIx2MS&&!725NP_dAM(2&r9F}dx3D*Ue>y{)6 zUAlF9o6EzxXLDmo+`0Y1+vAkb7kEf9>d6C+SlGLs#OuW`f z+Dqd<9QgS7`}a4$zs4ohPCl({_IZP{>_rauX%fj6r-hcZ+%zc*^!Iujw3tWnL7bO| zq2J4xn8hB&{$GMW-Ra6&7i*pNZU19y>ety>B+6zuS5&w>)q4Yy)7eX!oBsn zAuAs(ul@O^k^h0zw-0Rd4)K0snNz=kt64UmxnAdu|CB>7XI=35w#8|N4xeghuG*Y- zfz=+blZ*5B8Qg!iL%%RZa!1f=%3XkcK6ve?fAaO zk9XF@E1%pRn=LL~zsH5ivS;r446kgRk7Db1g7i1H%km#-xEW@D^V{~x*TlE=-6&n8 zuyXGujeXP^+f^{Ol=;?@dr>K{Ct(uP}-jKK#nEmf_|1$fT za(hosKK6LS871e=y#jY@HRWZeh}hkAHBn%+Vmm6hJgm)4{FO({im5tBY~L?~WrW2{ zr$02tWG0p#u-M}B{&}sCxnbw7o@vrr8{2mlt4cZXdKcy@ZRB_q<{~+(v{Y>36Rq8< z73&s%_Y=z&`|wqI$>lq?o%4K~*e=S|{P{7hKw-W_{~WbLj5kfY3+?>mYF|1oJvFIy&8^>SG`nZ@3Ga6ARrWsIb64~* zqrI`5$J{F?KO{Y}?z~^Lj{nKj`@#< zKaIPQ7W&WgC;A=!xi4ci^U_II9#3PF__b`8$fEieZKv9{Ml3G1xzMA~k$?1L=?3F#Z~b>_ z%ioXr+wqSlzD&SKWY^{&=eaYNI^Rp07rs6;e{9%6$F2#YeDdl9j|^hqk*D zlWV?g7XMi)?{v;;|K}Yqgcj>Rp0LxtT>f`aaQS>O^`4Z2vU5}?vK^YKdQsZqtfX~f zYtd48l0Usd($ZLK+Jea~X6#Ao;kL1d4Fx?nh8oLeUDaTlcBe`zc+d2z4R`KrS&`hq z+o)O?f9tA}Z?^uv{anXyPOi#QZ4G%Gpy{W=ve}C9;G~(Al1X-9r=6|0M4V}NF#onw zS9j8uZ}XbOGixW>guOl-_&oN~z0kc!9rr%qZ$38JV+-HORW~J!^43<)P3J4fbUyGf z=y(MS7ypEZT<2<{e|Y?Cu2%WrRB^ZRw_x|;YWvn-59ExW&N$4m^tI?iyOxWkZx$|5 z_rH+6C4kA+l%o3kc{UiO)C-*-en4itGEUI^}IsNiX?bC;A zmfya7cWuP(sW+nvXXR{rnYE=$cLkHuqU28adSlq)dF$x4Qr}CJnOD~-`C2VEq z!A#C6AsoESohb`TRSeqJc5k(N`!c96Quf_jrOlUI18a|_&bX;}VcXvDh#MIxjPGPa zm989{buZXD_`m^aDM`KiJHClc_X{X%y?K4fdEM%~3=wA*^CK4;(wF2X8Vg+%tyRc4 zuE;4-tF~sV+};@-Ql<*Lp-KLG@7R1e^W?&~Kil4V+dPlZ+%?gsHTRj{fz~u}-KQ)ZUd5X(w?43#y{l_tUc~a) z3nFpb{T40Z-S~d`c87vpxw9`#iF?__k+eea*x3zNWv%q2C7ksNFaBk^p&_2>vy|)m z)W4rzq{Uy^-`{Jr$oONA=JGzLT#1ZCv7{ri#^Q%dly70vR)S1iWsn755@sQ1j zv_o2NeysWUuyU1+-p}azV=wKGD;eb;Ke3>!CbTmk?U>h!*|EAIRf&EE2GZx%Zz!$YnOD*i6Fx4yQB-68bMfa}ALK;N%j9$Bf6#tYbMUYK zkDgMm^t$@9`{LiTUNhg7qM*G`?Hc#w0P!huSF3z9?@PDrH0j-3d?(b=k^6} zxOZzp)vHx%TQ41&uq5fyX3;BR;x9L@_I&N@!*NM`!44PQy}pJol@{*aQN^-(X{FfY z>-v^!#GkO--&wMSPrUw<+`5C?JswT?arRXERQ>f8dq22Y+%K%Vwm;^Vc>cH2Iq8vK zF0PwW^tXHMA6Krx#|Mja{O1*%;Ax#cccG!GS9q1U(a9(n)~%nDX7w5Pd*wm2s*Zi|ozyr7e<@8WVMnm?l|F4!@;3n{`#Z(d^vQ33v9%>G2*c zSgHQ%`lsSks^3#X6XG%jTNHK}TXPyL5}Go3WALP$h3450R~_O|yvV&OW#Nx!5#RlK zDwNE8HuO2>M<023$5T1T?8on@qIZoOCM{I55@y@e9KhPTpulBby8V%f8_U;z+wsOe z=bu2db)0SOln=*V&fA_}e<|OQiTi|TW`#sjVdaDi-}k)wb<}TPu+$`u+|3{7OAE$0 zcJ{KmMEJU8KMuQQc=)tC)9#8@J_UDY^{kqmKi9js)N@(salgbR)LqVw?OO48=DqFQCPtJ(QS(LcaXiLcQ zd$W!UROSDkwv;6)#wmQ`T^+ewGrn#+skqIoy(7r0Tj=Z}{^!pWBR9N!p?gXwrh8?N zZTRfP$1atv%$_Kg^(DeRYx|wr=}+#M{=MnF@B3Bl`>{6X<8!}79TC{kC~VU#|IzVD z^SRR}{N2`Re_sDFeZ9l^vYTk_|hnt50G(&Kh@e~#*ujmLYRH-1rEF3f2s;Fh?u zCj7_j*|zLz6@@>AugCj|i~XwiU|jQm<-d3R@BhD>tx#N>)qVU!#>Ui$d#%%+7uH|O ze7o58fc%G#yzh_Xr_X#pZS!}t_VDthXTMqmpObxU^FqzSBsV;Ig^h-_GkaEQQ@~3> z!J6aTJ6Q8w96okfEzNzl>ZrE16Us6ic%hJUI2|D2H*(ofpY=Y37{>$=wStFxgGKy)!Iw#yj11gB2^j z-z$GQA!ts=`X%YoedWngl2)=^i(>;5UslzAS(5z!OMy>!{f*aciz7Dv;dqv@d&c)U zB`@a{y*zvK*KMXt+veRml{#VT#O+r1t#f&0{+!yzdhO(<%8onR{Ka4YpR2V_r!U;a zz}3oOitpjPPd*0wYu?^qoAlhVqTI*-JCF4h&+rJ+ZC_POKDdEwBFla8r#>>qUthPQ6*}t?D+<-OIL7p?MozxYN>`@Cstiq}-m z{_^cpH_tTNX;NaArDPW5b@y!Zz3@-#mcO&Unx!`>E90h%^~&W+YN5d|)=8*63fy!< zs4VKt%0j6nVw1X5C+ zeCCqKv&YxFo$E6lJ@%>Xzt(<1@zbJDhaPbC9GBnxf8E~~^UB>HDNnj2{He*^|AoTL z^oj4^%@Aq))N$9^ZViuc{bBuxZyfy(4|lJ6ZEz^++OH4#)t^4zzbskv;JxqvSMfgo zKYjaL|EK83!L@r{JfHUK?%~X=Os?OO>vFq~KKB24kK1m~B>TRlGLh5no&Ws0czf|; zwmkvDOo20aqdN|_&76~C-L9D9!p!NCzUoZpl|uD?i5-mvOTRF5l}^f^5-3>a_I}C4 zhdrrGxA!D|d3)^o>D0epmu2rS;rV+>@5}>P+sb7 zdR#y3SI4GK;YRC@E|ZR)Lpu%17^E+Fg?l-)WTu8{$d)OWq->Sud{&~&VVh(ind~g& z>v{Uw9qy?D5l$RMqC2meRQ<|WSN-Mq<3E1Oj>}6rANkr>P&}h0LQ^0wQ+eeyyKRLI zZ&DsVzkc2S*}sQ>_h_CKJT)uu@OeYt*U@RZzN*a~+kNjGX*jV=l5zE%#E6ZHcv*bE z?DJe&dO!8;hIJJk>r0QN>Q4Qdt8%b3*lAOfp-9V*(4;S|uG{=XR$X?~Uf;v8yK&tc z=5prH3#ApIfw$`te*a>OJo@O>4`#tdj>{X%d@i=VU|VT^aIWD*=C_GUFZmbAKdt)i zeCYl{n}ow<3QmiyMY9tAH>~$FUdrcj(AaYV$HegSeDQw{eR*op&TeYC^rLK)_u5dM z(?W-GPlraGU|Dk8aN2>xog8vA&+oA|^8M0rU|%q=^<>uYTc6+wdF3PCF#h&MpTpw) z1zdJTiC&j$c~UV&^yl(bu3t3FBwI^9O*{I@r|;UX>lfUoc1oQ1zVhg;wpH`8UsQ%2 zcIF9N6C=ELb;O6j=={mkCP%L_&G;-gy@`D{*BP&OPb|;u-ZlUAl+SC|E)X~q{`{;&@IF6HR`xWOMy8YO6dwKoUJx{_vNW>jdHv3-Gex_VX@ngpE zwI46sD1CL}L(e=5{TNO8lzp}zQdHdRc0XP9Is5zy{^{15heYojxVkigzqc`^5TmJay{CCrHj$UovsfEeVN}?eznU`KvN zFdY{DG3nBZrQQlpq+TuJmaDtAZol>3+rRR7zfF&g)>BtGc}+Qbaef%bHLvjZpNiMl z2Y4|%*JK~wxj-`8cH{$kltinEg^yZ z5Bz1d&&;%*an413t;M-e!T23>W;6c(6zQ$^J~HxiXF0 zZg}}^jnFsib?=wiTk-rq?))z|Yq@&VL92CFj$PPzL~>b=h|WdPa1#OLzX$#nRYm8& z$%;>vTdumTc+z~G;BS#hR|SrYs44bl{wp+eE|fLR(F|jqdN@6Faw!B{Va3^L0MW z)vR9DPvVM&%$;<$_WO$7&YqPm_&r-T#`j9L`Fpcn*OqN$k+gm?E4SdZ>6sw*_nUZ9 zW0qB}y6c_6o};<(xm49V=CxTLE{Lnep3C@f&t!g^TDQv<*WAAB&jLaDAExbJbzoO} z_75JZC#N4oHXk|O*>9~=bMGVbrVGa0I_DD4yT3jxTxakpF>(2VC9Au8|60CzU^%6G z-LL;r(r^C99p@Alsbf;R*&eNZ|LwwM-wNi*U0s@4k^R>-{LBikHsd|7_J90w_jvJ- zlFW)_mZ2HPgv?ehlq?K7F7qrmYJ;X>{<+OlI0|p8znr7(obcSn^x4$wZ&fxNtGlY& zc#R_`W4@520#~Tsyv!L7-t=rLRj-#*;}GQPDPU`V`Dpi}OH;GNf0~BoDKloUuu2?I zE?v9bG-i8UNaJyFR-uPiIs~uH5J@#Ju-TO2q@>BWoa@|#4Oaz27>kbg9E`m7FIr){ zsCQr3E3Qag9RVh>gPL9(OW4%C7U*t#mXq+iVAsEdlrKB&vdXb%{8|z6F9bYefY}<+`OwE?Q0b>yCJQ9^BCLp=fQ_m|LqYD-z+mDpJC@z z3;pRUyV6*mhwOa&B-2{Md$IP)zyoiaG~gWr(M;pg_GwA2ITZ(3R_@J= z5W8hs_vqzW`}ynnet9kOmi)Zm=B~ZjPu3$GviT+tV>)>G-ngAJc$dJt+3eJ;w{Q3C z-u3G7qq^xUtluyGr}CsS{Dr-9+yx`wOz!H#4%!aU9*p?~X)`Y_zs>x~Epo>B2&M2t zyWs;M*H;u3wN3ohz~wc;H_UP5wPY+z$6q*^fS#|cRP|YU_ zEdiT7%xf3dWte%I2yTsO-m&|{BgL%kt4dCE%d=UpoOX0})qb()pcQ5<_c+}-E4Mr@ zOo~sP>9eNuxC{TgyPOAm;zI7K>P3Eb-XO46c&n72?xHlYD2|i9Qg@$kd;V4S{{Pjv zXJ4I-tZrrBw%^}>x~J-cS^RH>&eZJMvEX|3ibJA0Z`!&~YaLLwIKUedf97h<*YKa$ z|NRXue{^4e&B4lyKkr_?|96zV{(a3Jt3LCEUt(`f{djYNUFP%lzqPaT?bem%9Da7- zr_!Id?wS5et@gB@Xf|4J_wLvu9_E#o%6-~=b>=#nnR7cyY_I&Ido_HglxGunw^0KJ zZ&5m5%E49^u}tj%uMWYzH?BA5eC_x;?NzpMSRG%?gl^u~H815(U1wPGFlb+t|3T+l z3E{~HtW2F0xfB=fV{~=hHv4ad=Yp&W%3A}KIhzWFZ2sMUvp2dYx4P=?*Wdg8r=HvT zYSa09zu(v`_rHJVZr<+8+g@7uF)6l8;AZ1wRdhV^wXvO}QGow|^m>m@7X678P3%XW zGO~&&ICTkXbT)|=Z7eEGQZL(m`R=>dJKt?C4_&+U*`N4*{q2_NZ%gmoT_*cfV)2{( zUQ0K>4p|#&`aI^f{WFQj(#&&THtw7#l$7CS-F#{Lg0noT>#l^K$cTTuRppXY;vwd{ zjvuXU6pWJ-qPG1$c5kK=Z!m}WT~R$dV@Iy@d2i>g+;7DHWp~}fm%^D{pLhFAWt+TN z|N6eu;kg%@7uinBlq;HT7~SvGp0|31?cBS}KQ>kWeifHwD5)!E=Kkzz#?#vi9D8|k zbN5HS(4KPdW2(W07v7gQ?>%w7Tw~v?)iu>ibtW$N?odxHy`;OqU99f>3-7p_m(D+) zB7B}bZl|J~Uh6#1%Ur*wncS}C+4o0xU*hr9x`M5Vxq`B>0xvREpSw62-&-xCRrla( z`28=d%X7Zpy8HD({`>p)?6>ZoB{5a&OXJFb_Y)@0S}7aqr7n@VF*hYol&P4zaryO{ z*E?(Xlux(mm+idLAE>rv@wt0~%3<$BR`c|!m#{OxJz}`vROrI^ORbqsy@%g+J&RvA z{k8nTrTZ=YH}kN)X6)CwH2drffvJ@XcAkIqN`%)|cG;52p09sL>TyioruS&)dG}7M z9fnb+li%Iq>@CR7OA7jM<5=AHFB9#$TIYsLy>>k5!Xj~5PsLqdik^O+Dt5GNZ|uzN zlaEEX>Qr1#hzZc1a$&Ohx=GUvX9%#oy_oZ=nP=C2sYN0>9cNcuzu-V`sU~Z!^}v=xM#9LA!#9|KLNzHxGr@Jq+E^(tltvug(0& zTGrKZW)Hsd7yf1DN#U+PUiWFe%>SkO_J4ou-mO2c?Rx&kBS9gl0PGvgWCVa_k&CPQPA2;3A znf<%SYx>0h;`=HbTV!rZTPDw5vRm8bX4mgGtluv1+N&>bJn!*1DD0L6cdRF)U{vzD zD_(`aY#FBoxO44XWN_Z6Rp*O?enwMgLE~YG8CEY{LVkIOMpdTVO#31d?;9>I^uFr& zs~6SZg?}&WmwvhA*SqkU%B*S?_YT>-^*ew3W!ju&6`PK{eQnOZYd!mmdDo(M94z!c za##1x)XQ_(d^OkH31vO)-TUR&<6}|o%|&-N-L(7g$LpTQ*Z=Llf64!@++o9@Z(BS9jJ|BQ+{b)6=PA=9 zrr?H&lZ$)yJdZMI*t*aESKq5Qce7Pl9yxf;Fg(K&-@AFSaQO+Svp%Qpw)%$K zYAmPC_EvE7M<^e=ou>59;MQF6_KW;>^Is_Z+53>c=Ix{Jdo1@FelgVxe{Wj?{o6pl>R#o9KLM0Ya;UXOdi>2${+;IO!y$AKH|rC-+OoORxHb;}Z8fiJw( zx|O`@k+18l^zS&fmWKFki!^Uv_QbB;a`>UY!GBZN<`g2O|s(=27 z`|-ofw@YuOax1>yaQJOV-}bNBpZ@8VA1~!vzvbhTLXY)#wq4FUwQu*jr;E?`ZrZp_ zRL{)#(T1Zx?;}-MNRiJvZ8$W3nuN`aP{4 ztyf2Ov@P51tjr?Acdp>*(w=>{Z)$H}Z}+dV_Q!*FAHQC|{PkV_)W(lp>t+-MU$Bn* zsUvm$_Fb`;ey`71=lya|>(#QXkWSqorg}?LEjv``>`HMD$DYb%)<&07<{pxns^KGC z?0WyW{=_45IvQsmC~=yntS`A{`fJq#zY1Cxbfm5k>Y1?7FF+_?nqq2|8>j%h8I}}6Pc!#KfV0E<-G6Vs|(-Nx)D={Dg*yV&&wg?u{=au}Czo2H(A&e3G$>(P~_H|5qx zCQi{iFS|Ic7n(-7aj&}K_98`@D*LD4~x#ZoGdH&&v(Ae(s)=7k20wUr7Aroy%j?>*xIyE-!b!Sjtvld2RXTIomeL z>fc^4DgXbQ^y`&RSZ<5OWim7{{N@$@_(P4Kl-qY>xu$FzBp zEoJ3tY1N?eRp?>+mL(U3X5FxN$$1@r+NbfdgJj3qMLvqxq^eG@?RO7vy<)@GxlZc& z!4*lDlJfTzPoG!i8M~L%L1lFoZPN(P&6hd$m2=qY$M>7g z%$q0r;Oy-C&&}U&ssCRZquCYrqV&xwmq3o~c4aY}wk+SP@JZp9K#|Tz<+zVCyXy)n zPHDgAt-oTlaQ&>g+PRJIYjrCxw~3WRyqu#^q2{P>;-3DEwJ}&lRVHewqwo=rxf_nC zt8UsWvHMH_ldizrYcJZ|gHj57I1=wlia$%eEq$_k!{Y_7C3oaET=Na%jb2xGGtE;v zV!`3i1=5xeoZ2^}q?D=X@OEh*6k|?eaqhWy^XwLv7aSSxWh;{1Odnn1(G8d=%p}n) zV6?78U8T>hbkF0ioXx$L3TCjr?P>J%tP)=>;uW+>@!y^u-S3tZN@&zozcBZ|{WAQu z!!DJ4_a)cb-79O>$lGo+=Uc9R-fHby_e9AJbGBD^R%#!NbJ^1B_oes$mA78|`0XzI zR=l}EX;oxc-kAd}Y?mgsNleqM?M?WwFY5Ur$-S@AUp=hl`ZMYDh65>Y(;W(aKg!xD zZm=romsVPOa?kz8_m0{9kpFHT*u64)rP`V{ea`n>jGMnMHtE~08C&yv?w_Z@RrM7X z@pWGe>~?j_*T&h`u@^tNIdS>t{&{Wc+uie~R34L7E#UAe;NssSvs(7}50PCm?5p?o zdmg>(a6N00T1%fqQiQ5$)lwH3l?PLU@5&!;&P>YNqPi}7LE0(a<*+hryUc7qs?)oDx zTX&azeQ|f9i=7O(?{L{xrxFQbvp$%yH*FJ>J~$d|>HVSN zx`T25+iLzSS?_%}v-7XY(}qJSTm9ePXL5CBRb;c8bLyXM1z-CgcaD&DVMT$Sn=ch6 zW^Fn9H^$2G#Pl6WOnvVp(@sRVS?zAqu})sJv7*CJoh`(JJ9l$n7vncS1FvUJ1+fPM zdPSC7K6||}-YTT#_IKL}tt`r0avOS#t&DO$@=m`UeysW$8(Zx5A9ELQ8(%v2$GN-W zx@YH`7eYE4t~}6S(#lw#8X@Gx9JwMuKf~+I6Q9_uDcY=APcJ1XacL-BVG>??!CFkC zQ_{qFzt>WicOp@0=knVx8-I7tO}IZZt@gRup77J=Dih2;Tv=FDxn{ch-g%$@9oXl5 zQC#8iy_qF`A9O^LK8a6UBReah`+)fM#eoZSE0_3P-&%7a^=W*WuQ?A0E}ctllU2o89%Ws*I`L zJ8k#v6Mn6`ka;TjVf4>#>)#LW#?G_8rM!~^A?`u9EzxVrF{{GzG-%q`_u>JL= z@cYm2r~PfW%h$e}?$0k?UjFOfW%Inex^Um?O4EJWowLrSiSM=F_nG~!9PfAI>4Krl zT*BL2ZY(@-;6cU_QTdHiIM&bMvVACAcXX}d`In_{ld7QQ>DF1vlDbQtUvazD()qin zdy)4$zq{T>nQD*q?oHdaJi3_QmL==@!L18t_GNL$F8ZSBKiA-g!R#UrQ)eNrb`ZM9=V|VbxGCjl94M)dnbELKBeKN;jfeRYD%EooquZ!tDa7%KjA*l^y1dYkMg_k{=K*QaC}#nX5Nb? zr3WO`A4z^HagLR#hRj8~N*W?w^|dwTC5Ai{V}W%}dEDr{=9KzYwUb zU3$=gvpB>PX1Q}~eK~VO;=mLsjtM>QLL8?iw9HI= zps{48){ls&dbwx$(e;X=;o)7E*@C3+GHz7<-Qe5HXT}DHf@Vs&fHJYuR1QLDVDp>5sPO~vp1eM z|MvO!6ECl4bV$6+dpk1xJYQdWs7+(DevMV`lf?J-5s(<|w@uv&s9&)jj`g&$Et8 zwO2nK+NP)$E2(+2=6~XBjhKq9bN6&iTa*5x{DzEsrEn?t61R@mTMO!Y--xXaa((=2 z7C-Z5=UaO&GMlaU;x#zaVZgn2l1NV^2kZGW3SHW3H!Qe*xMBW>P6 z-}t=RZqC2?@$JhG^Bmqxx$Iy&?aKmP{7Ai9e?|H}>K1t}-cZP^xjQHB zoZCC4#}RLp=hxr)S2uH?*rp}5doI`&U3y(4^(b`ZuJ`=+cYeO>=XBe4#?8pA<*RPa zdv7zdRpIK&SxdsFN*HZ-p0#VCyHkYo|7>+jlV3`$>=q9zpIWHO6?-fFwz~WD)CErW zH;r@UCd7GxYW>a+&ao?vOP)2PIvtp{B1L2Fq#61O7p;Y!Pn*qmR_D86%LT7b(!NTk zWkkbf`YcO$HSbBwF2gVDM7At{7PV{I7M9>J!_C`Hca_WU*3uGN%G=WXsw7h|{OjH$ zl2vOQYaC)1J-v44lY#e_B@y3)S6ClNyC}4^e_E>ga&y93 zz2l}F+>p3?kL+4ij(y4L9k{bn# zWp&n1KlaO7|K?0i;re07xM z*d5CC=K0AteEW<%AHE3>0__Qu|#J=jybZ_pO-I{ZmoM>Q;d}3(HK2G`**nuLu5(*wSBXbpP~* z$$y{f$j|@If4d-a`ub~srOOq!yI1e5xRAZ+W#O8O9DB>ZFMH==dH3z2xs%E{k~~ty zFF56Fku)@jT6X>ITNPuAbt1?A9{F+4U=RP7uFxe5Pc;ixzI|%-QUQuC z&$?Qt-kaxUlC;??t9xUH))^(u8&g(!&fWE@ zL^NlUj&0`D9=A60xT%|H@7BFSK#^rxqaAZggA2!sNmFD~;+J30 zGyi_NaB|PBn_;uheLJ%4$2Dt{uFd*i&Rq%j+IaZF&O2r2s{>c$z45u_S8^RFq5U{$aJPHLCMhwr_IWUcF}8cI!n4RvnV^aGk4{ z?X~KLREGFA?}v8p@-FVYy#As@OTw2OQun6MDlGke#?VOi=e5n(=gZW6TIf=L;nCq4 zGd`zw@@MVa^l?{f_OVBczy161;a+IBxMIB3%GJkoY}rH0?LAKi?m4?wK4`A~vbw9< zWw)euv6o0P&g4w27GzbK#Pru8$MD9RSecntyU%FHKRC(1@pRAQ)3x88R%r^>t*}^U zsJ*LG`L#(;<0SnV`4>9QXYb7mFDbte{Ay*}y=p0@jl0@!%vB86IluO(XW6pcl8FsZ zl+8NcAI;(wd%i)M@9K&|j=4f6mF`)g*Tp17^n>qb*Ti?1)eAh1eX;QSyH$D{cRn%~ zI@I!Z(hZib&}_L)R~~in=Y=}+SBacn8$0XDlhBq+p{7dbkAHieRh)Z!cg>PN zH%-vn{(jG|(!j#o_r5e9F0<>u?R<6Z}awR26*6`hSw+ zpqFIbfq?sB{5ZK-qe_mAnV;vs&;Az?mA7qotRh-axjxjOBwUz=6Ha#8gXW$xV# z=2CBzj}|UfJ$2UV@%|&JoohcC6?DaL=s4tZzF9McrIle?;9-B4h2=+1^uA-+E&Xfv z!xPyHlJX8 zxVj~C5x1e@X`jV8i_2WNT^SeF(j~l2tav;^mCMznkv! zuiwJ^N!Ep8GM{+oJr=nv1!Ub>BHJ7x^Z=_N%njXXfll&+<#2`mXsC z`p5A7@z?IV^Z!12=pOxFbNA1kf4cua|1iG!@}p0>sAz#ElFU31AU1yQBM*$y)2 z4uw5VtJ?Ry?7lzux7;tq|MVtisk-yT*7&&vX?@x9>Tqz}!|M_&X5ZBAPms~(ckc?a zp4EBoq{GU&G9S3BR72>4&+;?$%jWjyv+7#yp&HsKc^H@d<+ab}*jgy1L7l?>Yqj zy6RlpTM=$MnWG}l z1-GZ%nCH0S{oXt2@$05DymqdW%FdqZs?%|)*YQK^sap%D?ml&+(~IxR$DL+{>R0CW zspn6a{Cx(uZC6z9qqGuk$^2dZc9l5`<)7{2R=U|YtLo)SW3@ujkIQtUi<|lqgbMZ- zpI;bxD(dVVZmTmArPHhAm&zLCe5qKK$klSQDQuBP0aLrm<%zMEg^GNZ?)t{LsMAwm z^%RS)y8DY)M|)l3Teq(};*z|>&b{)+ck&}%&Ewp;o%`zBFM9WD`X_w4>2aHX$07R_ z!F3JCKgia7dv`GWb^pHNzb_AK&$m1~zbgE`$H%Ly*Z=ST9se``nf!nMcY5=eI9Phl z*xS&*%jK>w{yKZ*@7)*o%GIx1W?r^i zvETN^=Jf0TZ+*RP_w&?M{a;U~FRs^Q4Y^sKv&c0`xi4Elq)n5N&HYlI9&AJ$~g4^~d6y>&mE-qZ(*7(Y;^~JA@#fiKp zrPp7ZId_3a!VB%@%9%S>Z|Sls-OhE?O7Qco<~hf=O5QpkeK+i#n^IbK<5i&x0@I9? zlr1l9Ja>W9DL>@Jp>-T9JMToUwzD~~XlMDmHNL4QfApEZ`|P>J&uiTlKQXoFhQ*P^%2zmsWLme9eFQExcEQ}7G(p>hM3C3_~E5TE=z;frcj z$hC`yig_zKT_cPhNwdUnoRY7uf2aO-TXop=H}ZktB=R*FSxk>lUp`>QK)Lm&C=^$S2n3v z`kF5J9>nqahei8xvojTIR<=33{;aTkq33t^x{a^*ytY~~$$D$huVXLE&a6;Ac%siz z=wo$QT**11opXtw=uFXn7g&m_;_jF%F#CUw2sCz{Nmw9au_^&OEa*U+oG%X?#0 zmRYbsyig|GQiDRcG(~dA~n**Y4Z(qPhEh-H&fy1?qmje41JQ)r>&s&Q_bS7JIY*lcRdnsJlt`&Qt``A>@Ch6Q|DtA^e zJBaal85O0Mxo8OXA89jvk&(DAV+og5g|fO|tIW2y_a=C~@Q7wND?O#yUlC9{>5Jai z_dS=VJP8pI-m-tvoukjqxGk&?biOUQc>nhM_j+=1e(nBp_j%ga-t(WkM!%qKo@R+* zj>*-s*89%47|vdAuHcW9lJ|(*vHnl=jl~b7kG|HQ=lzcJOz(?H##`6rKYwX=Kk?u> z<1bF-cdlRmB=q@xbjh2hOM2!v?wxG6cI*s?vJGnD2TpzdP>cndw zw>?{Sy4wEJ+3o+{q^~~}H@PQkdmYctH?ywYta_)E+_!u8rSD%Yo_E{zy4tv`zc*WK z(QzF!{>7&xo&NgiFZZIq&s29l@6$beg*RN}#OnoH+;3bK(ojsEDORX!$xYi;E-e^z6O_EYnK<+}8WbPWqI< zjxxz(aa&w{sy;ZM(3LLPXjmlJ#L^jS(7l&8O?m3Z@9)CZOkX(Wn9Xcn>-p;J=@Y;2 zOCR?sU}^vREb)GROWR+z^S58_zOX6h$c;Mgg7{CaslxK_C0E{$x$^fFzkmHB(#y%f2tY0)Jf}zFu&fUnL7XH?E2@+_rLjn zYJd5k+W$|k*Z<&t-#fp){*Uw3y7K+M?wHt}D8FCx_WA$Y?)yJ1|GmBb>E8Ey>VKd6 zET^_ke_rjQ{yp^-LHn-sz5f?|{P6oX%4sW%%!3vmWL;sfL2SRywTByyww<2lK5g6H z^XDrLOcgF!Bc#QAMb-GuiG&vE)vsB%COyO?e4g5 zXXRDPZ?ZCJE?n@EHFk;gqe%5nLUPv^9eCj&>1J>!&j@pklE zzeznik6L_;xbi1J@aXCauJw2N{O|3r`4VDREAmWtqnU+mz_dG^9j?z9#Z@kU zTk>RDI%klc+}Teq>+fAC`x|pTv#?YD`%Uoj0)y)^8nOx&g$K4tb*7%WoAWhf#sfkB z*FCYk!NQzA?FF*zfrWzNl4`yJHfA%HJUe(NcJg#LPM>wQQ{UySI%;|~Al7?<_m?PV z>6qxiApK-9$vcdzPi`%jUGzO9YMtSQ-0;`FlD?p5xNfA`$Y4{g?snWDSJdj84)`yVTJ|4FF(axG%dvhs-hE&bu~z+$iVq{_oSvXE)c(`qtYmZ8vjSzwEz1m$%pb`QiR= z2}|03Yq|ShXK!Ee_sfH=%k4ki*32~WecxtofB)}n)h?}bdg~UYG6bh7JBT)|x%TOy&XnJE z{INK0`>D?LH+EUdb5iHO-Oj!6kmHUA zuH~m+{d~E4b*!W9$U&n5aN*9zWT$gHS5Q*zeinz=usHCAh^7Te7u z;dYccZsR}O8ISAAxE0sLI?dV6c7?%H-E&?oo)$gT|5@jy4NmrZpsnG=_-eqYzwk?kW&n!~@=;HaiZg(I1zgeN%4(}K)xmn-l$Eo?1NA%zFeeM0HJ%4}I z>(7_3-&$S2q4r}p)5j0rzC1Jk^JSX3fn?e4)z|BOyb|WuwWC5y};or~i`_;PrufNFuLqTWOq~5(76uEg>m%!WB z*mTYt_jA>s@8iw4{P4YYUuyBPscXM(`!S14a@)$o4|AUHl~3CJ{@dDppQ68aMsinf zyWRHps}HZR#@uxt3SmXclJ_!%nV-@X?Qw`tm1FO5CL`y*#$kP*-B}dg0>83vLWtYOhZp&k?;o z?cW@ZSz!mZq$F*7U$ykhZ;LkLrSI)F&h1T$nPFwmo%AAI!Fp0M^Da4TOX~JU9&n$?EBs` znOkBvn0O0(j5@CRF=XYX(+cH^ES+-CET=q@+hg;|Eamc>s=dwZ_e&M{KG?lEchBnc zvZuPTO_$kQ554bOJIQ##vB;8Xc?PeyfBV(>@&CWtpY`=KZW}Cn9h<$ozx|8Lz51^Y z*Z=#z`|fA|mi#~G%%A-FdVc@6x%+=Vc>X`>-!1)D;rqAzJ~rFPeB$xl>fyhRJ8X-?Z1BZB%;obn5l|d4KvIA3i_h=t{Xqdv;g+Nq)OH{)zJZ?PWjzNI#U$ z|NnaXWq-d^U5k?jJt@njv{K@uS>M0j@c!JkL#;h00=5bMeX3m?ZLA>Ou`zr`e8jZZ z?0YYM{E&2nw0(Gjlhlwt*;_VwcGs(m z3-3%?Q@7+~tV!_SzNXT(rT#+Pf4lk|g4HYz_&#~L#+-y7FFK(Z%o3rM|FSNFE zaAK=E^hk^KTJ_~$MQTElcO(-geO>zH@1jem_j=Q8nBo4a<(Z)?wqZ?;{sFYj;R7|VMN~PqCQHUE8I|pLI3&teOs6ASm3Y42Zq-!{nKtUL5nW9Fl6`=Q0H zb8Kr|rZJaYVw>0=!_7~tDoLD674-@+2=W_T*aPykH${+;6JAu&ilnl*2ezAGAXZJl`{@cy%m%lSaoc{gZ zxnhgs>VmM(bI!Z%c;9Q^EAA6v&Asznx+L%a{hKEK+t~jneEreg-F2Ju?@P9cl|B4$ ztpC^c{eP<}o-dyNtJ(kO3EdJq>3R0@`@d{{IXk}I?7iRLgI|6;diP3r`{&vDcjwGI zdHmVpv*p&tJ3p?Tyw8g5{Pl%(@4mNxS-Gd$G^W0$ZiD@s^?g5Y-CF(a+TAbQ%k%4= zFQ0$g-~6Cf+)D+gpd*=yw$p;+%TNAx`Pv#_VIi8v7`yynngsLY^;6FuaNO9)_bhw; z=D8CE!wa@PHM;UvInU_*rm6F{H8gE8z4g}2|FiBD)`yPVB^O*?ykSyFVo|lsoa}h_ zrITS=Yyl>Rchus>qgv>0CJ>06dIIE0_M_Tt;a zf8THCS)P*I{o<=@!;JY`9skezzVr8&m0yoNt9#^sJt8oX*T~fM3+wX|{*6y}&x!av zbDB=#T)r|pf#U&YUYm0z)@^26y{0R=i){5N5>9IS zK2NLt{qB=R)PIjlr#JeC?27xPd8jzAF-7rv;+*$o+lxHil4fk)vM<~0OP!9*syBNw zc}lmPzNDAF_-B-j>#`D#CA-Wr@5vs};GQbB?$uZK)qRTnX0fk-|L3oMe=Ym=w7KlH zYq#Dzo_enI=Jd_yx4xRQYkKUmn6fz%(VYxW4=Q%Fv&8ANOtDd{U{E>2|3I|UokfVB znprY&`wcJ9Mtq^xAX#)|{SG+;g#d_XmSxGpgTNg_c>qn37vr z`nG-NwRzcRHy)c&yk&j;+wA+>CFkua`g-vwZ$i1-;_}z$U;i?E$^Uv*k>RaJi(^Fv zHMY6Mt90lKzf53R9G>w|=i8uY8a&F8VoCpT~Xo$Y6Q3|&{{`d#I5;1W;#A)$9p@ZmMK$=P2;o=uD@`YQ6w)b!3Y zjR_hbKA#eEJgBU^$E?Hc@Tm;TN6+op_x$V>zR38yG-1PEmJ45}c3-+`yV7#wa+{+; zFJ0_^r|0f%{l344U;g*=^*<6*u5Z4+eB3E z-}l}vw@ds#FLUGs__{wJ8{w7N{)HamQF zVT=9U|9yMy|2+Ni=WqMn`nB5M=o^j={! z7HDRb+`u60zizT6H)3K83%`)b! zOOh_R=G@~tq8L3xQF~4Em8HJgjN$p=s%(k$ivL!71$|jDh%$vOCsx)iY z@J&z?SiF+E>(gYmc-1ErhQ};!=kM6dP`0HhJO1U0)H&(7E^cf7+OhF;KG>+Sj-%u8 zfd{w5Vot2x^}t}(UKZxW8>JRK6S@NT*L?kA{)v53yz!;mZA!PalCxtjBy6aYn{`$- zOYoNaxe0683hU<0S+PfOPE#a*zC_-vUD_{eEEc3LY07YToFp8UE^vN^QBJ#>;CjEWd7b0XXVH4aKoVKBYG zmNwz)k947kZsCrY>t+ z(isxWo#6FOVDpL-$9(ps`th)}vrV2Hz?6`7&&O-#%A3`j`6WH0<{mkDfpx3gE5Ej4 zH)+2+Q|C;b`HFXroPEVp_PHGqi`n+)o2tvUKkkW)-K|*j>2dwFa7LE=eETVXk2m=G z#?O@h_rzST_V0a*`Wp;6Wq%)T{{B7Y*xBh9_kD}1`hHgZ|BpX6t9SBTE-5r#QgwUs z@_+}=+{*p7cs`Yk&wKLc?Z=DZ>R*0nT>iSY^zMe2Z4F1iKe{-(>Ywn;)bA?$zDKXG z|MDe%E`wl7oJX&i!l8MAPg@^lSsYt&CTz+cA2k=IXFp`!N`1J3U+|PLt<`TiT9+D; z7akN8etVNeV@yQlgtVh)jHhPy@Nu{?f7y59O!|)C#x?;5b7ti>_DPM*GpD;L8t-5= zJ|xJ;!E=DoMydZp%cO;z3{4Mtw=o$0Vr01SaMO%x#tltXv$Y!8JeY%4#5x&ScJBVU zw>fUd!s*dnv%P#>HaK#$y!P_Vy->|$c_q+lf%`6(`4`fbG^iw;JI`dHc&k+WVF0_4 z6ubBW=h+ivk{&p)o(Yh3v|zZdp0n^^c6Ajp?V0v%elwFG_t&i#lD{3&w+mbP$7byV9)61j zdv;7Z)}WZ^wPWV5)h{1>V##zDzqS2Ut@XyL9XYzTE*1fPjsX-R^MO;E>p51oH@v+Q#=2?@svQ|4U?%=!DZ0W(W1g%>#|ZcvnnI>?n&!JNF~Am=?Nkx7ce9SSVWD!!`a zfkLXiQ*M;c&?_=&4SK$8?Z+qQ-ntyw_%YKczcs5!{&GmDQHPC&uiQ$>&7a)f99Z!x z-Jr}%#5riz1(Tq)g6^WeZ$%DB{yfomtJkb7SK{KfN6QM0-CbrBbq7t_WzM86AR;Ey z^l`&a$1kE`Z@+Aeo#DUkaA5Y+*9AW|dRuH?*>-hVr+s7Z-}8Rc4Vdqh6y@j7U%U0& z)0f)cca?wAJ9b~woc~)|@RsLSE2`aUcF26`{{LeC_V@puU48!V)#LU5UQabokMY`E zTB~6yRKNPv-m3kNAIh%0e)QX0mn+Nu9`4rbo~n0h*^|GYi;91K@Me5C<-(i1)2e^J zg&sM(_-%en9EI>2<^4%CwFzlK)H9*`_5m9N>--&#X}T z(s!3db%uhq!Ta0>&xzl-eVZND-uO}EVY!$orQ5L4BI0>^ma*;yB}?W~=iav5zFSwc*%UaV1bI$%WPS{e*dgzH zZh=Ft18ZqsirnX(B;J{pHyc?FK4w`Uqb}n2V(G4=WsA?fe3AWXv%eKX>nY~$L7iDmpUVL{g#P5WmzZtzua!dO?FY^QuFHMGZPR_nT3DXVX^1@6g^- z{+chLw(B(W6vZuVPnNjGJMw6L*ivF>vQX*-Llg5-=UE5(8nU%~O`mOUOPQ6-d{%_5 zc~N$A%a*Rpx06DSTHaFk^=(oM=(&B;guAQoS^5*{uk$9(JkC<_C`rfQdaRqbj3S%k zi#Q*zG%2S=Mmn=+eu>jM*^(h;$ekx6JW-&@EwL%}9ajH=D#)pZ~gJmgKAXjFrE+6*Qje|Nj3k`|I+0{axQa{V|?j`S{nH zw-?P;*1aiu|LDV#+w<-|n6rInUfj~R(SN_3J!}8__uZ@S@9+C+{N(c4=XH&GC)ix~ zHsx3Dzs|u^En@R{n$FzBJMnw&z50CEZ1%EU_xT?8b_KBS{GRsp{G-Fge}38R`{glv zfBi*;t=^KRZe}J20u-4Hm<-wtEeU!w|ROicinmF#WcZ z6DwBk|C#b6zTt1@%S#t)9?S^XK403sO-EnAX-!1#x5WMyu7KSgHD-OC3mY$rJ+M1- zYE_TT?g-6uLVp@KVi=BIl+rlJ_kks-VgX+U$CLwIY6~SMIc0mT>h+niY3iJ*sm5Gd zMpw*aqs=~S={#`c#8Pd^IHR8}E)v>I60C;-K| z2~JxaS_O9OF)*=Qmj3(V;)gG0i$?ta@N~alZ(0BOlszoxHgN6fD|mh-_VJZkb3dEk z#&H#MUY#_Y<0k*>v=PIvBkhl7G-axrNbjH1USU&IjJyOqQK zs3=#DhVrV#8ZQ{k1P-dNP|^%?Qkmc^QNyNw@VhAUk7azT4&^5#21Ev^McS-!?vyVbw1 zjg;on(_|NZrJKlM_Ap7B)yM5w5>N9kcP)m+A8+Rd*FQ6T@Th$bx7E#~=gcp!7B0Lh z82j;6($UqHLf0(+B{RKC+uLuRy|L4tJKy~1?X&-X#n1o$Y5(2-d)MdNJzD*JSNZ>w zv-f}1&X4(jY;k{`sQ6G_-FT$vYEerf4BeP{(b)6`+rM1>?@`% z>wj?RA6*fUAv)^#@ zqUp8k+O;@prhGTf(U7cOm|fmz<>kPvYA`KrM_&8uy!z6e$%@Utjh0N$c-TH;dd%|- zLB^sNSaOXFRX=|E{CJ6U#U6EuxF-(B)$`6A->)qp7Z90JXnI(-Sy9C9;m@z|L4`5M`6EallBv?21$3kTD6*{XNC!$ z5G!d2*}|w)^1`b;Z_ebMPXu|TmcCfLukgS>f$DYTk(TAJ`wsppiEa^9*&r8n!SF(p ztm6Y7J%+=we%|e=pBWCf@I=JggmZa6Q&bJiZ_#a?c;ZHckLCrF5eH+HECvhO>)eABg8 zm2tHZ@BeMumGw8X?y@brZFl^ey3!w8>pi|cjQqW|n*ZCk-`~!L|9ke~nd-t%KWuMb zkNt9SUhR+I`p5T<@4xqU{6f=w?YfiQ70@;3l-~RO!RPkpgiRG)+5fUmk~?9o zUEj+?R-d?++a0_w^YrbH4}W`8>wgsY{eOP*!_;5zj!Mt}nXkvmQ?gOY_otJ`7EZAj z9LkEPjTWzy>{U{qA}GL-z`_^eG&|9O*J46O<|{ebwP~ThVkV=+)6)}iO)d}5cz;dyz%P;M8cZ4LJ}n*+d>*=!{Feqdz}5mBlu>bD^HpdPk~;Ly zIb{J$i+HTfcGav^CvG~JcsX^>;SQA&jw*EC(5~%zR%e>%WDCz#ixvua8Q!*Hf8OQi zyu`9%f`st$Ad3p+W3Mzqvb3VlOSSeMbW!?!ZkJJLgYxxAxkt7Pht6eB?l`d6Wo^ce zOKPU^^|C)M$#>tkzBxsHs?1B3l*Q}LU!3kdtClrrqfnIjYS{|gsW<<Q(b{CxcX^{b2L?RS3{eQnk|(|7yqE#;QQnRd5w`11eT=#;mY8{T^t zSNYt)^z0AA4|{HHlkE6?ZKAi|yS0hucQ#yd%R8+o6z>?f^~93?_HT33s`eaKI~H|L zPd_i-|NH%Ylg?Y$?R)rt&*%I`vH2goCTy8<-DyLEppk(^Rg;w$E4xCsi?nbN`|PK; zK41AYi*4rhQ>)b_OO6}876=Y%z z4BH&IHs~5(3pJeY@8^J0rm}O`t8ng~|9x01MZK zM&2VGO#%*yEayC!ML3!yl*AMlugm{YV&WU|dp%!D{lsRu!ieqkB6q4#qo*xsNad0)5BOdfBi}UjSWiY#na@LzuI%z+{@t7ubRcKsryT2 z$(|}W^!I>t`}(O17w>xPF>S7=^v6pZ#Cm_L+E1P`<>FWA>_s`Zvfux%3tk;`%k%DZ z5zjo`rU!!NWeHx_V_DU6WTYfyPi<%r-=G`4n`6;kXWRW6;V(V~pR-(gJZ$dX@M4do z-Me5-)ovk+fM;jZ-I9K=yklr$S=PYdrO+ldAy6bTfM+KoyTFE&$lynbGu~APUFy1{ zrtQ;rYk|bB;_oY(wyh4l7&a?uvSHPdC+h?oA6%HV+QRV07UkJZMyjRR+TLET{36}> zT}zr4RVuudWm&a?SHtM`5!1kc7C&DlIo)DuL0Q$HThE`plwSXrgJsfO9;>tKcn?dR zuPG_kd#&^E;>-=}c3Qcclts+$l-eO2 zdq3XZ|Lf!Q|6A4b|FkaYH@5x!(e#qUY3EnVPv%^nYkxZ@XxAJ&sbkmctFA;}3YV%1 z`*Frx^Xl>7&$Eu}yJjI&3rR|9@or{IxHq z*8KmM`+3{*{{7AWKMMYjPXB6dF8Q1B(gH)3Lw3r{ybGDKUa-8&;JA2LP2sSJ<-&FQ z+*e6R*fw((Hr2gIQRC76a&>BDOo;iPMVxz<@LU#Jn|wTEhN;;Us8p=O7D77pO%xLNfa9vlx&UiNQWz5#D6+1%0`BSc|MgH{a&! z`SRrV@*T&ouU@Kt!OO2Cq(%IkV9lo*t7DeTKBq$z;_B*Uc2D>`H&8}$1)G7A0E^&( zgeHzBVwR8N+WYE{*}ePpp>WPtnd?OdlfNpQXWVsi@>av3!@FkBx@c^F-Fxv1(@8rl zc$3mY5C7~rUFtP;vGJVg5)u;p6Y^eOc-67XJ;|kQ``Lfrw0D1-x-j>sT@T0lvX0!v zyS>&~c33>p>-muP*D}_A-HJJatp_eEadkFutU1K8_yC(o+nHO_b)6g=vnH@;cYjdO zk-4mK!@8k=e5pDlK3$Dmk!DuOR#ycj&cOch-58MQ>i(e|K$F(W*Z2`iQG`#am)o)fS{I zP_p!5)Y{P`d6+?V!fB%&V!AsVIPWzYEo0y+i4iKA#igpD_%?uPN%wC@Q-=vGPdYdk zt(@_rz_Hy}lJ(Ng?uCyVjqaEH&KBIb%-clvg%Zz`c^;n*$kcYV9J?s|i)~3kJNuP~ zeB}jBEVCLkG!zAG4ze8cPgMDI7^lB z7VFd#7A8?&*Sbl#i_T#2fv_|b}Q_78l-qH zW9gBoC2H$)Ux;nkCZTC)vv7+b-^w6wi6zVeB^+t|UQ(Xk8)h07r`(#a{&yn7wZP`B z?4M5OE!uZ)nfYqS|W}lt9c+QOPKG~d-{ng+7ue8ZOw|Wph z|Btr#<#%5<7nbk;y?6fa+wy;o#CQLjxGlfcZu1|8_Ck;KJoz=X`TV@M9h2?9SuNF! zWy{sMzdHBYD~6b_+iKesi)$9FL zF5kQz?*ID9;sbqPaNyovkA_I1Y<_RXpa*VS0EE~cW^3d=voBEaOFO#F?d-RKEyEE3!adFhwmnv|-@TqMvrxZu4^`ymb9XT`G zH~sIb@79Uf>N{n7wXdec&4gp6t9pZ89p5mCPsH&mU(*6JC(f;NkNI{zx0HCn6B(S$ zBb*>sDR!cxK!R~o=jPK|`O_<&R9*B7epY+CmSr6uf4TFzCn05>`R};i-rdC0X`d9PKZxm62~|*EE46kRTZn6sykneiu-J@^Cls9C?KKM!N?y%l%&jLg zw_^J16Pf)g6Q`_XS-!!*O?7L{QID0eYlZ8kNSpU@&AM8axbJ=Znv3#$HcWaAn@w+h zn_+!>ZE_o5PCQ?q?&`aT)7IYDl(s%3f&E3)laJ~bZEM={uj$9;=s!sRwR^ws`MUjk z?_FIe6`0`V6@7oW}WhW%>?zmr9mJz@H`+cL1o_h{6 zzU%rr?KMf>@;tbH|2u0bj+%9EQ}4bxeb1!o!-|)tzVR8q&Gvr&c47a<_jcP~+Z)&Y zdHuWgkKF&cv3tbY)Drl_W)(cCsskJg@U|ID=?vU3`rEI4`CR6H&8TW8SBMY*<&ClW2+FP6FV#pdYD zZRx5-tFH%$gdK8MYuh+8tJ%e)FKmPD;lFa?yk-Z=>>f4A2(+6Aw1zeaFmkytNr*h) z^j+}Qk>%tGULpMx&oqj->M{=t?3;5W`N{o{-V?=d&#*5#%6YhiW#`66^DIwhahmjq z-{ak^ui@9`Bp#*R+<1h0b8BR9snD0a;~RA9I4#%&80R&vJk0Ry=<+K*x5dPnPQS4G zb@T3H-6dDpRrWqz>%IPtP~oDEg%Vp`q)(>Z5Vl=@_sQ3tcO`D`JNURITXun=%gvAT zj&GDMo1v8_JGF3yLKEYW&fV3{zrS7maqhxCTbFf*U8aQSF&voPHl^}>ru#dat>Dot z#x?#k53gDfx!>^w6Q99^q@BBsoMrqJ+-(y?0{S~2FrC&HS^DDJ1V-Kt-OGKs9|D9e zVmy0$w-l=Lo!g-mc{}68-i=&O3Rv$vIUsS@t$bCe>>Z0GD<1~7u6=gl$%l<v{7HbK!st9Vw`q!VdVI96ON3VNlOWO+mG)M??S`V&^~!Y+FSm}E=ZGi)^Ddaiiz z53|R?)M-8b3gJ=PucYQq`SEIf^VjgXjF+|E{`|;(_kPlz@7MQ#Keb;Z`j_m3Z;Olm zy(vGxZhv#o^4q^lWxl3ejtQ@++5Pju#`*bKpB+k*Z|pGH9&CKIE=X7H*7iTomX?37 z+`n+P(XQ813T^~$F14Lpc6futzHIYpITDwbz1zNI<;scQCYdSzr6cC=I7$~PyPqVE^d~??TxdGnnT-y{H`anECj$j}K({Sqt^omk%X2bO>Xf&6n-?N{W~Q&9-ztrV z3^8KfBA&7{%9kiEdUy65hrz;2TV@L!X~tgxv8gGu|5?nruqCf!_u}l&r!r;l zuAOE7Mf?#gz6yvnzc91dd{`@CiYw2`hZje=l|T_@-Y{spB{dG-mJFr^XByJ z`#0Oy&-gr9nJyqK`xcAGEC-V&F-?Vu5xn!c%%cgc+0pDti zJ+Wqca{221zWMlV`mSf;`x@f;8r&ncbIp=uIOgE2v5jGUWO%UTn-zU$1e!Rz7HmCQ zuOes_b>Oqj7K3>!n)jU#c$x9uJ~;LB>E72YNnBG7^fIxi?a;UAlys6{I#bYSEa1Vz zXVSOPS!UV+nba1&Ryj#oXYMNkm+zRmD}Uf*U~82KaAebyE?l3wyD{|Rk>FIfw_Fol zB>HCu>75tIeZ6=4wV+T?>2CS7#wCvY*1#L zBsNLy_N9qa1?MELo_AOB5%)!R^;O>%7qZqK(tCKq`CQKB{v8LG$bb34ey)#WpZ&xM zVUvUG1e0ZTx5mxNopN;DqZ=k7dp&7vGec$U-tI)3+Y>5Cg00`VXOIOqqX&ozVFK{vp;?` ze9pg@q36Vj@D0BG4+C>|Y3{Xr@w|QYXC=wM9aosy1h?W^lT=ntul`X2dLEG=YNWQFZm3ug0(vL?A z@BY{)pYmH=`&9dnrELH2O8>ZByWOC+@QEEqY2G;rqXOp_Ogm$rgn8W%$YRybikh_K za@XovQytU%%xX85{!WvP0XqRYythp0<}8=m_;&pjvdH3A3cE~ zJ)%)x z^Q!cjtNh+;w|@IRx#*&FpZYwxg;C*WS5DhGJ+1FnLO_cnvsF@%M1atO1wAevEgMq# z6}q-;vdTUBjA_yZjvS}i0^fqR_xT@Vj%29j+?Q~5w)yMj4C=xv^-s(W`~7w$M*!Q%83Sntk@;*coZ60FDcK{XKdX(Re`;!P@$xOGos6V(yYT* zHWlo7Mr&%TjRUz@6B&F^=r=U|7iK(V1G^At*_s7U;EZD zziId^ta`Lbs2l>3kNf4%#q_4VexOpmH}%QiS?om;v$-0pMQzFNE5 zXWoay>#KJCmz*i``+sx({rul?_CMZ+xr-aw=1-{nFYUPT{&h1e%kQ(|-|qkYKTlrx z9RE>yquSZ`{++a)bfWdkZZE4P8Cf2-E}N6RU&xu&1TKHR{qpp;JmPyxm8R*R{&rBc zra!I!Vf2sao{h)%*VnHt;oT5@d##@Wo8_+t#yZ|eSwk+eTTGcCv$Fl& zMd7Xnre!l^7G-dT9O!Zqa9x$bEHy*x&_y2wC#EdVl`bC2dM%H(R^8jRyK2h`MYpXj z&rEDol}=C3y%=KWV7tYzqaxKu&{<+iz_T-JI9m;v&drc1byJcJa((x3qr%NSZOXfJ z`^_aiIvnOj=WmpVJ+t9(c>2l~)>v7`^B2D!i1XWg(LTiLq5TuvIsPec3Yo6+Bvff` zn;DmO#qaKUnbRr>Q71j^EpLhYNHjA0C`9K87GJh{*2B%tJkOEsbcb}0@-n7h8PS6L zY;#?X7?x)FcrLX(q7Y-28GWo`Z|&b|i=Gm*onJrfJ9YTX&GYi@a|pPhT>tedrC-PUvMYG-r167Jj+y|ufP zeS_UmR~9{ut{aCKf)tu%k{wc}iuIh3WNS&T;YwP<64s%>rL~xG8`I{3ei;s7^|MAn zcUC9No>6o%cZRa6?3%L%UQ=zGvzA;rz<)8lRsDMi1JAvROG`e86f{;plv$?vIw0y$ z&TCEOmV(V% zOY0<5R?QcfctgHx{y&zx8zd^&az1GPoNo7J^SbX`Q=FHSaeSS@_jYpqio48vE9UNz z+|GYFa^^bwEg$8+O23n?{;T`<$KOr%Uw&=8_nR~C-A;SYIa$gp=OlW6yv08KeeLet zWw)Czo&8#I@x?P)ljv>idhnBFM3PjOk;Ya)8VW3F=0rSF+RSFZZqGndGaYsrBKQBQpQ0(^^Ajh7gVk=XmvG+PDv1b zvViSU^LOu%&Bi<#tS23smN+ys#3Zz-Ena&d>rdLpq(uTOTm}ieD|B9Md%5NPwz?OO zQoen-(sj3v;|$kCsZ&W8ME0!jdM(`JLz#ZDhO|7%AN;CHEqb4Qe z=dXogmU}@t6JX*x%K)+saAWRa=OnSN3tS{xguCTNxhCF(KsUz0FgI!hqe z#bRQ$im!{T*P;ZLi!)Bl)V1h2_;P`Xp~Br@zI6qgCsiDuax383?Qs2X^-r@8`2Xvk zr(k(8cZsmS&K{l_Z=UkG*8M#FLpW*qzY|Nfb<2zYe?Q)y`Te7!UJd*1a!>_*a%zW?v=UJmrUS04V&2w5-S5IrP&-wgW zzxM6p`9E0g@5J4*zx&E`RUunyNu@__h`>~_qV?MZ4VRXz{$jKDKmV@p{|>Ic|7*S3 z`@gH+&ud+H&AoaH7t2?MyhnHQAFr=z_+PSZf{dh&zS7HQ`G+PLUufXaoY2Uv(>BZf z+N&8APgd(Yuem1q^$Dlp>s>6a2m7Mg8Bb1RdU*PnvY=EWyNzO~ORMZ!rWGlB=&A7Pv)Uv`N&vm+=9p)%3 zZe8|lR!h;wWj}x9Tv%DFyS1>e;+hY;b8toUQ-LtGNuDf{8)jx3ia4jbI7rTFXyE2! zPl&la)1mAH$EK%zPAnk?jGIqc3otDBy?{Oj~2HdR>42x7g+HO1iaI9&Y5|&~01c?Zo$h zt87OTvw5}6-N&8>T`p|fGP9=W{-Wv*w~k0<*6)@PTAk%fOZ|JV=6;^5wSBU`h}4A! z*33(DAD?ntFXNe&``2)*e8pztb**wdU!LXG?tKtK}5wHfT;LobJckeCW7pgbuHO^PD^9lnzSVQxIZvlUNh| zDb6(DZu=Sbiw_R=JP)`uC*r{5A0lf6@9pS_cxzGg`pmSekvi2M)YznikF}L@$Tcfl zFbhO{(6GzeurWL7lb2NIRoff0w65;;-*{T%L+*>2?QF|+-iF6B+x=HQ&;LmH_M^ww zBCkI?v2m-o{%^la{EAEMG{+&`Jcsq|9IeR* zGe7FgetDuSS4ZrDj0O9)1Am2C&DJ~D7$^8~9<%UX5us&hY{q*)Lo`xgvzj_%OWU-R zl){4cgejG~*6Hn7b-F-7=1hi6Z-YdV0(;uh9ZES9;}Va!1ULs@^!sqDr6@qDe7UBR zM^>=)yyp*=th{`<)6^o!=H?swEq@Y}7G+LIcMlgV)GzpJ|ZOc#W}crT2`=#(+xEbH`7w zymj2u)@tLzN0TKFyx$!!=la@xx^b0d*#y61VSZb`9nU}3`Tga}me(r|{r-QWdU|~1 zrZ;=uM`yp?tE^;v-tv3x>zlE_rO%wr{IRG!)Hm8;&pTJ_uR{F$B`{adH83s&Zd z&EB#?&0Fhc`eL^2=gv-key5|SBY*wZwfEKCr+>Hc%H)0E%$vW@Rfr+t@RJ+862|L9 zlE1sXW9(7Nb74BDq7}B%C0F%%gruPeaW@@^$Gp%GAaLea$Cw@ z`z6$No_>Bd%UP$u^(pJEoIWGnJ|<2+y`GTvx8MK2tj~1AmL(l_-+t+o*st4h{nLYg4@xSozp9=2%Dn$nXgQ% z^o3P~a&um+^4a?QwM~IrrAheAv>DGUX78)n@b^qc+t-C1rQLNAvNIN?Z=QW(+QWl8 z{me{SEG3>DFk#eBUVQBWhf;f1B)iZSo-7VVCZ0_(wm2<4)OBB*4>q_Z)~j$w|tkx?()g7BzMD=CieZ0KKYoGD)Qvo@3Hdl zRdM59*T{8zWxOtY72Y4~O6O_^2b9dK|iOVMH$JuRP<*{Glb>-}!RQLEE_Y|Gy+b2#g z(^&rV;MdeI-+2FW{CVx3bdFEV=R5OM6TO#K#aUb3Cg`s{{Byfb-+Ae8qLUMuT5I3U zXFj_1+Y z+#2l4jHVL~NR zK2IxIY#QoyX7R<8lrz8n9k!kKXXnpF_B;RWJf>-xrTS#?CIP<7f8w`Jx;lSCL%8>a zJO6v*w{1Q$;Y@?ma_M{K{pou{PW?82e&K7T_0E3N(uc0A=9ibv)Ou9qP$jfQ!~Wct zj4STHj~!k4!t036`lDL;QZA;Bk0al$TqmEe6V7us<59+?_fPJrtbBCriDIR3q_FLk ztB>c|DS*V5MTTLQ~tdk_7(dQY=wVFI!<`z zMvQEbu6dV{g|e$m`JiVr97=Q_0ZDm0s?G_lN4X$a&M zageNT;+~~wp%ozF$>^YT<^gYEQ)t4useu^>v%0TL5V^9E4at>{xQ-3@3kYAlHoPE9TsMI`=KZrzDmpPM-@*M;NV- zR7ttD&r|SGXg$Gn@X*6khaCMrJ}k1nx9-j~$^L_-H5OY-mdtv2;8#|A*0ejve%y)M z#&<@shk@hifonxouZyQ2e*eKN+*K?}(_;kp~SX z0nTC>%&#`>c5XC#!gy{$gTMtrC)V!;%)%DBb}ci%B{_V2p*v&uBbC6=a)+He4$ZlF zm$_AI#**^o7sDregyx%da4tP%6DZ-hRmtqRLcllA6{lQQn#HG2T46Y$JK|{PCe_=< z2kIU*GKoITFk>lNyysP;dwt{L&(970?n))^UL3sKebwsP)LG5Hl{q8$njT55_#t<$ zWpcYs?}?vTKmL3V{x`4iV^QcL>)0dL|6f1ZUBBtq;`_X}r_cU&_})4Hc6qhm|Em5U zpR#@Ji&eK5?H6CN?ANM(^($?9B3yE9%U?{66q+oz*ZiFBbk0eBOL?#5s@WNO-+b?^ z;#vA^R@J(9XL2QOW%gb_?`C`Yx%qFN+v(O*7KAzcd+`yaOuAMxihamG}!sAo-KO&E2GS9zV&bT6+Jf}c-0@Vn2#lD-X5dRtC=)(7an`F zp((S;(j}oqZ^7c$x(EAAZZ6}9I)ol+x2yy{maI1C4~kpnF(CN8V5OL4oa#lXz>%9EOy?#U13khq$M3q zCnhw9&DD)``XKmw=bRnwzk?#SE|yy>zjF0s=_iJtzJ_VJR%xF;bg}LEx7+!p(wqwM z8l7j|*0rTRDflP$aeL{S$o#umb{7t%9%I~~$TRQ0F#`kVi9ptw26JzO1TJ5gnts2R z-}$Xz^6}d@zG=p8%}tN)=2{%}^yIg@`B%O&*Ps0O$g1bM=c*;%lefidGd z(dA69PwOVnILP~ogLh>EW7!HNfv6^-6Arv_7o_GWa>gX^8Amiq@B}p8<(zoaHbN&^Nl)dn`MP&B>@^k-q<7Ym5@T&X# zTH6VY*$>!CzpI(NydN`fitg0wUtV2puK!g3 zzn7ktO|<)X;L>}>hN;vTj&2W6F^Jsy|0gZP4vq4Uamul~MvCZI_MG?XlDBL_x$Rj&2`~|e|MGU-u7R=>xIy&^10^A z#I&y6es?&@e)aYLZQtZyJxl3&bg;`Q`ogtd)u`8dT&851ZP|0}!YUs&tvyCnCU<-V z@2&m6e_g%jj5f~$eJ3&;f*S;tzO`5Poeg$rGpN2NoE7WFcbM_VC8mt1ZEK!zq?{8e z@}G95DN;>Jpe0JtlQHY@0mJeST@TJmIj*Wm$h@-4t5P_aO|n}g>tO8{yA=lhc?X@8 zk32I;VOrcddFN6ouC5&tu4QLau7u7~d21g(f7-*jE%^-f|4-ZY{Y&>)QJ^6*b-%;% zPx|58?^}hG9XLDb`Zm4)8gK5Ge6PP7_iy9=pE+OOB(q+7e*g60_P_6fcmMak{VtB{ z#VggAZ4WPM)rZw6muUJ0>St_ur1)sn2dQ)0jMiCAlQX>aw^U}m?);!#i)1$@M7>|A zzSgPjU^e?M4%>FCohOg1&V139B6H7w#fF11Ym3)hoBZk7*Z%W|<0bv}3zl&#f6*Y! zu)KfWy#ME#%j+Ib{&c@|{l9Ytd+u;N379x5{mQJx7Hr2@c-r4A`nZDArkrQ_;<;xl zEUJHg2!D7%c~-*#@AUzat1@K6n$o(r&z3Y}Y_m|}ZaQEz!@z1uVv&XNvD8}^r41BM zHD#}_+?W{Ym=)lb{leXZU2qnYT#9(2?AMK&8y8+H<-VyLYOQ!nwfWNt+2-$$=B#|2 zxBa!|>c&m5DOj6*K2J*J|q_c|x*(gABp|K}zz zTpAXOU6Gq|uH6x=vgyc_Xy^2PP-myc6F)7QU{x^$A5$m zlz%QwX6@cg&ypTSJ%6kwQ=E!C2^(f-^_!Iij#eF?{KZ$ z5hdsI?dd`G7gH6xTUH5KVTiVaM#y>^Knn!tOs`dtteWB$c zDmPDj5L#S(r6tRBVj$N-HgGFS)==6*1aA2 zQydpun&fKs{GH}vwH1dpORyZ}-C9{tzMv{&ne~Swcc*BEuw37{WZkKY9nsfauAkAG zd18*iSJ5@Pt+uEAYP_~g?>w4gP|U66arQ{hRso~!Vr|(^rRGG=)wy{q?yLQO*}wjc z@qeZlYP?(_->5vRnaRBUc*Vc0noV2K_~1IbniGW{ zvjW%FfBvYD-LJkjck((@TjV7_S31*j$3)h@U=WN}5 z-F}fY|8nk-B6fpf(C3fK|Pq{oKI=C%oeh z+2|{ME<1W))0HYIWzzyitzS1?Z5wx1ifj6Ad?Cdlr}AXQgQk?-33G4Gni1M;wEe)r z*nrlv6*h*pbB@J>COut$#^JO2)JS4fE<$H+vtMm`&Di^(* z!@qeV_ndi(f~RgUCR>WQzkKkCZAlZiM2GeoZ42dF3ya+a6c|rV*B5f;JIuO$f|k9I z|8}qL{xY+YDYm6=4jx(<=E-n*(RnG|CeP=7^Y^mmEmaOW{PBU}$>{lZ4-I$?4%^El z`t2&vI4paGp)sNJtRth~ww~8~rfm1w{8a@cTdy_sibP2>9bPL`-dfeZM)J;`$#*9d z$;n-H_doS);@xh+>aSlT?6MLk=xnQ;(q6v&$Jv*A^Pm0GY&{dTBh`^_lJm#9pp9qt z=*F$;672n#@MUtX+WpeqSG%_BzlV(@tahTt0BT@A6Xp#_;`t1FuPxpP19*vli^f8J~ZBeO~cw6%K&)oZS{Py$y z$*-4me>H#kx;NcS-5<)5?>>CH*hB5f;>Ww>yRS&Exi4;gR>W)0szsB<7w$8dsdD$i z;nL5A_gB2h3kc+0HA|HB^`-S?zh?ZhOW2$LT86oQ{@cQ=Pkc&I+dr*)e03Gqvaf%u z{;i6u-DiEOOQw;frta$s#@+M(p0}_2d)xlc$Eep$T`UI8cTPX#v_8-ItWxC7f-Soa z2bcak#TQ?(lJBSnQeB*(1B@oY-HPm1vkrBXMzUE8ky7o-T`{VNQ!Q8)-zrTJt`Ok}sTP&A`nt7gLbufN-Xlqwd zuf#=@h-X13%onuF-OIgu%sjm^W6$r4cbmWE-Q`@P|M|EDn`4OuBg?7`&V!DOMhBT^ zElSYS6?gSAgk7c9Sv^J%Q#Q^C`$RNJ(jA-4$X=+-g)IntFvlZ$V>+5JKCKy z+l8L*S)a6K(|R6rqgyV|xukanuA3(O@L1D?ZxfcBId|{UxyRckh0e@UdaAH4B_!;| z-p~8$e$3wA9?$mg^!^s*sry#U|F_1t?9Glz&YNWA_x;u0l$N+CU--wZW!pr~)owQ3 z`R~Kx=k;H2|K|VKobdZ>|NhsvZRYHcdVA01x)#6gM);esnrmK=h0m_Qsi7zCuG;MLee1f{ zPwr~*wAju3BI2-c?Jo1q3Fgbgs`ggIZP&QHv{L=Rhd;k3T??Q8N1yk{my7j9A0J7t zKev$m^p&3E6|_xDNe}} z7i8E}no<>l@l-RAF_R{!GIcB<26a>&JFNkTCmi`e!H)yc{4Z{EE5!0ySPCh@GypOrExW!^&3 zD*{|W2X-Al$vGoIG&Hd->_U+?+XGa#eN3iKjHd$} zFK_?A8alyAr14-=-}IG@MGgngz1}gcLZ;9;o+p2w@64*d7`sh?19uqE$6?5zO_eJN-mvpVg1eOXAq8*CDI~*7ULmGGtf42}?HM>J{anRgZv!_pfabg?OcBKqCHP2S=NM&KS7a3O`gqUAk zpnw|oD1@Thrx{7KuJ_aeS;vH1~pC-dCwFRz5>=Y>>U z-<$ruiC=eJ_Wu7D^=ug4iC><@F7m9yB5!L+Qj)<<^_$5znx+3Fg=>E+o$JkTPw`t+ z)4`%;n(vPnn0YD{zPCE~tFe9!|BCw_;p=a2e*W{$>%5g(eyj5@{p8>F|IOs0pVhw( zuK%;)@2&3V?_+wqx7SY8;7O`*-sJl3Qew^pzOs6|O|Q>rh43#Al%34P+q%#pp`#&v zTbKin!GfDk3D-GiKIk)wcV{&aXyi<75!<4DL2gC>>k$Lz6B&|;-4+LVfQav{3&eNl?d?8o zJ|B5=q2rIYOCI)=P2Fkl@u0b37i-?lg&JFH0-imX>nx~!BPnjq>7tZ&t?A6h`{ys@ zInl&BM>x(_r`Ll?LpkSQRet@xPivR_J+)miWX1$9)xwMKe0F*Z3f~s{$@B5ZUeVsO zPDy3=rrx^F#l^TwuV&iem6b*L7ww*#&05+J?(}?}-;~{(o_?&-nfuhnXZ@3BTGzte zu3vn8;pw|4l@%Y8a-YKn&CW!%HA)CQj)ONiwjP8+WH>0htx+4>+!NUBm= zOOToA?7RsHZi_Zulg&2s?$VgH_F9yx>Ea2z1=APVx^MY?f5yIV@@&U~8GgKr_Xw2z zUzyi5WpUra+Q90qi-jfr$7{#^KNa0loRGv{^1~rMetyl4`#k1}8Fx=sd@8yB@#xFH ze-D3M{k{I(uKz1q6SZHT`l>eX&9x89zb~IWzy9mL`#0v=T>H9r)9tG3N2mWcx$(j# z_JeTl#FLqCBsL~=>^$~y>Eh#^>(lJOHvf)f!rPCAr4F^vjtTX=3`2B#~4OyRek99Q;i2urax>U)jPvl@1n@{CKO$kNw zgw|^YR&yMA=PLFnxLO}Ls426nU2^6G4!0LF>$+>_X|G@uUX{oi;kbE1(838bMNI^& zgBYq?edcU&e=?P6i-f=xMC%Dr5-_ zX^<)WR>WG;qws=r@#0I-@s@o&5f)sT#{$i-_m|wrjWXuTse8JV_e_IK)DNZ(XOV;V z{Qe0sG+O_7@P&QaugNlN2a>2dPGsu@^ddmuCC(ssrH{VxxutVH|bFn=QIP){lZtZW_9w|UiX{DYd(Kj zp~#&ho}qzPMW*R;d*!s=jFuEG3k~UEem-U1_w(z+pQb+f_|CC<`#Y9v(|0V=bu{;J zaP%&S-Lw5{0^gOVVo}01ZZ{-i1UXC=y_?7~bpfwg_)W=s4rynl*92y?#2Tj^ahS)l zs34VrbLA7iHR=33@~br5l~phj%P4mNF%;~dToi4 zOMSyE8tq;8J^S+S`rkY^9(-@;p6}*&cOLuiN0t|rORw&;c$(tAekZGEy{UbS`T?%) zkJSg*`HLTKp4L7k_+vum?Hu!^zjszUXm&Gb3uX{De4R?q*x zxb*63n=5}g{TEj=zdy0vEvTTVdGhREEv4nnH<-iyuX}#Fu9HpyqcqjL@i75&5gZS4-9W0skNJVL)tM&A+zI@Ky zzH5S>C;7g(I-%kB{Vz9?_xRa#%_x`dE7Fb9JivK2Q0rTpU zU-Ha$-L6@CH@~S+ck=?Qp1*i=ZmmY}i3GPE)oIT{j;OT;uVdOA zr)W@EzS%*S<@A)S&tj!Zts-9EP_E`Fjjc)Wy4hx%yXVLqtsN39Z+bVaF|7OYcC~>@ z!V&p{yXzYl*X?fCtG~5!!D6XU%P-=2r=1@9pKknjs&3!4eBbZ&bNB6EclFh>iEkU+ zmS`S))F;1PK*z1*)EyqqO`CV=_br?IEucQ?Yhmg)iM{&gR!dYG|Ff9K`|{t-b@llw zi%Ztq{M%6TLtDr(_D;|If;-o~R&DP}Hs3a-c&j#SEkIuK0+&$5d2G3Jm9D*9#rJyJ zk#Dj)(v((WS3i#`8KGTxqBxR*(Uy}?$Yt#8_%xjYIwl?F!* z4VT%fIP&jHH`v7!G^3fNQK4<$0_lq~_Yy>16orx*3+ zb%yy)w|uhnvz2%+kCH~$g~aO{*k(+Vn7J)QjLL3aJv;lk+YQYb*C!jDe#-kz*!E|jgd5jS zSYiD$Ipb!TyCc&aLji^m=2tP@QC#77ZEEgaFj8T1NVQme#?gvV*HNjfnZt2H7Jo#m zL4OKcn2}WX?oFwlzhCIOybbbYJSXSAJ%H7rVA-@SYvwp<#5t~-7N0eW z+A9}+TfN_CgVh65*$?-t|9oNkX!UE$r;YCxuLwNV*kSZi=3RvG@#}$ttg+Ku^LKn$ zw?AF6WydL(N3-6{*(qYf@$;+N|BHXWeSG%Rd++xRHWtmXtskrF{@KcHPl{glBEqxo z(U~i8C*D0fGQZWp?cL4u0`IqTu|-KZT=uOFYH__FSl09F-1SVIc^kVIe82uux?Xm@ zo@~XYgPS+suPeKn(mehCzxVZjelORzdscgl?|`DP6z@VuraO#naux3`EREQ?&DF2c zS-_`jSG#scV*8ps2GQ4FB}F~oWRtGXwPsORM3mD~hl1wR1&hKMW;{FT=sc%6h08Mzp{IrCvtCqi4ub=yA>BZW~riC}Wt<@VjceI~-wvbIVfH}iY@ori3<+R)n*9T?5@Y;zz z3mStKq#Zoyx_V*82JWxfdnGjc+jJ~X?+q5b+{djZXS8qUwC{rDu5s2+WsVtM^G-Na z%D7|dar1AR-@bbJK)2ewW=4jYI_%YuGD_!u$76S6y}1-~<9EKhcJa_X_bTz2s9KR_wlj0xE85sz2tSbi zE?hbLKPU5>S6PkjbsE?6otPh)@BjK|@Bd$)-`_}|Z<`@{OHBUrwnLnc1nO=t4{Bw& zbf9Zvqt>D(rWp&_Bnz}2u(1~%uG>~@$`Y3)ua?2P?uJBE`-YN}i4N;lv|I>at!?3& zbU-#x{OLko#sxe#m4&4aiW*gK;x%Cu74$tV^(rvArR*U4%oW^|)QY$lvPr4Fy)eCW zlg7w^bmS#JBTlZA%+bm5sv5M$b?t&jG&wN-=u+~wQdBbrd z$71Q9<=m+={0lBT&CO3wxa-Kqo^ZN*_2M5!=L+Ur-t*x;ub)Euc~{eRZG-Cvc+PR_ z{PSNRnUKGE(c#9mq8XiKd@SFd+Ig^PWE}f!-K1N(&$f|y+3EPdAD{1iC)B?v>G7)l zGmkuoFf{+3tGX#KUiA{oX}7m(G4a2idhefkMvC9^2k&pLGAGZqTc!nXZ7-|hFBDxT zby0iYo#lVyF74CSd;WXZ+p^Vi7m6NM)K%X4d%-fI*6P#cw-aC~d8fVFDJP3LE5k2N z;81!Yvb9N6a6yBXcbeav=f{+Fluas_O+(y2FZEl%R;*UMAuO<5?X(C-AVX<>AY=d8 zn`^=aB1JMTY7}x^3iFDy`qXntyp-E9w7Gn)Y6e#<_q3@C7rt#~6pOwnkUrk#o9iG8)U zq4gKm*}hF#`+Mu0-SO24l1t{>O%C3;Pa|ow|mU6QR2Gw6wXTl zTm>D8_k^-o1)~~nGbtsqOPx_!NoFyqEbFGV+P4L@VqyZI-!mfHzcZ zW2i`qhp6mNF zQq4Qd&TwVYcE7eck9E2htc4Q&nyxCQoLT24`jQAqR{y^Y~P4wAk&(!Yz zyU@X)62B_)-_hHROdnbvS#XVjAe52U!n7^fc;>oMsE;Z$vJ2~&>uHF}2&h*;*ui>62 ztGjf+xTU^n6cX2O(b9U*c0!@;tY7n{ntW9YXVF&ytdeIExzds|RJD>`tz+W6ZQ+{5 zqp&Od^tp8(k2z}x8Mk_ct+qJ-cSXPnjffXh&dlK65uhQrr!lHqM5jP)vC^9}3ubki zn6WHU|Gr$kzFX$8-0Ruqi8A%40_}cYKj`%}czr?2$@vZ0e=fa#Z}aDmeA%C#J7?H> z``K@O6R$t9vA^*8Z_^}u&B;rJb}U*Sno=%#Yg^vE?6*gDN_<){y?NsAQyGs6*2Ud%eAjnllEyyb8fizY1zBqhIuA&TgnvMrd?W>%n*4` z_i;hf-3tLyY6pZ$xI^wRm@nV4^VC=4C$_tmTbS=+tGN1f{_kr2e+i$T?SA=`&-EZ{ zl7wtW!ST2UJv<_;oH^%&Mc#0_8gk|dbu~5G2v2zyahOSW2bxQ8hJS` zRQp1=N!2dCn%o1Y20<~0dI_W)OyK`Szk|jJPQta=CGylo9R1^ zoU^;6uB*5>&RF4Ob*|T^wr7gw1XgW9)6PKWx$mylziImTar>=hNAL1J4L)&F;FQGI z$PKk2Ep2WF&0-O(j8WYJRr{Y`uDaFfpTe(cHzax&8LrFPoCN?+8Mibp2JM5^#XdQ)_%2`DEWEawUp(v%eG0%2i|LQtL{}T z_t+4pftCog`@`ugv)_K#MAT@U{Z_BNn?mnmPtO#2v7v;Z`)tzyN#-fN4 z-8D0p%iYf7jpY2#6>i7l z_VHk-*oOz7E`Lp*zDxGxnShzsU0luxT|HzK@ZlxfgrHL@>Q^T*x@_J3BXQOi-sVUy zU#_*?^DNKZI^x${)@*EC$-!9rvCMPJN5uu;D+p{y+Dt-TuY=#r->OE!y|1eTTaF zm;Ajy?ry4Xo-~ogjYE?42KTp?Ifer3WK)}rraa``m?*xGYb^&;XNG86`vWJ(p3_^6 zIWOfXNi8f*-0_@eH3zTYhNg&vg0>59HqGDCmBe0htwkfjK`Mnwe1{YFjz;CpO?%6~ zg-q^H4NQNp_(05}dwmd)`Q>GAJx zy$@b1bzP0wbC*j+BBz-6*+f1=m)q+ru3K*{+T?ue_J-_0MWt#VbB9n?`Hsa`9`tA} z$h)Xr{62r*H>C}awo9HVd9n9s^S!KnORlvzzt4ZT`rKWID(gkn)|M5sc`KuZtkb&8 z7Tikmo4@c?Z-At0!nP95!UY#~Tq^2*Z+^xo{`9ELL*vV=d3u)Xu`?YG<#+1Eb`OcfQ*K%Arv@JL=ZQ0j*KTFqcZFOvPII{lS zrY)cT~0R+q{Z4$xHrpK_w7%`LA@?y-CxmHoc<+|KuBPMtXwvNJ^MqBf84H->dSR4@C(!dt`PpFC|_639Bj0QfF11+-KQoTJQR3oQqrlzJoJNw&e z{oe0U+2=kk*m!N#;EY@ z>}ia7Px#btm)NAwKbmk%nKv;lY46rP5xhE!Yo3eV+q-+tzl_r5hU|W8mJ8mv_wN30jhhcI?DZ~G)Yt!gyZMgP z-X9^0`=_s8|ErtLJD0qYK4%v6@t>k{_ogjsQ8iZO z*6Yn@TctkdUfTWa`O?}(w)f{|HmP(^>yz1(D$Q;EMsC&p-GBZz9o|@KJ~7`a!mY<* zH`Cb}>JbZm+RmHMklU|alm73C{G;FhudkRPdj7V)?|J(^!@K{|{@=WR_^tPya|P|@ z70wbBEez|WEF2}v9I^|Jv*d`gR~_=Xp>2}DE3(@C--`^!;+CYM2~Ihwwkk}jEDso! zu3Y}Nz;K5Xi*&O}K>~+}D@#D2nAT)v!6Y{p9*<&1gX~8)1SYzzx+$c(QR!s$Oa|jg zYI*x~Gn14~x)+2lSAAs|qxsS-bE4(z)Kwqe&b0l*9a|$QrMzGHZ`+DDhv)Bh=9uk} z#~XRL=~go<~^)G-Z8MO+!M(o z(!hJ{wY{0c-`=u`msviP{-2Tj*QcJlAt_%mXGfWy=_mq zKa|YkIVNSdHe&ONli?|cXLG74emP?2`@lg*{WM$DzS>6J{ef)y%q|CnLk#6BXUW;u z?tJ*{sBx@lmWkyy%hRbAg%P>4D{GGH1Xo^sdE>EWtn7;W%kGpKs?Rt3IqC7I7we`5 zq~>LY%sv@C`J~}ZwXEfjT|b^wE>x+CXyboYabfG13r}K~tNXsY`=mUtpa1>4)^gCI z<$HpP!fZ{3F%wc+KV&wtDLr6)b)oXERD%wOtoRPDC9l0`Tq4PeuE&<$w|)~m#o|vp)6Y-=2~-2 zfo*Zw)P+kHiiT>Oz1&0msQkyfU%gbGJJ0ZE1CGtL)i&Zm~en z+^1Z{2`L%Q`8N#LEX=*wC$PZ$&ACtM_y67g{QQ6Qf0?-tf83jV_+drOr{d$^o;=N8 zy1wp5Mp*@u=oHtp8sFM>U3kE8?=Xj;M`QEhX&DcCBDSS6r>zimZxxPemQ-4>{l&AX zBD+lX?l?4U;RHqYJK<9tl?q&WXEbHTYQ2%YIl(<+jek~V!O^sqnJ#;$2VGKN5_JUmTJ1a{$Vodh0kJD08KazIlQpNXEJA|*ina}%4gsJuicaNt0{PWL) z-fvX#nZ{o*L7DqpknL?d+x_J?Eh}&Ls7-!;^2l@ECFb`TT7$$3xf{2a`W$1On%HHs zeuL1llO_%ZZJ{MSbFNn$R9%oJsJC96E&j666VruXN{$|jZvK7Uv-MvX%foDe!`a<` zvsu4=3wvz!$y!xIcfCRn>)c%(YZO|PHh67R{ig2su~pl2o&)!v#Y!8jcJXAqWwB6| zSpV3yXhEaQsQ~x-n)f$zk16V~2p`_*tGKjCuP)k3d>`-phpNZ;*t6Xo8S~AIRT(Z; z*~Xpl<~crdWmNK}$TUy8&u8}qi!Q%8chasL<=(_dul(5jImYp`3T4Yae>iyWo^=oZ zySy%N%01?_Mase3*}zG#XVL}pDQ!6?O1H}Y5K36}z`<|}-yFvH{>p=|y{3E(XyWNG z*~P9ZlJCI3plq?5Z%pHxdCw|4I10J^#1<};i@MV>t3&+}hq|oHik}H)nnllMT{7H} zJkQ5EK}dgHa|5sKwxIj}pO(E}F0vwg$KHQG%>O+QT-PxDztD<{_UA+IU5fa2t?t^V z1GnS%Zx+qGU9{)Z z)@t7WBWEuk_pcAnTYt~m$AT@bNnFP2$$>n#uCJf`z8sss`9`J}0~?dmL(#{Nylfhn z(lS2Js@cFW&!X8_Dxk9V-Qp&(N88usPfN|)_D@vw*oQW)7ikwJvA=rYb+&xo9Oc5N zZv@y2XIHU7jKM&Sd z+4HuaSCT8R@@`dr$-T@{!l2;uma{jPyuECg@l8)AF)fhCc&BjgT}z*shny3Fml?@7 z2UZ6}wU=;6tXDRB{gC+*-zDYm0t)FOj@F!ij|%>mI`tu{bnn{jF=0!Zm=}~D`f+RC z(=TZ*60fyPxCFK^HHI&lrZ_F0f4;%TeNNUK9*rWe)jzzxBkjoKAi%&B^(U0maf5@( z4ke*Wn*80Dq`v#sIi(0H2{c+NZjJx@YIXVY>5mG+omTJT&c2uC?|Ad-q{+~>`byYF{<_q~6ycRAOr|GEC+mUU^x2R_gK&2MSo%p-H6G2u#&%M0Fl0ctZEPrbUC z;L0-R8f&R_ha1PNpes2CLz}CO4Gr&Z6jjnIl1WnArFHfw>jbHV3s*`z@0LoOlOE)p zzbjK^rPN}#IgFDdpI@=zmATPkwy5K#{M5&X_ZJ2yxPRC@{keJkpQrE2FEsG|_`Fx| za)W$fpb_Kr1OG~1y!ZE)Wzze2Z}O9suk+{UueWor4_*4^cYe_&kIw}*%l>ZNqM55a zgTLZ_d;hT)1v50vihMqP+Qz*sIz4pOT({nxXQV!_IQ93UeU626T&$&K!JhiB{o5}u zG>Z_-T#|Ww)||4n^NKB(t=ln2IM$?UeuhJ#*Jkc5&a#qg7jC__!289fV0Iq;{kwMj z`KlYk#drTt<-Z^GTbjC={=GPPcJJ}W=l{2_efVs0(eK~(s^%v|1z&uVNL#{~+F&)w zf!Wp|y&%f+O-csu5{r-)HdFY{#Z-nDl716f_&j*>1scT7 zT9}%A9a!#e>L_cFT*4^qa?!O!V*6Rv?LlcL-NK5N$h}zFX(A=Gu+w={e(I94zLnyN zT<@EzGUM*d2$eT#RkrrjUoUq&{|(c(59&|;9lkS9+N|`q!Sj?k>(8v4wYbb8V*mb~ z3EoSrx)$wjyB5eO@N8QwtfSEVi9zZh@5VC$qMZ|@w=o+v z8!u^OZCsOywZi-6?mn~a*$0b+#t4fO3@>;eUy+!|(C|{EPbdW`8rP4*L{z3v(=p3I;*KNBEJv1T-dsQ4pa(2M z1rJv2I9MJZXLqaLC$z!kc%%N=8Fx-b7f3x;3X&+l$=BhN`XF)LUX#ZQYTKK?KA6(c zWvyz((Wf-8=G-yM8E0oSIi=1@O4-Uc@$SmUvppLBES%DQ{qi>7_eJ|2C)~X{_rNbJ zZJ`c9&dScp427o90}mQiUeCKQN%7zwr5u(5N9INAm@T|G;-=5-bWB-tw0mdwr8fnN ziwqfOCaTIR_j$?|@O^Y)yW(+hV)CY2?Cl36uAcObQaV3FssBMkuj!zYV{qyr5{|AX156;{B=`))<{JyBSdi&$6BCmHWVNl+u9R56M z;o)z;jvlR1-m!7d<~!1&Ua9v~XLQ)QKFiy&<*sGtneY3L{*2V0-|bQPFQ?+`%ulW* zcdmL`ZTh1-iGS}i9UG6%+NTLm&YlrJ{IC6ce|tc|nL3}T>y_LjZyox|x%!^kljp}` zo&8JJD^Fp|vYUC~VFp|BmuIHVdHXKiUN01Q^P+h}xyR4{KiU5r4QAU_Uhwnc`jhd$ zj(+>`_haz?SHgR`@=ed=LLF=ly=(CGCmnG8@_qA1*61-@5wB%7d+U`sb__S;De_JGCnzLq#>x z`7hJezipSL>SL2~Ki|+4xTnpsK+;iyZ3@%*)tBcm%Us~=EQkx>VOD&)Revgjkiq=6 zHonT?{tE5<4`l_;6M$e#TB)2VKw zAU-Z@JDR1F|MrHPJhZ?yj zFZTK_y7$ufz_Yt$chdYhU$7j1WfAgXhxM-OISZTHvd*kB*q__$baQXJxcjp`oq9#v zM655xUWr+8hWX6Bs~;URmR-7QoALgYUqbC(R|ZQT1_hp_ip-}@G`eg^HMcw{YqXHf zWc|$MDSppw8`%~Zw9j`6iA^)ki1<8L#b?7#k?$QMx^9latGwPNMIP@v=5orExkF&{ zu?MSW-#cK{Z?-IDp?bM2IVf&F*bY*kz-rsXyUUc6s>i1E?|NpO_|C!j# z@>_5J=}5J2yMFrb# ze_#8)uD?mQLLslz`s$fi&wFR?whBCMkvH$(vt{QjJ=U!gO5Q$S-e+pf{5K2k?);?u zeG<#r?RU>k-~CZ*SKl%574QAtCd%rk?Z5A(r2oX|c!9US+Uwqn`lna@u8-PtwPyd< z1KQc2S3k*>xz|}!e3m)*&iwVe%C^3*+xq|P|Fp)pm;L{pu{rbm{lDFhH^$ZdKmC0A z|6@Y+k19<$7Ov6lpLgNbD=U9K^_GW0g)1y9YTOJieM-^y;Jl|Oax-8$Z+};$W1rH7 zp4cV}h8)=t#wNCsHba{PCaXi~EsIPhD5aecU88vQsYmdg?yXm5OIFFQi#(eub<@kf z)i&qMlnWhvu0fYvT!RbM{W&-EJ<~IJt{JGglE-h(yjY(5yI<^k-}m>ZzS^&S*Oxyo zc<6lcjJZbqPG`jed-XJ-`FZ#PubWO>2E za3+9rvx8*RnYU}^!PWveHZ42Q!1F|IkH8a2CY?L&R!&?>%3DJXLf5p|?s2^owdTb? zDb-i6e<}KHX;uB4^)hYgWmmp6yy|;cHA|z@54<}d)IZs8U1cldxepP6A_Wr8jImo{ znJWI8vO9BLyEgA;Rb48J^P4SS1GKc%9{l<-eO=t$!=l+c$~AOmng%VIQGVEnb>7RE zb{5SJ-|MAQ+%74)r}AwUyY{qJ^_Dkt3X{}U&5s_1o;%KbW12BDe^&@D_L-Oquj7_Ve1wZkMzoxu5cW`L};ngJ=%d-=hEZ`|kf0kS$=y`?z?L z)Fab(KaXz^6ZrOa{trv;l`HDG-Rc>hnSTGFfA7!a>9^a@@B0~U_jmRGiyq9SoyWqD z|5LteyQs2n%Z-VL-gYk5?0nTWiLG>ztMF4Bv&!(7fid;2=kubpFY(2_bKg_`zx#c3 z?W&dem-g&75cuA{vDxx}UHAxBtNL{~GJoNxYDIe1q?+{vV;X%`Y$O z$JPEn`u1b`j0qxq1#aRCTK}d<$izM1<66=p$-%1H@+jg0i`8K!vxQ%0FcmwebTl-2 zWb{dCblow~J``B9^hl?p(UNxd8pC8s3q?bj4AFNhn1s&wxe6}y)ZF#Nh=o0Rrb>2~ z?9wHUB_1y`D!CTAbcUuUr9F=8c6dI4<&~4sjMcLj+P|4$_NUqScOCzW=I_n9#Xml2 z-0$1GFCcS{{nB@-CLCP(B$#v z$x_|hI~OxvGUvR|_)1+FBj>~p3mJppFuPK@AXtJ&xX0zqv%$1P>m zg-`TWB+vD(ocFWxiQ&aN&l+#7V_ROk#H85X%SVZMYq5g4RxxM8ZiUm&FF(6GQNAbY z*%rgomFGaqOF<*r$)dKFcZ9Df@OldNta!i`w8E+8uH8Il;R|UOco=50a9o-sBc%Rp zYqNGxgXToX@=Z;R38=Iu>O zHcqyXv^hDW;@X1?bCj;K^B-gXAH}+jz2@}~|Nm?M?RR3zYxt#h>4*ROcNzsYcjwmE zWdFIm@2o9D0+YxK1|}?Q?@0-_W~%S1{XTo%5yu;*6JFk! zsTlNXcV8;YtOG>~OKo?yKfCtSa&Gf>vzcnOKVH7K`Eyu4=7?xw_-?D|pW7O}SMB_? z=lw4Combz!eIA>!B4JiGE4xuQzjb<0o9P_ezv?IU&CKi5m?|f8`sbBxCnstjJG+>Z zf8`cF387v6=k(A2oBQKl{ceW+$L9Zu{&>&*@%g{EYIaNi|M$P__tA^uic2|MvsXK6 z@vKd}<7|BA0#EUwWrtN>H}DIen8*_(z|Pa6lwqvKY#HU8_Jwz{V-o9;>s&!k*kXI$ z@&&1|^4Kc-Uy!uYuPE_w4HW5L)hxjk7_@1HpWMSq{r7%EEIT#(7{`~*^NlTP=DD!2 zKil{;dbQH+&N)ujMd7;w9PgWdvU>4$+h4!Tj!&_6%B#$S&0iGEGha3{?%9vrm)Y|t zGD&jmJy#Uk!DS>BKE*A`Ncic4gQ>4mUvr9d2x=;_y6<&4nsMPvn%XKJV-08F6#jJ| zlr!2GCMRxoJokW)X~LQ#-TUlso~$hmP-Sg+lE0~Zn&sR*Q{U~`bLjOuk-0zkwC_&2 z7xVvgM}emOT4BAa6HF=D>ORbV*?j(U7#e&S<|eI*-#=w{wLfa3)q)kzwKNfb<(qP%XYhe6`}p6x#9mS-l{II{h@ln%8yxuUC!rwebJ3e zr91x}J`?`_&$<5>@5e2?Iiq}rN`^DD$K;}Ov+o>k%G~9uRBlnz;bOVw{pRw+2Y+7? zKB5!vT3+%bsH=Cf`lEy$B_`ss>UY+Ezn6VGsb4HxxXt~J2lp|rai2I4dA9WHYTjQ8`x51SrxZo z!^}z7wyB0?yB-pfpJlo#cH+t4ER9H?%4<7Q#Mp$F&sp9$yLV=Q_pWfx=z;aUFy*jQS~@=*%V_dC4`|_q)%=-+Q<2E_=|v4HIV{oZW4!Uw6bO zMQB#j=JQYX%>1jwH(MgIKy?SN{A~HVv(D$;S=8xcwET_X^PFw9M`g2n9Id_lo6h-u zzH`YZHQyvi>(ZQc!h*$nt1sLGbsnWo`@K6K;>ct7mh+iI(Ues6v^MP{ijt2ebRA2G z)il_5!HYYk@_^1_y91u2_0M!GdubMc9A)E3M+pL@jm*Wvgz|NqK!>PNF2pMT+cVFHWP z2F6<}w|;(n^UK+HZQZ@%PKPU;%xCMkU#f3^D8=zk|9^+)wcB}f9>_lW__Id`?G)DmsjEc&IOw3 z{}=rKP(ClO|Fv`d%#7=jyIk&wWGLwWJi9%E&)^x~oQ-!E334e*cQ`!VV$0^@>UF_E z;!HqE?IETOtc@-+)DoIfCp3vzt>1TS#fxtfI4hq#`|vDhE4ON^X8&cqYF`%tE)V@@>V!`}W6=m&h#p{lDw0 zJ;yGKlJ^Uj^FG&nJn7E?(eys{=d;V(?p9i9n`tC3V|}&C@5w!B<5srSA9;;E99w$k zJ~sT6==j{#=}PF<2UDCj`&^!ud$Kjk@H_`2$Fzs1FZ3FwS2(WCPJZU0v%^WM&2>kSjRS^iA;=IJG@4@rmkAJ2gckG+VcPCWtd5=_#MxIsZ_lFNo z&U$iYCHD#6>vxw_xCTaRXD(TCwV&0jQn*h!=hc@R*9EUW+K~BVY3J_%<R_?ZP!!}4>^!16Wvj(blWZR=VaBAi4|g{0lrdVCGbdouWbe5_o7+S>FYQy* zweP&g=XW+Z{gA6vrl>^cuE`abb$#z9?^~08zV63{zmN0J>~DVjGQo<${J_T)%U_Rw zRXn|N@#F#B4_x-g7_GnP2elVnir{aQl<>Y8<)mIVZ2|VmF%$i$szuGy*^Wo=_dq#yr)`_np>L(dCOv!Y$*c zKG%;*)_?x{taY2+jPLyQZhMxVl9EZkpAyzpD-)l){QjiJmu+g*whK#ajt}U${xPn1 z-C?S^Tzm zy?aaWS}>i4SzO$th`a6XnZQ@Sqd6v=DXe8TgfPs8;yg0i{KCaD*i&x~0%^UxaZ z)JqZ*SLNEwIaOK`zbK(+N(Ap;m!lSo-d_5kHE}7&qP1_>;UcidX> z`0G*DUng!VeR@(N+oLf-dP!B^$A3>&Fj^=bGPFEly2kLv-PlzBs_iV!|wYK-wePJwLb2zr!K-MoPe%e_F@AcErc#Z29F7 z|9yMdCXKaH*`5JjACFCSWjxxI?D6r~(X9(yri;Ef@mg2kZ^nhm{M>96QKC~B#PWNU zIb|laO-W>XUb-+uSflN!-E6T)vCfS6*JszW(oZ8I-;D>2VfFOrJnYntV2Gimn@1NQVPlaISUKiqT6ZSR53 zTaP<7>*#~_g@Yy(&!vCl@o7*Lxz@1l*^z36k6Fi}6l#`b%ds(pw5*H${LF(><^kW+ zlJl1sn4>uTp1d=;7Q^is+%K}^VcZ#(xJ^%0C$AASohjudP(5?@7K1kK%HXVp;(_Lg zre|el9oZzhewy_x*Ax2NjQ?iE#M%9MQvc(cc>VXlt)!z;^6xu*mt-1$_K^x$UQ=cD}F_bYl%uHODTS03}s zT4XGj_vqjnJ-6d;7hg-rsl4pAsOsANlKVDq%yzxy|9Nqb^P=3t%qMlHd_ME{%bKfe zB~4p%GqO0?KCNTowtP~@Xj}6s^yl@jkMA2jh%wB6c>kWy{y*~BUSGd|{8D}Uv3LS= z_!XAW8!c>Gbf<)^h@Q8gD=VNmbix{z8r}~qp)1zy)SPmSZymczg5;AGZG~>eI~sYH zWU%=xKXb4vlS#&MLP@Q|WaX8)3_)zg87#}Mcqx6|sq)oHtK{~lgLAc5dHYlvB&xak z9PYpGo`|N2|%iDuw;rIV#esj~7f?00ueH-2X+S9*E#?IOS3zSETq&$^g9=Jnky zC_Z5N(dTvI>8VZKjR$#|#Gi>wT-(O- zKK*C$!CAo*88SJVKEGm^{M3B=gLuwIuNx)_bsXIF?dloE1uOv%H)T0~cy;-b#lp=T zJPvxRWpk=NG|T7xU3uE2`0~3$s*>A;zxR6a@`Zo@aA)$`}X-VvK+iUD}=*sdid>WY#uSE-)Ne6_1Q#nzTLq#^%~3CuWP)d zR#}#K%(`dHXw@x7U8n zT&KR{b5U}vOUmEmSwW}Or(E{0ovFD*es%1jZ_`?SP0nWaVYoM`|La=qJeRul_210@ zUFPK9U-3SF-vsp=-;!^gnc~5D`NE=DajP4vyNNFSUQMfoql`pPZubj)kTdc-E~BKhCpjheY%9Lnqek(_JRVd1BpN#!b)XELQUB z-QmdReatB{ZEfGALtRX1`({6Xa%%4H%7@b`c=*`YE&KiM_J>Y43fyyld z`O7_dCtLh)aA_z`zxqeqL4rqtZK?1jyTuo}eAU@B7pRvjto75}^E58Lg6oL_W9o&Z z3F;0Lru`FM8&qzXAlO_P8d9|>dN1F3&UoXup<$P;*q5xE(0ag&b%{gtHLpz3yKhaL zSrjBU-bsj$U*-I?Lh38MY_9VFA>5cF0XRb1s7j%hi34DC5_=>M@Sh2yf#&5AR zj;fWjm+pf#va@drUGLEgknnlnFv~wuutDk)&pHoLPeHCrSLM9=0y>(tqoM^3W<7{l z-XfP!yiU`kX{)mOwj+*SG8^7BSQNFGFOtf7(e0C@`uj=4B(Wez?^R8l50*UioT2Vj zY%ps}!KXXd&$=If7|nZJ`>$V@xD_+QwEm|{7TuEn>>T^7nKQq_@~8W^qyHsW$`{_Q zV(U|%eCpCw?d6(@j8+RCa@y_wdD{N_$Nhh||9{Y2FP!Uj+~4$`_UE_HK1urP->se* zogS}smce7o1P-+yx#t9pm@J*T3*HCU+ZMlh#dg#FdUr&4q6`CKs>fXU^ zmddW?Q=U2AQF^=k+`gJSe+w?mY;*dU6n~EY`?*~r(&t|MOf89balF?cbRnUu^5~lK zyaFxJqqjr~MOZ$cdwEAq=s6FE=+k2NiY9K04FcaY-GTy|*rq(_;z&8>HgS5*ycQLY zO-X&t7dB-1XFmA!?5s!r!J_HwrbtHkwW~9KoTcuuT-0e!ivCGW=U+$4zF%i-Z9DaV z;bhj;sJQdFwo6WSx+%9L1gsHT_ays$?rZ~N8IEe<%{#t4nbvm4sQZb*F^>73=U#nz z$iMH_Qo;18GCAk(+Ui8xyvjQB`LK{`>gSL>l~;IYy6h6rev;f%Z7+3ObY%gv<-yEl z1}CHDaE0!hae7;6`m5b5-MosIOt`jZe$SjwzT#D4*I}*d^!JAadSqsBsx>G}^SrLq z*9>wz`}&_qc*mkGrFkzHBa;kRZYnwm8eDk#wMU&X_|lP?$2%^pnbT*QrM&P%U%IcA z>Q@)Ol;)1f?^dNID~2m*cOK^To3d%4;4DwRZk4E=}e81)-n+blq^35!4Tb7~PZco8g(l@pw3WrZR@zu+-)ATv> z$!iNV6+&?U^7qqd;X(PWEOY$=iGG=LGKiIQiwTWV4ukH|G9*XaB(VoBi+d zS2u4yT(+w^h=*j z7Ed{27Ap4yCU2En$Rv8r!F_`hZ<2yLW0IpJ%akhz-W?6#Il3kLhEa5%hse@Y)$@s_ zX1#mb-o0)$ov*Z-=k1>v9=mH6%-CLZ;*$HNYqzfS`bG(@mF_lKv{n7>qNSj@zUE$DtlWF?KM7OlrL0rMvjRq zq=9K$1xLnJEAM9sK}%ZpG)}pi;M#NN+Ql_<*X4@4L>({oHqQLn%oWnGB}rtOWx3J> zhj@3L&+?WoiVxTpU!L{wQ1Nr~*xV>1ZNJ;~EFFp*HD0yLEK1Mi+%<{WcS1ztz+1su zyQg7n4?eIhFLiKGPum-yyt9qtxb61+KiKEn&(!3fYdE?2ncd1ol^TZfER$pTABvWo zxvM%Wd&Ed-ppQXFL}B3Ro^a?d+%!elmj!k`Yv^> zn5-%eh`Y$c+kK$ zNs)bq`GFG-s1%hS`0qLe@P3 zJBw2`XWcond7(i2+}vdk50`zel-*Y>vaqbwarw8Y`?k8VJgAVG@Nn(STbJ&fT3$JG z{+o@L=fCA%GH>5G`Muu`6a>xryXgnNN`l?n1IBf;>bs}&@n-hOp7p=<@8-mF%TK-h z^>lCe{1VGut74MZq<84uT(Qr$So`fu1MN2#PKh1QU3F)|RFO?rD_4uFW`?|Lp0RrA z;pxxk|Irh?wZZtA)n}iTuOy|GJKZdsUE_Jm#9EW}@Yh@G;@ZkBwyl}I;X-%pLQDVn zX^W5j>vcKO(^cASpS1n%gMZ3XK0Um-`T6$ubuv8Re?Hj$br8?#RYDXO`IOt`OQ0J$cLYJ+A|P z2rhEqKlvfEHOi22&nxL^q7JP~tG5&^_p7e&eyaQENu`mAj$V;UWPhjjq%T)aRh<=x zTlA8-VgJeYW%gYLvD<0{)C+9ZUv}%By0)iP*#bcMxPT|JK0itcp|3SJhx$Q)_z|OE2EQF9=y%9 zsfeAk>EirD^V%hA532=e6*(}hevu}^B)G^y+QNa4D`SBPOR}1alja0QS$S^F)rY&Q zJc_j3y{d&~MxW&HGe7fRzxw^R?8s?zD{CJcJ&*cblqV=Tar>^FdS$V9dQa!-FfU@g z%Wo55;?^YI!oqL!SzN)<`w#1fwicEkWtEBtml7gRWSQPw#=ZS*+1A+WYgV0E({rZd zL`P3Y@y+V>Tc6EI=8?O0D=;#5f$wQf*WYK_17gaKSXLj8%C0N!$^WyDEyQr8oNCYp zR}SW|-sd|)RxX?zF2AV%25at0R!hgIsZqNo@7h=X!Y@AOop05~_wV!oDx>DXWxrtsVfb(1+Dr&rWoJQ`Y9r{ zb^3%m7fW}}wq1VpGyChm%F~ON%U;cno_?wATAWOgc}P#qrtiXQuAd5VO1&EP^Mas| z{lz`21iqhcS-9+)$+>m+b{1D?u$)z#B;mSk!BndymCx@rM(eW+b~r{qPP}ga`(4F* z(^+M{mXT|(oIcz9=TEfJf${)npBIl`?3jEsd@{$~$VrE9-(@TP{B+yz_RG^Z{QkN> zFF$YH`j3weW|gxBd9c5Akeueg!yLwF^o4nnv#8&NmZT3%d|N6v^ep6A%b+j1#;j4@ zrMcgM@vQy&1xz7FSd14m@Pvu~>I`R4+{~vbBKPEq(@Iw{jd{X%EoAS6tLof}++ieM zm{Kh5pJ6&BPeQjde#nrnKWhd}P2(apT>y#`x`j54lv2$XDXD>&atY)x&>?@mgQLCmt zjWWjLlN8_Te-+j>VSluAe{zfp1A_vCr;B4qeS7lpKTE$=byjpN7Rhe7c_!LYlgY*Dyj`y z+x&IIi;PDR#gWn7UXpridA3WxeY;CEV*ZoqnF-D(nzraYp7eJquaozy!!m0pn>$x`O+@9s z?1Os-X{ug=kEX88U&}qWiaTkkghoGG*QIWiFV92Y#jUfy9kXhGMfG>_eY>sua_`G{ zN8T;GwEJ&Kk>Br^%WnT^n(pjo|2X#0m;UB$^)OpiDIzS$RLEPFqVts&I*6;hKEdTP}xC3sBw0G}(nV+}l&*-k?>?Q8fKdKCFUWpREy;YL=UD4)u^#ywT zrN1>#6z{LHd$DRwRpCvG$|L)ZCQB!uu=)1niJn4RO7b3$w~Np5bxzr}J1z4Z%N$W* zSeL{ePD|X@1q${6OO-o60>a9)S0jS<+wlF zd%L$;8=f%yETh!?oYRHrnNzHr$QB2YA2!OG*}2-EihItz|)%=e`V{zkk>NqgvY1g1cX~t?8X@!RYn=@XH737w2x3 znRhlNMcc)(cTUy|g%vir2VK|avtENFbFL=IiYALK3&T~MO;~iVxXeo6eWJiBtfI`5 z6TqgKaH8p1Mw?KEa7Dvey>$%w$6bT;3fN~VA5=XfGqtmA(vG*kz1*A@oe|7QD#$t$ zxO7(k65-8jd3i!U1u#vjE|ZGQ(~$T2zf=6z)Wc$LFXVlD`S9QA@S1%x=IJtizi+IO z=?grruX@FM8GyGFFN~R_0O--3z&aBZhdxqdwk<;c6Ih2VRPOw zXS#;x>`v0z9lP{RrtQ4E4|j?Wo5kgP_uugGEZbUZX}@=0|D^2x&6ixl8zGtMd}L~% z&en>p4|mefoQe)Y*a+ z%U_<1ldF+FfB)UQdgHgwTfLkrF1*Wqdtv$`hhQIv(jF%5ONP5xu5F(D+Nzc@{MXSx zf8U!d`1kaG#{X9HH#Z9^HSHU}NxzbkiC~@N@cg2AlvC-1>6JTf8qAgT%V4>{B+-6A z`_zU4m*-{0GY>HKWH6t&$l7r9YMzypNY|Z_eyGdos(oC&8=C|G&pXsq#wAy3pahJ81e|>2B_kA<3 zx^-}s$;+zxs(D*(Us`qfkJ88F^VMcWQQJKd732>~vofe!dDb}Ag+HX73Ka-d>X^#k%xbsdxFe+vZ&hPI;WoROv}7axO{u zvQRaNOOw<2anXv$Z{4bQ=doT>-@(=(`6OfCj1?;sCHFXLCv^8tzqM#i4U44>v+@?D z^Ul${lN8$Y8d+yfd!DXR&>!$9py0`>o?C&*e1e)0mcJBBCrj@%HdjoV+w$#U2;)la zr3LSM*1BfruARC14vVxBK&9{_9hSANT~99eTDSUSa9d7J?Yg2@=jXd?F7Llz`}DBb3(BSy{5|E2GI_MDP?*|4tX>w~THD%Ryj$bWnO z^5^br2QA+I{=E9_@>8$t6Hlpk{_bgi7yIz5`Kq;2Ci3k z_xtewPh^j|`#1aBx%%_GKQ5*Hd0M~!SlA2V+`=0^j^mP(Pn4@wdp zyFwIF910>VJ7?%rZ`^lt)fC?hvxZ>%TUCpmt&Y9z)+zRs?|Ap6?`b}UhWvcZJne@o zOSk9g-zYz``rTsdyWQVjg>UZPy|VZ2+-v2Uk&nI#yi{H(@3rm;LsUiqOL)f% zg|>Wpq4a>Q{J?{jtkX6Mf(ItF81=IYtvDpRRc~pqU{9laStdlVCB?l` zx$w#D5l6th{K=O4o6>gIG93>*BfIx)O^&(H;%iSmj`!&3Mt$1UQ?5%VAIP5m z`*(QClWE^fcTZJ`Y7U=pIO6A*%{Wk`Lf&X-uM0I;n(pu_J4eJ;jZkp z*W0SEo{RUDcG;!OmtthOCUg1Ooh7=<9;_=A|Jro@{E70P54J;FFge`?%j_C2as-NH zDOF`S<)04jmdc7%(ko$d+i{2`>>#6{fkRK{0p5qFKkJHxO`B{M(Uv>oigFA`Xv?=V zsJ+|D^mlV?=6?|O@Zq9h_rRxHzRxb@5j_0s?)$s{59VLI z`g`u%;6pd`g6^iTWNYl;Q;k|zHUG%wA7`JP^|JdQy{Y=#d3le$ZF9U=HKiLKx^#0@ z*zPuIuZCSeUpZHoom~HSm5ki6;-2)o1#iFHE0;MC|F^t-{_kIT-%q{U5XK~Ab9nm; zre_LmKaErr%f38M?7Z&Xc&ea5YKKGlaqUxvyc^nV-tS~K31E`D@urb0>p`1WK%1O& zHm`#?ymi8!c*?$Xfk=WNw_dDv3DrUc+NX9XXTr-`_H$?aqrr!dE{YBbAnNT zv$;RhFC(@c6=$S1E=Xt7NF#I{O?4*E@ z($`%#+g+a?@sP1PzFM>~IZM|yD=ls1mJHpF4ACh)*VT^NHYqQ9aqw!d;jZ$~prtwG z@AgFek4jXS@VBjU%FAbIHuWaAH(YZ+Qf!x{W_RxX$N3i`>fTI0`+mE<*T(s#nXdm` z>OVf+9MZ3}Nw!+)?ndodjhAbDV>P4rmH6!<>?*0+gXoHn>qGBzx`Zn@3TYheO=qm=T|iOU%xy0 z^k;U>Ci&AlcKwN~$o{kDrd6!{&K)J?LgIH7;~KPPG4pP7KNRPGao6U{2V{?T%#Z)u z{GX}ei^ZSf`nwjr=IgWB(>63RKZ;m8t$-=Whc7V2X=&@dxaTbgBhFkiUbtPet-<DflCs`1+`&sC{!tKkiZLOMApsbNBQ5rinQ}(d-m$|#u=YD@) zTUoPtXZ4G4&*1r~v#WOFwl3Y1(|+hg968v=u%zkPDpT3u$^8ke z%r_?RG_~%%_e>~|p*SGWb#?%|#NzZ4M%4>4C0-nihE9r1myaISV@VfK?rStVV3d^L zaGE2!=4r3vCYRS+7!2n;V6b)ooj4&^rqJ+q&KBnd4aNuTH>Mvwp6_7G=DnTO*T&rN zd6FpWk%WfQ0#^g20tFeCf(>)UnWGJgHtgD-VdZmTj_i`wJ6pHz;Z0sQbymJ3`zE0? zfx+FM#a4G5ySP$r)4eHnf%D%y;Za}zaj#y+Rizbau3`lN;#z_!D;YFahMrn6`K|Sv z4&^-aTenNKH`pCam5rF*C#PEBI(y?`(L{lGi^^95PQ?}r!y*{9ZWt_Y4Qph$Ig$HQ z%^mg~%x8JtEqIWy?H-qq3x7gdNV`GyrYG}sPjr1LIvgy%h1cw(p}D_C>r&UY^bZD4 z&*)vTdKzm!G41aB`k$Zvcpr6m8)@g`_jtxD-s`ESs{R%JnQ{3?;~Zm^0dMx z>1Q}et=pY<>($nIv2#AWdv`eh?$2lUCms&|mvQ6I-uWKNBQYbgED=&8EyqaAF&&$tm_rF*FS^m%Vbosx5la715d{TY?#=h^dYgNOvr(a%X zX|X{p+$(8f{LdHN^-qt^J^#+X{-sH;N9O*YJbL%7r2ln<&1u*jY`Zfr^}ve*4Y&4p z@_zZczTDjWyU5cwtG~{@zgYg?IhLHdkK%mg|Fvr38`mCUG~A(MH$USAM=Vo=*zr%H zY?d`>7&w|pz?wfL*Uy_J`)%sSS4S>X1yJI6(j`6}zHUal)y zzv9srZYitePurfk=YMdv{r&2S-JZIfFloFT1-V zkzr#C!@08-MjPY<4I_M}d&^%~xNk#@WOw=8Ttl7+SCb75pM#2%5*S?iZZ&a;w|0?4rbj zjGL!Coer$?Ua?g~?BWD3MSB)iT(R8bl3!Zp6-zv(VxbEo6F7xYL zLQ^JhQ~&OuKiPssW^3Lows(E)zvFk_beOMPc3pKw?FU0?zpx^mm&c1X#B@azsW`qq zo-(b@XZMr(s`V?UKPp<6cJ*}S3EBo3Dw*UX0J=>fi zQo9ugJ^2=vEi!zrR$xeWHKfwtTr!*7QewUC+}#Z#Pk#lhe&*~eZc(EAX*$)Q zU-4`I`@DOn*6*Jge%^3T`Q2RUwT`z<%P*GtFXUfsQ~IW30bdYHqp*U;Me#@v7QF&@ zVTZmZ&1tJ98K&@U4D^V)b6@bm(#UNJ{CB2hPP)k8nDoIX*?fY&S(%Z*LB^TF6^}TM zC7f}qR#MO}X`5+eHGP2;bCcR>g9k=J9^JFE_VM27Z#8G#di3_cO*@p`UyDAQ=@Ne; z;&k-v%2l7$A78ksa?x4q0QdB6j$TDkv)d0#-)JsnQ0NUh^6i%u>+VfK9bwy;|u7R}7`di_r3dXBr%Zw8;uGyngv-h6SD%=ruTb*G+u+NgBx zj-0KGyUx>yM?!b56lXmt{c_dSNB@(>I{BJ}n8`L%t0u4Cw_h%4YrR7||Hk#dUTlo7 z$!eXIAX~ZNn`Wb|FG^w z{~0@_dcU;+u1s?-++w=Dq)TB7laE8|HPw5HX}gv+bEGX`U_DaEw1g$JhfO@E%7cBn zYuCX5EhPuui?RnlGN!cX9GBzT(LBx5euMsxuQL{k^WG7-o0KqrX`B_4$h0?yl26ZJ zu<}x!*FQrtZ3btY{YxG$o#wRre+79AryuDME73A^aS%OoK*pt_<#eFKt4ZA^{Ikj& z9vLqZUE#I%BqJ$-^P`e{MqNu)CIY%42#a*HSgVh?d_{&>;X&i=N)eE@TfUz zz_xqB`aF+0Geg&Vbi4>UJ9+88ux-~C8HgJzFEra4WqdhT>>+q`@x?srAIWW z&j|;zx!3hPJL)@+2v(qgJW!So4Cgw{3mjmd9ta3*D> z(01qS`#tyfe_wp|uzlG7jJ^AsckfjG zIQ}|IMcYxYR!C5F)5b4#nzC0X@7Z0EdZ%XDoIAH`|IM%bw>92+&(Ede>+Ano%{5q+ zequ-8B({C&y;u1US9wSI^6@A~2Fir7yk47a{e*dC$SHZkzOO(ch!>&GtKNejckg;(qh}{*UkXen0T`mupaGSbtaQ&Bk&{94P@#R!y5a#DYE>9X@e7(Jiy{erJQ`j^$iw?_5nR4yb4uS!FF{smPl9 zyGv^Fb}^}2w|2RTl&_4Nt9Hmk?9P@}Gw-xD)~_dV>E)R8P1toQV69Y;Q~RVdsul-& zXGD1{Jh?LU-{-GycE@gi{lB!4m4Q>HgO6=O(xRouFEW`NznnHBF)4%fV$dBWcfkl} z)hSF2kr%k1SU7c5?kbSG|B~_P6;Xz!NsA|MD~jZe&AwWmx(f;Ws`>)wQG*;ab{JZt1M6JoZ`BlaFhpo2mUj8^c{@6+BmnnBIs`$^pb@sB3 z>DBa`{I5%Y@7(`Cet*%|wabz{SGXJ%x*!=LZyRY})%_{-{q)7fPw!>2@3NGXpWnxy zv1skv>pR5mtT`Q8^(}AGzS>`YyDLI7uB!Or^^S9=UYX++9c|Ug zHpy;s_W@g#!lP+Rg2P{MEo*3a#rkq?iSf(4jh~+X7GGNM>S6rvuOH8?fAIa^vVGsJ z^&9?5|8V$s_WSAQ9rx|ycQ`L0>)&G01IfbX63u9s#{W$wqs?y1{x zgorUhHi;$>lK=0m;W!&@v3a*T+~?l zQ2a83s(>=b;=?(TZELxfKNZUDi&EV7M9AvE=7ZUNhs7$`w2d70BwRjtdSag2)N}RT zeN`unA{>|!1ssJW3Sy54NEGob=4kuubY>RsgOZY}K%KI6m9wsJ6o@qaoRq4_aNKB4 z#^&aJ1tzr_GFPV_ls+c7aKV*EPY=(Reb=h2Zq4+U%9Vb-@Kl6X;i&^0t5#0!TQ{}6 zL+HxMRZZR=FO%*sKmEqKPkd#M*^!W~M^~*3vMccN@Z3_QyqRS~wnNxWnX41CAC~OC zcyC>F<5$jgCkhUPPw3g>q~R6CbbUska7CTP3;!E+pLO~qodQ`iINDf`2yU}^t>M5^ z*sPoNu7cDxAMM+CATiMOU?advgZ1E`|r;x{+rm=)qGlPpL6?nrA^Mgf9Lkf*Y38r ziL3qp`@4Mog@=iM!CEd6$??7*UyO^@DP-kv2^l7GeB{z7()w2Z^Cmp>9}9qybq-~VZSd4I;&{ePCL z^D2LM(f$A2V)uNTKZ<<*4}~obvl%$>>KYgvI>376!InQ0x21Bau#6ho>gz z(@e=LeTH@{?2F{GP??!r*^ zJIR8P&C`Rkvh|)okI{J_RtN70SMCtUmlv!o7Hbx{GIIxfG^av}?5f{aRG+uyvNU1)uu`(-F(kvQk{@@Z0!&v8ASUY}h5z2xur z|9;e^}5wn~ANhO|c+j#$=AD15y=DY96gZS*#y}E^;&* zt&uyp#NwV~1e;xs-b9vXhYsrOpKw8F#zmuBQr8RxwKHAwP959(oNLC_I;BhN4t91c zPAZ&{_h?D7pGb6D;4ZGPr;dx(B|qrPvbtY-ZOvwud{TFr^gs)VItKD4r``usu z+spSwRoe*f6xps4`PnOc(+LPF-yShc_u*T2 zBw3hVRPDY9F3~;n9`RlbU_F~q9J<@xtH9laCzrFx_xSr2mbd22zSbzRq+vmsgX`J_ zZOa4>StfI41&`eH&*>i~?TvAtmgE`T z;@T~7{>!f?-qW6oHEPDM3p00_Yh9a=zwiFOqV4QFr;9n=rNthq|6Kq7``3B@&tIRP z8!)5pOrP5U#s`a^*4zBLug!4B*OJ|{U(cj>`tI}lem$E1KYZ2w*tcz;(;rvm>%Q1B z@4=e=|GtDDmtI+Z?fu_N`>Tq7Web+SaJb9vueb02?sED1&wJ{sFYgsNWfg14=lha% ze$3^YzV-Ycn)ldkF;^3M67~DK{{DjdyY}6Y|3 zlAn+LSQWcK-&T)xLE7R5yBv1!vYgT_b~|E!qSU7U4V8tTKcAG2abw&Tzr()v?fQ?& z)_?czzxZFmMdR1eySLNz_g$_3B6rMti!5Jmq2KnljSDOnJ$&Hc%)Q0IVA;%vb_b+f z1X|Kgh{h^d-k892RG{yScgn*#lb&~VwHiD)r?YCx(c%6?{0Aomy zxaXbe976jP&xdBcE}O<>p0}rO*}5%@*UsGPB)G8dfm5kh@rY}6363KJc@0*^ojOYsE>s#ahO%c*a;Ixsx)c>y3u8-y1 zJ$>#aKfe~=?XFuiC+(xj;X7|nG|g9?@?+A?2b&_+PupH#lebq!Pc6==F0JE_jo*vL zgcY*ND4~^n>69VoIAzL?}NK6uj`l?Wk#$Ncw}IBS!uJwYKBQ>Tx%pX zpBvtoHCg3ZNz(e7e-jEN94~JRl`snA)egU$m9g<QE8 z+xcDXH_q3^EnsGt!zdZS_;+LCDTWXFC(X}&-xjoD|Bi|uYu~ot_s!mYxvX6N|AQ}i z_t(E)S2XSVyVI+#3I^q!yZ?9bC$H}pukYit)K&YFv;EgQ>)ZRkT7R$qoqxCX`S z)!o&a_tF@ZD9j?Git)`qY->bgrU~oLMn)AP@GF)j8{y?ssCV ze3fxMRXwm|M#fYV3tQ&t2|f$YSg-fk<9E$nC9gS1JNZ*aj_Q>t>s(E*2}`{$Zs)tQ zY4@qRyByhtPwrOMJkHtmsXM+@YTd-|XBJObdUjQ`x}d`;n>`nH?R$Ru^6&7~drT}W zn`Mm-JzMdF>vQdYfG zo>|dFT_04hwLRfT3HOLL+9KHf{BCNZEsL|v6vtf;?mq62-R3Y?HkLQ(bnb^qwW2&{ zQrKBf7ik;n9<(ra%xk;V?zlll=7X7co%&yD0?2~C(N;v1ORxc`h;tnrKmENoGH zUygD67AP}JD}2cj5>+GR-0n8RYQdq0XObl>IhQ+sum})rzI;Mt+8IW7-$ye|F0em! z+uF5UBHYAx-4ojj=BoGemVb)Wj9{LSzCv!xtK1Ymsf_sdp)#vYt4a#CFD_bTKlkIG z&B0rLxm@=)YGqbGZvJo5L%a9p;Xe*#o5xT7D;-<2t4`pxf9&5!`(>7u&);AF>(9fZ z?fd7OInM5l<)6*|KF{utoqE~H#rys}j{kFgUd=yoY5xZo&+IC5*yHhX+2i!Z3a;C^ zZq@vF{Q2RpCpXK@>vY?fKllIt;9mc}pSR@yU7MT#x9p+tkz1Lsxn2i`FE{-joPD?d zzHqd5*vk)zr)?fyiHet0Gf#VQh_}{wZc_CJ^OY|h3wAiVC@MM^?P}WFcG$O$OJZH) zp^naH@3McN+W%ty-_~DO{Qte!pOt-O^L+i2%bw4EZht4PRw318v1_GYW5$Xt4fYid z+#R~5I`aZ@GldJ8HSYvAb~;>Udh=Gs%6J!(-wUQW0-Tk0bvX{c$5cG-p0IV{jW*Oe zdBM#0@R9?YwRk-|o<%L%JdM*L#nwl+E0jCEByrjgR^jV!lHMrv-#Mhd#8Z9lf*_8y zA0G(w3m;r3tQWuVe&6QFWf$$=zrGOpQlrYRX4^Zzi7D=X_8jZp(I>GhBud z#4IKz;Q(hfgY#y)j&95Bd8OcJ=5T;_od=6SgrmFIix_+NCiNA~!X}Q=5sqvYDS2Dj zniAV4v}QW83c8DE9k_cbdVXVQx24^*EHU#7Ij;Rn8J2M=ZfMx}Vf!;3mC8yzMwJ8m zb{t_i@@MV2Wxv@Z7DexB%>B0RS?ZbNPi9nmeAwlXxTSGcZ*R1L#f*9D<1!a?if}H` zy~O>gQ)R*RgRMIm=eAAcm(h>OV{mx2%_nEEjE%fhz~ZelI_89^ALY^vU9)V>l}+CB z-uNj8z!kB zD7N!3Ppb{LN4w6{EwY!E-+iAi=QPiLU9ynvhDh#7CflrHiy!^dP`ks@*@wTk-DmXCDvI#jE$8>*)gxmSNsoh4vZw!b-TR$b_2u8mZukG})%mxw zJ*%F4|Ev6{a^9KA&+jbF3;lZUO!b1w#EN?{Db?( z2K$!#k{b*s9q&FOSmkE?s9?v}pxD>3=O_Kt5qu~d3?szx) z`<+ugJwJ}WR}U*L&EKMB~4T2tru-x6zLG(_F6pa z@{RRt*J_4lmru@*;)n@L%VxESv6#Hn&9w4^(4sJbNbdI$?B#=R?edg`v5-`^Rt#$RM@5&hMX62WTVtkrQb<>L*81#J%k8mb%&HY+|^5wvVe z$EMVKTp>rcxx8uCl{L-hVC++NJtTf_mt5)@zZFF)i`!CPnP;<~Wzb>y*~+(`gYnqu ztBq1R2c%C3Fp5|lR$dU$F4%N{XHh~sD@*jIKl9Z;#Vl~x)@0Uc(cZjfomqB%?8Uy* z4<1gOZWmTg{)Kfq!ilf&INv1z~Hv*S(;wvqzDDpfM*lev|VdT z-C%7kEEs%c#f!ZP(@&(VYVf#M^P$K=BmCpjrx)fuxn*6+(VTL-~-A zCo)bPcUtu~sMqzsSaikze{(Bib}(8cFtZ$Je79Qr4bxxq=YQ<~h}ReV{T~14V}AWF z`@LKLE8eXw(Gp`a4i=fHHP=`%{gvMS?~Y$hWea{keee7Cb};W8tGUb8Z7GKn^i42aH3x%p#9s|1GV*^d6sflhX307 z>u5o(ZqI?8JENCQUFf2EtMc{)O9N9^qa%Ms1x)8vys4e@>&M~?O9QUY)vMh#?SlUf zR-PO6ulpZ)=KFs-8UJVd+mhI8&ov%xzxz-9{XJXRWz12{;%gcl7<9Lv^Ez$OA)A-r zz&(qAR>-jUBBL}0hgbd8Yng1u6OZ&YL%W&}TY zw3c~ww!_MpiVqgAZZ0w0VkGu#(S*z?Ja^rvbj3|m>*;a~;M!@P*LJM7aK!>GtG2B+ zJo598&%fPl&j0#wU)Xhtawf6h`q3E6=&UbUcEed`d<&mqnDy5G3hxtXB#+K zvzsE}_<|XXtak2eG9GR;($AjLJ-ux@ce276-4l`bY{biR z{mx1=%+PtEsq|ydM|XuNuY@d)&8<<42RL#PqV2XYtVz&0dM)P0N1K!>ssBzKe{#*| zc2K+aq31$wv6JR8nZ(_TP5ZG&;bjI(Kw#uf)8gL3H#U>k+>yB?tQWC>apK_x3VsHI&Z#xJLzhG zy5aK8zop-TQ}%&i(WMJ5Z4NLREYdgc(Rg6#d(oL$Ab@l7f>V>kOq)aB)c%}5x0xrm z&W^{RsfCr%c=4pEf-G7mSgZ^AuO{0qX7CoODwD6D(t5)c;6TV7H z#le{idzYKo)}43%aK5gn@UQ*)TV6*y*Yet!S=Yuq+=Y&{YdGTy7XVq`S~ ze$-Eps$1-5wQN(#OKXS5&*uI6_p;0VRnLFiZ}sojU&qNJh&pYY@ff? zPSdTAY|gwY%*$Ij%TA>^gFn*ve&)^`$#zSPDHnL!E35ZOOwD!K<12iAjIrirJdBGRL{-ENef6vm^y7c~=Ig|`yKM%J#%oR1U9M7{ zRCaJ))$fY<(;>f4K0MeU{-(Nbg514>oMxv}o_)%`*VO6#=73fdvww$Ry+lo71Mci0>*4cIYqe>OuTN}6cZZ+1DmGbdde|d3A6T^jV4`p~? zTn&!0wqBsSyE;$h%DNn(1$|FU^EO|JI=Mw?i{Qj>>mL8@{r2yUctrezK*yP_0$lb= zzcwwB40#~Ci&w>oDa&Q?QOm@(iwk?06(x5xJpcG8r!B9;p=3pKW#C#~$vYR6G#W2$ zl1};X!ZdOJqUMC6Zyw2_6P`FIx86ybso(A5_eSpc1*rpjwv~N~-g;=>UKzW;@#dG! z)}BwU@sW`W`g@nX{r``@^L2bzR{U{1AiH69Vw(edOFgr|Yx5^23QP}AWV~Qt@?-k& zoS`B8z{B15|6aTQcW?gw&+itetN;J`_SO6=TI<$|+FuDiKH*c{-|O|eetz-4{?hYx zfd9pPzhqBv&fH)YawXTY_Sfaj;`5J*+eiKVad@)&|L4zMtv^5iZ;b2j*QX!e>ty0&)%nuiS{V{rRY2^}@C#maPvwik|mft4uX!7iT?*C7J`5}F;z0N9O z_xyQlJ}=LoZq3qo#`0O_MhR`^Oiyj81a=el)0-@Id}kR<=mAauB!XYa)d#!WYrYpw-A5Cl85YKK|62~I2 zQDv)8*gbJup^K~%b0oL76uPKIu!`t(NVHend^~ghUei}Q)=tZ1mupTqs_i29GQXw% z-M<{CwY;L`jrAra@_89vZ4bC_B&=MgwBP|7!?Xu1x(TiF54LHf*36rCj^{i>SpYLj z*u^x4t9vvPy07zZp7Z>(s8e*9p?x`fQS_0o3{lL&a~dk6)Eg9&B(wD#%B+}NwHN7s z_GJo5;CZfm(D5Ljkb&;Lxie2cC_Nazu#qE&W7iYj9*58E8Q%OC8P$vU)-6a$n&~k` zE2CVfDE(gLq?MnQ0<+&bTd1slCTVJvfAFZYGG9z$u5)ilV(F5=o5%I4^w+mOY|+@k zHdpPrz=_#Qg%)RVthL)&y&(cji=+Wnj{qhE88tAgyx zqfDI-OedM;m32kq5_q=`LW_xXqU(<$N-yTSL`$h9E<o(TUZEI#wOJI?jz{nVOfK6f^ zWBsN*Z{E#G{`+ZmV#MC>pSIqwzxZF)Gx$rMt;Yg}8OFcf#>Lt7|IW?$z-#yW*89Hr zzv}|RC6-oSNeP}``%J!8rT(u<&5y(%)9pLT&)0l-_^Wlzr>ooV?W_H8?rZqI<8r(o zwt0za+?ZGcV8S-#QRnm9cuC{QPZ&#Tj!e-ZAu^jJ|N|`kpN29H&Fm z+S1e*7rbl@<7=I3R>&_iL25-J|BQ!h8$^%Y|8@S=WAiOuwp%=8? zn%)1CGdF*s`G=;s#D*{vX67OW&M3FF7x?ZhV2x7bb*=9_XYjm|r7?kpqo_Sbk&*3< za*>mQizD|9gFUSxe7Y>Ix72-{6vQ02evPoobv&~t*P>*CwMy8DxNB|&_f74(lUQAY z-sQg9li7OvNh4FU&TUDGWBJZh>gzN=+!?~pn#XWZMsLB6iZv%0te<_-;`or4 zxt8&P*(B5DFLc^!pR+5T(l&pz&t*P?#gdb!6dvsL;?y|9wKHVi-nI#uPNjLuhZmnZ z{5{xWZA;AL$ql>rZf47CTh${Y`DW&q{znGH-Y9;%7>ocdf)@8e?u~llVrCkY^tg9!Wkw z|37r=*M;k%B3hX?&NV);bo=Ur4_rHs{9{|xA*#+Gylwsd%I{n4H7;iU+G6+P+P|;+ z#V@;ND8J?Vecmr`Ud>tcCtUO1_j9iE;NoA6TLGA+6kqyev`~*d(nQSYasX2A#?v?TWt5s%o1iNQSJEavd81_B#t7MQr z(lguR%EhC#1?OL7$Xb;fiMR&7(Aj@0F-Jhb!0RwefYU9X*;oBn{@uaTzwqg@Yp1&c ztG_SoS62y~Q+{N9kKMb+m#@d`uiv}Puk3By!X?ht0i00HNW zo2o~iN3b)deF)v|aO3%;?3WjpD=UTdU6N-0xQXqB?4EYl2&VI=J6ZTM_)K=l-xT0I zvY}+pH0wF;&mINEm_HMIXJfFWs_9Iu zsi6}*Wmsp#{eAQDZujY1GiP%wJJfvDEB9!JmX^l4S0x!Hi>5Ts_j)L{r*ilHi}&XL zW_sPd_www8k}D2M|B(oZi2AfmC*b^??-ubFID(tpu5{dT{=HOCPG)uT>(jC-8(6p) z4$Fj2uwKzD6y@+n?0}Vgbfg%=jux34ES(w^d)nTpuJYQLV(RA<{me;m=A7Hpo?LZb zz5Dgm#O{A3<=^%me)qQB-2U(F{^crcKL5A#O=GT3=vS>W{x|8XrOx?d`!7xY@czfk zjk0UcZ;oBd$h?8+!=H#)#%;_p65B0%r!o^or`qyjk0;lL6*VjL*V#_ZrNG|;P z_V)h2&Gmoc>wi7{|H6I$|Ngv3m4P2tTjv|@==PkGP+#jRZ_908S+wBm+v)qxU3k`5 zd8%yQ-q-J>mtcUq&ja{ADdm z*Vco^I!i8X6_OXTd!3(G)4cI8*MzPrb_SCs<#qc$^553FkeFR$S@(h0$~^U0+@+^m ze%~ypzFgY1C}F`F;SEfI0nY0LW;e%kyIhf-tZdygfkjvU`#T{<=LM{f>;+o}@#qHWz}5zAxQ&rYv6 z>b+^U@Ktuv-dET9Q;L@y%{=U*W#@kMdE`p=3Cyfz7L%^Yc8XcPm?OY`n1_>t*Yu#W z$stbNgUlTYETIJvZ%%*lcKrSGwY2C%iK{`88ZpHe0x~z=JQMk~_0xoh#`_wQu2{g< z0yH`lpYA=dE9LF^-_PVa$LlTLyxLQejg4K& z^^CyV_CWUHPsa|1U6b=z>~QcdYjvAcON!bQr(e6zy?3fOsC$HSq3M^US$k}AmaqNP z*tGiH^);@qFRbvmx6G?h=n{+frcj4Tsm4unLngs{nv-Qi7c_}Ylrd~N)RZj2dCL9G z&p!{YH!{_@G04f+F)5!ZV2|AKmfP0*AWy1CgIj>piVYi9=*L`SmI`1sbYjv_G&+&M zsMeaXsbyBrP8YpNc~vV#R`V}Dw&Sh*rH5wMrxa?HRxf(2)!X=K@wY#(`QsS<8_w5V zoO(-kzBm5?-oDzp1^?Xi`1SIo74}bY^*&(1@ALgM_rE`ide0cM-hXM}h|(*1n;oCY z`^t$!dcVc(_!yZtf2+1G?^qcx&3oHo&z}d){{J4<@2veXclX!pd3yV1dNV{+Hs6^3 z{eGTJh~?gz*V*&y{>#VD+uzT0edE)uA>8fDcAaHj(R{*q$tq3J{Hog7!Ttw3_*#G8 zeYMvhZhl))*6%6X(-vOOd}WytBF*3iCbFIq+qKrjtvEDYZRL{Xr~-# zx$^MCG5ZzI^DB17eB^(1d;e5?MCTR)NyhqKjC6{7abG<55(c{z=S>Tl*+07tbxB zNTWrer(>P7D=$|Hth6lAt;!YK`2Nn$%DgPjsTX*5Z@8l3x#9hSrkvy30+|_tJe>VI zBKXCf`*+{kzf7t;j<0fh^yhsG?Q`#*lwfz>e>ZyP?sd2KNLj85d~92-n7w8Jo1Is_ zhvyQ{G!t1x`O?UcTe# znIPtQZjYRVa*M(2v}a50PZ*s@Zo0BGWR`PylDBT^HkH*02F#3SPA_}-XIWL;x}<;` zIgc&fE^KjN=*?g>*19M9rr4tApkjntQpMcPn3y}!8=?;`tSrcnvEo#7alM`*_9W=2 zitjm}-UIL6ip*3 zZ0<$ZcTE@TdBt3}tJ|K_|I7EFUysWV)${LZ{w7rAVk{A`zU( z$uYAnu$C&aTb_7!*BtK^|JS{cE98Ef!+&R^`O2;p;#W-rPBR$?apbbedxe+lW%IL7 zp7S}XUFAdi{XhHG-hOr5-p{e)g~RTX;oG>{x9|V*<@15wS^nr1CaBpKFIH2aV0ibD)l0`KqryY?(yzoy)__V@Nvi}{!Q zUVW}<`UzU$`iJe1#Idw97O{i8FJ%t<>uVu)7qqITW0WffY;q}5TJ zt=+_3#v<&|yp{EsRDZnh{NktXi>}`3O=B|GXqGZzD4usWLG;*xH}kKhMjba^?)7lb zhYxcUc-O3G_!%_k;f<4J4U+2?uqoaUj1&`D;L7*bxXP~aRnb-D=$clhD>I818$>_I zbW>>6G(2IdIY+ZQC_=MVplNa%D zbu@5CF(ltyzLNLD)0;h<1sSf&Dp4E}*A~d~Ea*D*qS43u(?KJT3ld8#EZQ0lNr;@< z&@zG1jaB6!&zcDgYaeuUig6#EB50LiyzXR=v0`Odq4S~}K6`Flc>h1A;+uHU4{fu| z+|Q4{-3{+5`?e!n@b~r&yN|w=;{TT6J>ze^wz~b^sK0sNAC+_LVEvJC@t~mXFX@Qn zvzreUq}*Xom~Y5%onQa-s~m;-Ke}6()S*SK=1NO+9&N;Y+tG z*YmW$YrJh)6P=r{wY!V0S-P|MjOmU6$`?i!<`|Qru6CR|=czM)jh0R^?*F$F4CCiB-S*tbItX&&) z=l#X+VUu#Qg_o^r)A49iQfStavG83XY8EUlp}IIdB6@+Uws-qx?W(ugUoLKTdf)Qn zHUKSO$#LnpNC8mI~aL_1sdHH93@j0Ffi|6`p2!%bS`M_Oz$!o@hbK# z0f$=6IbSq1=Cm*Vd_VsAqI9*;Ge$B|O5eVDi?>voJH9gdyM&2} zO{yv{YT>UrmucKzl^D_~q?Zlvb3H)7e!O-J2CcI94NnE!p#b8uq6 zxcEeq4+k$}z%SQJ4boEtcy2bzoqW)j#?i8}i7{D2QR|o7&4YcK3yNLbLP8u^I}OBC z8WR<{qxdsV^Efsb9dK7TAhqbQP>cfO)`K#Q+&sLB?C&K_Q<^GY)ZSkxQ^QkJ>8^S8 zM}c@k%lTKc>%;W+ZLjWHEgVz+;+sTci+%m4YxDQ~`L* zN67N4SN+xH-kkkDC1A=-fi3H&NEf=stF>%S{Qj%_>)dy}*Y{ny`{(u5tNn}ZD{H&0 zt4hA!+y1oj*#Xu`A0%^@RxSG2BzmrH)Bnh5TZ=1~?;JCozjRl=vy=4B(yjTjnlVNH zBVP5k`9^<_t>o-IwewW7Azy9tD*G3oLV9=I-t_LhN?Emwn`#SlO@n$#xb)3uZ&y9O zzJKTb3iFuSApRTsKF(#A&eoq?Arv!pb>8=+7x$dDw{h-pNI$8TT++f8vO}-@yh}zK z%M^|@mR1)LH~t%3%RE?EuCORaFq?jQ@vI>5@`5&lT$O8&Tw6I;ikHPKRv&DN#AX6em44fV*ZndfqJi( z8H;N6hbg3QyLP5zL#1WmvaGY`^qIst zETI`extdK96(XEVTszWdk3AtwiT^qd^tq-?lChaet zIp=!@+w+6vYrfBD`~6wEsxDNqyjk*8OH6^pL}`yeEyw|~ zcr*X+nrr;}r3@Ejf@?P1|6C$)s*OvU**^E~>g=60t0d3xK543T*FE95#_d3K#@f@_ zG8Lj_vHu^v+gkrI@XzV+zjx~<8yAY7{+9B8%lu^@-yAIYH|=bGZ$SO;iMF=_HcVJC zDWckxXR_{ zF`qJ+x$u=2|J0uwyp9~Se0I*sB4Bz^$5yv#i7M-v)b3v0n)aQ8HL5KvgF&g|K;gkS zqiOzb+Gi&48aarzbLBmlvit0gD&2tJJb$f%cLn?G3SWE8%0GRJS9`^#cCjgNEmGc;b8M3^$LTp2 zW$e1S`?qDj5L{_my+-!X2M*zYma~hT8zdAsrtOvcuA0KeAh;ot<7|M%{9Wowh9z-H zWd{#Fj(s@K!eXbi=J{XGU(KtWX=K!D_Mh|2(P;5fp7NPHE7Z7`JTjVj(4=aq3j3#( zEVFl5a;?_Vnsn&)DN7C210H|CW9HTo@oy$t=ENyD%oL3l47kkXdBAbouY~DL*IYU;A^I z(|+c?9akUL)Xkg28Sz;BjQCvPBQJk^j(5It?fLv5+dL7!1FFaVy}nm3cq4wn00&AZulb2liHTmV%$={5=hwIDl`?Xp;_s*%V*ZVTBceE%)en`{( zXp=nC@0|Tl>-ryUufFcSuROV;aMP_ISvGG^)4c2X*M3Z3&Uq%qQF7(j^Rpd0Bfl0D z8}IvW>iKBLVofv043{muC9FmLlGiqCGxfZyDtWzo`cdoeeHK?lkIEG`TRmH0e)nu7 zXZlnJzPQ8t+Wx#**n0Kd)ADn6f71Ew{=EOS{om@EZ*wnyxZJjSMbMp>Vc-4r4?VjT zcG@A7+lldFQt{02)afr4D)LR>w3V$?b?|cM+~UBrq#;~F^sI)Di?nvkVmCiaZiik? z%c^wItrs2lEfzcDcQ-fn-iAkEQWh<;!B2&*@=MJ+ZWOx4c+~+$nd{eE#B2>i1$1+_ zNeRlHeaNnn(4wc5`u4{x`S=eveeWLf3*NgasN{68*UIvX>ptJHSUUG!?y~f-{US<2 z{_3w^ZZ4~;w7YZX?Xg#@k1_P$b5m1gzQqwK%4EKVMIeAFy+J|NM?ut5!IEo%1>3y7 zqSSQ@cG%een0VcRO=!abk&B6pb1rb{F!H^c{?}!>>Kitl#Rn{V&oyYVXfURD)VUnf zRtn&q(sy&cJv?G!bNjR-9~Lfgogo_;!^fr2%DTd74r80xyY@_x z$rJpQ{g+LP_U|<{dzqCf-F!_Y$*^jr&RI<}@tB=v$Ci{&w%;e9#=fFVS5x5b9nBR= zip<-yq^I{}t@AoNbE@n??bkEco&xntA@iSYtPyO&QH&hQidI?%5;hAYtXjjTG=wlN z;HqIU4R8n*amxu{Xo_)UoYug3rBSVbo&CrIzP=2}JIOj6e8mxM?hhIy680@o6T0xj zV!F-;!6ORpFT6@!MEUctuJqn+|Md0pq@+tz|J~i$adEHgx;*=6e|^66^?Xl5e}41* zcQD?6|L2rH3yMyf)Xb7!6f3uR-SJOO|LS!co_SZ=-TM3HdTIE_&vD^4vob#=B|N-zUHS&wi4x&}IMbE9=(V*2v#>%_`z5abZwiS(*A~zTZpP?Xz;H zz7gP?f3oE6p~Xv*WYzBn#i@o>wbs-sjLWaU&DVo1@4?U7`2mc=Up@;rDV({pwBgwcE{z2}9kx?qZ>IY{T3GO) zPkQ?UF0OScOM^7Ww>!9|WzO4sYUSDv3 zBOP=w@t^yt1=|`pIvgBU&rtev#QgH-*WKk`xBBk*mvaCAxn2KPAMV>5t69EKpD~tq z>%{QL_jzx3)ql*3|NZb$Ond37cHbXQT;#4-yps$4e(qFZN%>RWoK~*h6|AxSFHSh< zzVK_5+jdw>zj7n%U4!d}EE1~@aPM#q6<{=O>Sv7K@Wxp3^fRuNIxflIQv-uVN#j@y`0+X{*iE^IFSwq>E48vdc#^S4Eob}l-+zBsRKE#3zg_qLd;9v=qHC8V zT#$J>^HIyWTQ7Es#O~eItFQm^>*kLaXI_yO)L?(%`)V~y@%e??VH0cStvg~S5P0fa z!lu0HPahQiM(m2+e)5~gl1QcW3%orMQej(+r3!D;cY-)71MwDq08d456uV%{ChS_1w8)jt+r ze|c8_`t^OS|4u%=z5lu#FK?P?D8JRN_^I2X6P?yxu$|>BGjl_Eg~QqlnQ5MfB<~1F zESd4vb|bU(3ccjjk(-+tjJL4NFAdUCNeemK)OsXV^WbWSnY=Xu`KzaIoql1H`G)>m z)4P_GZSV=&k!>ol;6qn#^uGHV47N%AOEUVV9v0fgm-0eJNx(USqnJ^+k-381Wv_(Y z(b>;m@c;d0`R7hRaop7!Yu~UvpH1#u>U88=VSfAX*{^=f|1$5kU8;Aq{k(tM=>z3G z(TikX&nsN4Z_khOnk%>5;GCY9$oMRjgEh_2;{T?t2CH~{FMl(bqG1srF*RGmFHKc!G0(2A z7Y_W^yHizux9NN69+v{u`=xL7qEh9LI=C&|`oibbxjQ;ngCFwF+_}1VXKz({=*cyK z&-N~o^U2$D_ul=C_vdRHzp~DI_Mj=^K$%j8q$8T>xs?5x3;l=qpp|F2t-{YIiM?&kP z=I^=j=jh%0)v3(x1t;DuHkxj2c_aJw+1aADwi1VyKYqE|-+x){y!V~QmYOsRZePVw zH^cnJ@eL<~uUzX~S-!FIxoq}z*0qA=p*xJCTE1&AC++z7ut`~cjf=-kU#4%Z$~u#; zJvn#uV$9NaH}miAj8GR8%XxM2t=e*Tp|WI~i+-91mb_nQ*R?`y$Fs``9)BPpvaqgE)beVUT(yX0hN1{dqxB?5*4qtd4zS$T z{V&4iXmz)=|J<8B%l}NA)OKU#m1{-TGG%K;Ud~}w5MH~kyrwqvYn6W6@qN1w*cq-n zRO0=$&9Eq4&Ed|ZJqaNOZzQC@HwZl7o9kd~F!v#&$bn*y)dw@OJ2e$JPdIK8NnD}O zY+`V@!7ADQ`Hb0(&s81c1r~5G@e&WYx~4yYT~O+<){29Sv*OL7cW|F@Y>Vqx-F)zw zo0V>7=@nH;GkwdZKC7dVJbg$13#aK%I3T%5fmtNwf!iWCi@C23SFygm{qRb3hKp)J zMrY3%zZgq_%*f=fXDe4t^1N{IY~hU}37?ireNWF_)#em-^+_`M^z+JmpOSa&5f?vO zv~66OwZ`?74?nXyC&N|PcL6?&L8|Vb5inM+at@S zS-gCECGUQ({9pb2|6lGO35|XDD(&Cz%pFXhCy8@wY&f_|IEdYISXY zs_OiPx21~%K34pDmHs_-*X_6Y^X>Ln?zvs}piyha3Xh$slR139POto9Gx1W-ucC}& zpG#7X9Wa)dQ~ty$sAKgdJ*HH*MG`q#tCmcBExEyRTXdc6n{1J_d$w3{GV6~N9Rjc9Z_v$zK8P_#0H@Ovj<-xJG-sMd_2kkaDs@AvgEV_NIZo;uZ zzk1K$&5}NvA8l^kQa#tez0JRIxkUUw_uSu3$A$f$Uq1fd!pz4{Y-6UY_SWi|&()=) zg4nM;IvN(9E*v&tVeSGZ;SOc})P-FxADHx4NX|MS>GEOIJ+lgr4{A=6gXWc`oYZk| z`F(A6wYH$LrlEyJ?4B1NHf&4|68ioqcY!6R&jSY~h4m-Hmt{{f39V>i%>DOu%?yq; z4WjJq+CCGRg_Q+Qv7J9+x9g`?{huqRWu~_m-)p(-@o~Xti+H#B6N{hD{rKU;;pv|% zY-&X>mn7%&+sQ{rU+jE*6VBKFfm7MsgPCD}-+X<$}tIKtV&M)$~(X1 zr)$J6J^N@ee_#3Qx(h)w4=LJP{yX{q%ZG0N&(=|O4gccOmk1Rw@?Eb#@MGGPhwm%a z{M-I;cKD@+htd7#5AYQ{;Pq>_-zR_jd71XdCbKWAABwe=99){SN$!x6(>CAj{Qqa~ z`Txdf&-8n?KJV*$+B>m5)^d zF1$9jy=@hI=GE-?8~cNw%J`VDetUWMVt(B_|80uVUd|m2lWr*?r$r1dD)ejY(`y^e;?i__pYl+Vw%DhF(aJ~r5*8`xfsq%7=~ zG`5$v&1Th`aNwB1=UKcD!&xv@hCScs4|0TjZStrF&I3 z>xKDSGIc*_JuEts#$6=QxKWQ!pfT-}(4N8`5r(Cu%!R#^CX`ytml0}MTNmCf_+pdF z4y!$!M-sf-#23ew3s0Mr{`*#6%X-gCObQ43 zP87uN|M_WE(#)pv=LvhS9Z>50y=?2@nn%79ws#!KIjKLD{ju?F-oV(LXL}7V#jayl z*X+G;?&sUcd3NS0OH!p*9Ar23EVvMv)tPu^%X~h0{>yh&s=M}N);(0TJNGH{3HR-V z`GRG;4*b%~V-!qjnYJ}+D#zw#ro+M) zSQ%AXxi*}cYhj`+)9fhRF@dXOrmF1q2ZFpV2Tw>ag$9TnexiD|*FgW|1M}&4W6&%MWiCiH_O3@ce;)@6YNzG`~JK|KE&tA3M$m9GksyPx&rS(lfZPSE}S{@AH!PMK%oLJG2i zHf;#oAi(=DCCv7$Pl}0UUVspf;_U*rgyOnv|NL3!Za%!ia^~dJuRrzw{W|-$KJNA$ z{hfIZ(OQ?cz4HA0FJUsLUfEeXf)4#maul+Co{!N_d<$Gt8?998078HQHsmeNWK880bF7ChnHr=r2oxsc26gz(Z_8>ww9^Cw7~ zF)~CurX7*Xx$*AB-tUk9d~E;tRC<=&VwGIgOo=o_XQk#Bj8o#?xw$CJSiRIKuF*+S zh9fFpWKHAroj)3QA2|Gw`YGeR$gfeb#*;_qb%OoPtDjCiouuM3q8xrn9eJ(F{*LI&2Eq>h+}8v=;%pp=&6jJPHctpsaKOZ9CfC@A7HVJ&i8qe}cU14|#brd*Jl-P4_&dQITOW4lGO;reCjx>*SG~LGb-9#ci+uZAX?Mdg7hQ7>5soiHDf3V^8 zyB+!I=!wW=50m_w`pU`7E|=NTowF{@I3NAnW`|bt`}Nz)?Ps6r7OVEveB0Li@9e+N z^^dkaJyJPKNhxU6wC4=x&gyq?M>R85yGb?l&%3?+|J7yxj3Yk3J?*iW?V#pW-Pyl< zKJU5CC^bX!n!ydJ%T9gQ9iW$Sgah zxpLR!Dap+o{S0@$o3cMRLem^BuV4>(1rrT?*_qI;p5<1wXx@=iN z+w?a*3{BT-au`lP8*ib1X{gwRXo> zKQ4TId7J6NDSw=@{HDuHy&S{ikR3SF{m~H_X4_3t_I6#tZ=P9BaxdMI6Q^cqxJcRE z?{?&*_Ot}!>@tp3Z0b+*)5xYygIO5reR@6 zm&@zV>WqeOX7w7Usx&Z17%B2BXP@j%7vvXS|ZVF{$GA-iX}!(Mq#y(hfb-TL*{`=N^@SvwAsvH z^+}OJwQ`^5zI(m5o+{D2tRb#?D@|Id#Qy5t*Ye_Axeq?(?h@ErePaI)A9?L$W z*{(E0P0Q5cWT!^&E7L`$Er)rQWU!gLbPk4;o(YdNNz8YcZ3lfl->1 zvIw)b(Astb>9R(}4c}jWJ1V~0|JApv2KPfUpGO_v<$dstp5WrhiWP3NI`3_L>%aW$ z`SZDZjPnX|&J>*gY4<+<{*ucRCi*6*KR&rnQ^c|<(K{odHS9r;!WmSMEO~9O1~wctb}b$B%d28sJE1vMrR&LyG-7 zr!XFzVkkBH$;k^AMND&+UtpJ0cevsA*Xj04rq{dIBv=YHa=tNeWq76FEFqIUlk0QV z-99#{gN-{FM4x;}Jzo|1;$T%#GON}OrUO!cZY?loXi;8Qw8~J4@jz;vj>H9)cLnYr zU%%h4=Cgq9OahPWJ^O9`dH4Q({r0I%*?sCn`xa*9pjk_K-c?(_XE19%JN2o~?Bh4) zR;)1PozQI`^W?MsvF(rd|2i7V@b_H4*G|8o-n1?Ew>#Uv-Y`MU zP^{O;tr`wEYeGcA_X;zqax`(MakMguWr!Y|z*dyNBIv~^ zJR^N!GM9=YqsBprIbrL&kKVJ@t+kE+RW8UPEWzC5;d=L)*IGrk1A?48)_v72pCGfK zWz&?cOkS_09&ftsvFV=zgW!c0i32Q|uLFH0JHt2Ea403O{4LaICh+^1Oz8#{$AX6r zI_nv~eR}=V(|Y&h;KgP;Cs!wh9%Qj=)>~=%x!0(jRkifY&y9sSN@WkFb}fm#-!k>c zE*J0PZ?0NMTsfC}ulTIz)s2ZE`(uhiomSuY&YioQd(C@+YzNm}_wr^oO7;en&Mk{) zGZD9zn7?3OUW9p*mfn_sN4p(lZ-%e`wp3BUSI5(^YY+MKB`yo+ygMJ}FP3||D9v}hL&Kp0d+owo5rS0}?r$3>>Qz+b zoM*_$Ieccq^RwD(^(UXxpLY4(v;V6uf4{x2cK=WBudg;dy*^X@@9r`g-UV^-H@@9E z_~+Qge|yBX&y%fRWEQdeWT*Or7plfe2U*>3`rW8@&Y0(U?9a=eJ5J{Btoe9#+PiJ` zKRwG7bU9VaL$Z!6<6@YgX5ucpXNSk+CwztX!f(yulKLQa7p}Vn7R7Z zjOn zAG=RKy<1Z?qnv&B&BWr>hwm&Cw_xwh+w)3J^FicGzCR5U6A$cEYG@DtuX;3I@qR+` zxp#)bvwpfNADt0>I^_YE)JD~Uxa}9jg0(kZotG)(!}??b)5!_C%MLUrGkF|nbTja4 z|M12^72yK zB;h9whH7r6Cs^_t7PDm~98{9j& z_hQ%{3sufA2bIhh4P5-&uQfTZnZdWu_#g}4vjAT^TVHYWNdak_p+hwKZ!CFECAe}M zTr=ip5zGFsA(XQ6AormMyPiEPa0{|n{Pe3$q^LBLdcr=wqEv$iq7n|9Zn;S}A1md1 zcxd(c-6=bqWPK)-^lq9l;pwj8vn$$W+V42dA17y5kkHMWVn0X}zoSJeIba9D!nYulqzGxi>ftFq#k{O89Vzg_?Q+1!}aYeAf=!*_1eQTMyvu>a|i z=zY!8?&q&O{8noNhekup)cXtu1&ng_Z+pJJI(>fG#MdT!tK#O(uiX4_!`JuoZXZ7z zKfyNR#e`F_|4eMFzkl=pf8>kl-%n?CkFIyy;t-G_lEBBcg^}f8?cv5r43XXM7xx(+ zV9UAgyUAvM=Ivp%6`z4E&sNXZbf;`&r5yp+k#cD{;ZxO?G5_oRg6F}uyYPW>z8YP52#Ebs(u3|sC&zO$ zrXStJq_V(CzAf{1O@|{pm+MLnjr4MUHvd&VsmsrFo<3UKZFxpPQ{)4iw!)zW9PS23 z7#Z1p1eroL8qKpe+?#fR$z<)bMax#S8AvQl&0(HtXmLgIq<@dmdbjr@jtO*!OXpeSl_>o&Sd3NfBziO&SHu zZtS{}qRO)IjnM0;`(bV(3mj$7y-tw~aFCi7aiC#|sm5)FvD^td(2O z2#N6(^xn`5jL}_uVHaBmuR-IrgDqDh5;NzxJ4K1jdtRy(H*LOZ0-JPB=OP{lhdpIl z$txRQCaLZ^=EU5=6Lugt#o^#Y@%dFO6+6Cu+jw_kP1c0iJ-;o_za>%MnK zF7y7JJ;krcGRU`1c&2=*jf>qx{&$N?l*Idl_HoY&-sQkwQ6sdpah76wUC&?FczZ5! z=iV#1QdWDLzRrD=U3fx5W%c?^%r^8)S?Le6{&%&I

    EiC+z%mO1@WL+SqNkJ8$m) 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 literal 0 HcmV?d00001 diff --git a/projects/VS2022/examples/shaders_color_correction.vcxproj b/projects/VS2022/examples/shaders_color_correction.vcxproj new file mode 100644 index 000000000..520c041cb --- /dev/null +++ b/projects/VS2022/examples/shaders_color_correction.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 + + + + {98152EDD-7E28-4FA3-89D8-B636ED5D5F65} + Win32Proj + shaders_color_correction + 10.0 + shaders_color_correction + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 81f700bec..44ef64c34 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -397,6 +397,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_mandelbrot_set", "e 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -4923,6 +4925,30 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5123,6 +5149,7 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From 40594f3ec09ac1c045c112422ee4315371d99015 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 26 Oct 2025 10:24:56 -0700 Subject: [PATCH 019/189] Fix typo in font loading documentation (#5308) --- examples/text/text_font_loading.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/text/text_font_loading.c b/examples/text/text_font_loading.c index f1582348b..151b63d45 100644 --- a/examples/text/text_font_loading.c +++ b/examples/text/text_font_loading.c @@ -9,7 +9,7 @@ * - TTF/OTF > Sprite font atlas is generated on loading, user can configure * some of the generation parameters (size, characters to include) * - BMFonts > Angel code font fileformat, sprite font image must be provided -* together with the .fnt file, font generation cna not be configured +* together with the .fnt file, font generation can not be configured * - XNA Spritefont > Sprite font image, following XNA Spritefont conventions, * Characters in image must follow some spacing and order rules * From 6a5b7fb3f8a7e718c91a66aa66ee2f038cb0dba6 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 18:40:46 +0100 Subject: [PATCH 020/189] Update models_decals.c --- examples/models/models_decals.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index 6fa2bd75b..d445e69cd 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -46,7 +46,7 @@ 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) -static bool Button(Rectangle rec, char *label); +static bool GuiButton(Rectangle rec, const char *label); //------------------------------------------------------------------------------------ // Program main entry point @@ -248,14 +248,12 @@ int main(void) 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); - Rectangle rect = (Rectangle){ 10, screenHeight - 100, 100, 60 }; + // UI elements + if (GuiButton((Rectangle){ 10, screenHeight - 100, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; - if (Button(rect, showModel ? "Hide Model" : "Show Model")) showModel = !showModel; - - rect.x += rect.width + 10; - - if (Button(rect, "Clear Decals")) + if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100, 100, 60 }, "Clear Decals")) { + // Clear decals, unload all decal models for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]); decalCount = 0; } @@ -362,14 +360,14 @@ static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s) } // Generate mesh decals for provided model -static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset) +static Mesh GenMeshDecal(Model target, Matrix projection, float decalSize, float decalOffset) { // We're going to use these to build up our decal meshes // They'll resize automatically as we go, we'll free them at the end static MeshBuilder meshBuilders[2] = { 0 }; // Ugly way of telling us to free the static MeshBuilder data - if (inputModel.meshCount == -1) + if (target.meshCount == -1) { FreeMeshBuilder(&meshBuilders[0]); FreeMeshBuilder(&meshBuilders[1]); @@ -388,9 +386,9 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f int mbIndex = 0; // First pass, just get any triangle inside the bounding box (for each mesh of the model) - for (int meshIndex = 0; meshIndex < inputModel.meshCount; meshIndex++) + for (int meshIndex = 0; meshIndex < target.meshCount; meshIndex++) { - Mesh mesh = inputModel.meshes[meshIndex]; + Mesh mesh = target.meshes[meshIndex]; for (int tri = 0; tri < mesh.triangleCount; tri++) { Vector3 vertices[3] = { 0 }; @@ -584,7 +582,7 @@ static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, f } // Button UI element -static bool Button(Rectangle rec, const char *label) +static bool GuiButton(Rectangle rec, const char *label) { Color bgColor = GRAY; bool pressed = false; From a6dd08fb71f31be5e68a5fd3ab3f729c51f7a208 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 20:10:47 +0100 Subject: [PATCH 021/189] Update shaders_color_correction.c --- examples/shaders/shaders_color_correction.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/shaders/shaders_color_correction.c b/examples/shaders/shaders_color_correction.c index 8aee1d0e4..c96f606d8 100644 --- a/examples/shaders/shaders_color_correction.c +++ b/examples/shaders/shaders_color_correction.c @@ -29,7 +29,7 @@ #define GLSL_VERSION 100 #endif -#define NUMBER_TEXTURES 4 +#define MAX_TEXTURES 4 //------------------------------------------------------------------------------------ // Program main entry point @@ -43,7 +43,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic color correction"); - Texture2D texture[NUMBER_TEXTURES] = { + Texture2D texture[MAX_TEXTURES] = { LoadTexture("resources/parrots.png"), LoadTexture("resources/cat.png"), LoadTexture("resources/mandrill.png"), @@ -53,7 +53,6 @@ int main(void) Shader shdrColorCorrection = LoadShader(0, TextFormat("resources/shaders/glsl%i/color_correction.fs", GLSL_VERSION)); int imageIndex = 0; - int resetButtonClicked = 0; float contrast = 0.0f; @@ -113,8 +112,8 @@ int main(void) DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 }); DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 }); - // Draw some text - DrawText("Basic Color Correction", 585, 40, 19, GRAY); + // Draw UI info text + DrawText("Color Correction", 585, 40, 20, GRAY); DrawText("Picture", 602, 75, 10, GRAY); DrawText("Press [1] - [4] to Change Picture", 600, 230, 8, GRAY); @@ -129,6 +128,7 @@ int main(void) GuiSliderBar((Rectangle){ 645, 160, 120, 20 }, "Brightness", TextFormat("%.0f", brightness), &brightness, -100.0f, 100.0f); resetButtonClicked = GuiButton((Rectangle){ 645, 190, 40, 20 }, "Reset"); + //------------------------------------------------------------------------------ DrawFPS(710, 10); @@ -138,8 +138,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - for (int i = 0; i < NUMBER_TEXTURES; ++i) - UnloadTexture(texture[i]); + for (int i = 0; i < MAX_TEXTURES; ++i) UnloadTexture(texture[i]); UnloadShader(shdrColorCorrection); CloseWindow(); // Close window and OpenGL context From cf9a0619ca5c6bf97fc6d8a1c9d3dc63618b0ad0 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 21:21:05 +0100 Subject: [PATCH 022/189] REXM: Validate and update examples --- examples/Makefile | 3 + examples/Makefile.Web | 23 +- examples/README.md | 14 +- examples/examples_list.txt | 3 + examples/models/models_decals.c | 2 +- examples/shaders/shaders_color_correction.c | 6 +- examples/shaders/shaders_palette_switch.c | 4 +- examples/shapes/shapes_lines_drawing.c | 2 +- examples/shapes/shapes_math_angle_rotation.c | 11 +- examples/shapes/shapes_math_sine_cosine.c | 4 +- .../VS2022/examples/models_decals.vcxproj | 569 ++++++++++++++++++ .../examples/shapes_lines_drawing.vcxproj | 569 ++++++++++++++++++ .../examples/shapes_math_sine_cosine.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 85 ++- tools/rexm/examples_report.md | 11 +- tools/rexm/examples_report_issues.md | 2 +- 16 files changed, 1849 insertions(+), 28 deletions(-) create mode 100644 projects/VS2022/examples/models_decals.vcxproj create mode 100644 projects/VS2022/examples/shapes_lines_drawing.vcxproj create mode 100644 projects/VS2022/examples/shapes_math_sine_cosine.vcxproj diff --git a/examples/Makefile b/examples/Makefile index c601c72b2..c8500b665 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -562,8 +562,10 @@ SHAPES = \ shapes/shapes_following_eyes \ shapes/shapes_kaleidoscope \ shapes/shapes_lines_bezier \ + shapes/shapes_lines_drawing \ shapes/shapes_logo_raylib \ shapes/shapes_logo_raylib_anim \ + shapes/shapes_math_angle_rotation \ shapes/shapes_math_sine_cosine \ shapes/shapes_mouse_trail \ shapes/shapes_pie_chart \ @@ -632,6 +634,7 @@ MODELS = \ models/models_bone_socket \ models/models_box_collisions \ models/models_cubicmap_rendering \ + models/models_decals \ models/models_first_person_maze \ models/models_geometric_shapes \ models/models_heightmap_rendering \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 99be781ac..07f8d8fb8 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -562,8 +562,10 @@ SHAPES = \ shapes/shapes_following_eyes \ shapes/shapes_kaleidoscope \ shapes/shapes_lines_bezier \ + shapes/shapes_lines_drawing \ shapes/shapes_logo_raylib \ shapes/shapes_logo_raylib_anim \ + shapes/shapes_math_angle_rotation \ shapes/shapes_math_sine_cosine \ shapes/shapes_mouse_trail \ shapes/shapes_pie_chart \ @@ -632,6 +634,7 @@ MODELS = \ models/models_bone_socket \ models/models_box_collisions \ models/models_cubicmap_rendering \ + models/models_decals \ models/models_first_person_maze \ models/models_geometric_shapes \ models/models_heightmap_rendering \ @@ -895,12 +898,18 @@ shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_lines_drawing: shapes/shapes_lines_drawing.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_math_angle_rotation: shapes/shapes_math_angle_rotation.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -1157,6 +1166,12 @@ models/models_cubicmap_rendering: models/models_cubicmap_rendering.c --preload-file models/resources/cubicmap.png@resources/cubicmap.png \ --preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png +models/models_decals: models/models_decals.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file models/resources/models/obj/character.obj@resources/models/obj/character.obj \ + --preload-file models/resources/models/obj/character_diffuse.png@resources/models/obj/character_diffuse.png \ + --preload-file models/resources/raylib_logo.png@resources/raylib_logo.png + models/models_first_person_maze: models/models_first_person_maze.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file models/resources/cubicmap.png@resources/cubicmap.png \ @@ -1262,13 +1277,13 @@ shaders/shaders_basic_pbr: shaders/shaders_basic_pbr.c --preload-file shaders/resources/road_mra.png@resources/road_mra.png \ --preload-file shaders/resources/road_n.png@resources/road_n.png -shapes/shapes_recursive_tree: shaders/shaders_color_correction.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file shaders/resources/shaders/glsl100/color_correction.fs@resources/shaders/glsl100/color_correction.fs \ +shaders/shaders_color_correction: shaders/shaders_color_correction.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file shaders/resources/parrots.png@resources/parrots.png \ --preload-file shaders/resources/cat.png@resources/cat.png \ --preload-file shaders/resources/mandrill.png@resources/mandrill.png \ - --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png + --preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \ + --preload-file shaders/resources/shaders/glsl100/color_correction.fs@resources/shaders/glsl100/color_correction.fs shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ diff --git a/examples/README.md b/examples/README.md index de28c931f..4d0b25d56 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: 188] +## EXAMPLES COLLECTION [TOTAL: 192] ### category: core [45] @@ -71,7 +71,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [core_clipboard_text](core/core_clipboard_text.c) | core_clipboard_text | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | | [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) | -### category: shapes [32] +### category: shapes [34] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. @@ -105,9 +105,12 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [shapes_pie_chart](shapes/shapes_pie_chart.c) | shapes_pie_chart | ⭐⭐⭐☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) | | [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) | shapes_kaleidoscope | ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) | | [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | shapes_clock_of_clocks | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | +| [shapes_math_sine_cosine](shapes/shapes_math_sine_cosine.c) | shapes_math_sine_cosine | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) | | [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | shapes_mouse_trail | ⭐☆☆☆ | 5.6 | 5.6-dev | [Balamurugan R](https://github.com/Bala050814) | | [shapes_simple_particles](shapes/shapes_simple_particles.c) | shapes_simple_particles | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | | [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | shapes_starfield_effect | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | +| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | shapes_lines_drawing | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) | +| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | shapes_math_angle_rotation | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) | ### category: textures [26] @@ -164,7 +167,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat | [text_inline_styling](text/text_inline_styling.c) | text_inline_styling | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) | | [text_words_alignment](text/text_words_alignment.c) | text_words_alignment | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | -### category: models [25] +### category: models [26] Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module. @@ -195,6 +198,7 @@ Examples using raylib models functionality, including models loading/generation | [models_tesseract_view](models/models_tesseract_view.c) | models_tesseract_view | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) | | [models_basic_voxel](models/models_basic_voxel.c) | models_basic_voxel | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) | | [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) | ### category: shaders [32] @@ -214,6 +218,8 @@ Examples using raylib shaders functionality, including shaders loading, paramete | [shaders_texture_outline](shaders/shaders_texture_outline.c) | shaders_texture_outline | ⭐⭐⭐☆ | 4.0 | 4.0 | [Serenity Skiff](https://github.com/GoldenThumbs) | | [shaders_texture_waves](shaders/shaders_texture_waves.c) | shaders_texture_waves | ⭐⭐☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) | | [shaders_julia_set](shaders/shaders_julia_set.c) | shaders_julia_set | ⭐⭐⭐☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) | +| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | shaders_mandelbrot_set | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | +| [shaders_color_correction](shaders/shaders_color_correction.c) | shaders_color_correction | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | | [shaders_eratosthenes_sieve](shaders/shaders_eratosthenes_sieve.c) | shaders_eratosthenes_sieve | ⭐⭐⭐☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) | | [shaders_fog_rendering](shaders/shaders_fog_rendering.c) | shaders_fog_rendering | ⭐⭐⭐☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) | | [shaders_simple_mask](shaders/shaders_simple_mask.c) | shaders_simple_mask | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) | @@ -232,8 +238,6 @@ Examples using raylib shaders functionality, including shaders loading, paramete | [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | shaders_lightmap_rendering | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) | | [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | shaders_rounded_rectangle | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) | | [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | shaders_depth_rendering | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) | -| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | shaders_mandelbrot_set | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | -| [shaders_color_correction](shaders/shaders_color_correction.c) | shaders_color_correction | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) | ### category: audio [8] diff --git a/examples/examples_list.txt b/examples/examples_list.txt index f24cb9905..7c8709785 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -84,6 +84,8 @@ shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe" shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814 shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates +shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary +shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@krispy-snacc 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 @@ -150,6 +152,7 @@ models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle models;models_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 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_decals.c b/examples/models/models_decals.c index d445e69cd..f556139e1 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -4,7 +4,7 @@ * * Example complexity rating: [★★★★] 4/4 * -* Example originally created with raylib 5.6-dev +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev * * Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5) * Based on previous work by @mrdoob diff --git a/examples/shaders/shaders_color_correction.c b/examples/shaders/shaders_color_correction.c index c96f606d8..3abf29840 100644 --- a/examples/shaders/shaders_color_correction.c +++ b/examples/shaders/shaders_color_correction.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [shaders] example - basic color correction +* raylib [shaders] example - color correction * * Example complexity rating: [★★☆☆] 2/4 * @@ -9,7 +9,7 @@ * * Example originally created with raylib 5.6, last time updated with raylib 5.6 * -* Example contributed by Jordi Santonja (@JordSant) +* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software @@ -41,7 +41,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic color correction"); + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - color correction"); Texture2D texture[MAX_TEXTURES] = { LoadTexture("resources/parrots.png"), diff --git a/examples/shaders/shaders_palette_switch.c b/examples/shaders/shaders_palette_switch.c index e23cad1d3..048fe7fbc 100644 --- a/examples/shaders/shaders_palette_switch.c +++ b/examples/shaders/shaders_palette_switch.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [shaders] example - palette switch +* raylib [shaders] example - palette switch * * Example complexity rating: [★★★☆] 3/4 * @@ -11,7 +11,7 @@ * on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders * raylib comes with shaders ready for both versions, check raylib/shaders install folder * -* Example originally created with raylib 2.5, last time updated with raylib 3.7 +* Example originally created with raylib 2.5, last time updated with raylib 3.7 * * Example contributed by Marco Lizza (@MarcoLizza) and reviewed by Ramon Santamaria (@raysan5) * diff --git a/examples/shapes/shapes_lines_drawing.c b/examples/shapes/shapes_lines_drawing.c index 9347acaf3..aeaae3d45 100644 --- a/examples/shapes/shapes_lines_drawing.c +++ b/examples/shapes/shapes_lines_drawing.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) 2025-2025 Robin (@RobinsAviary) +* Copyright (c) 2025 Robin (@RobinsAviary) * ********************************************************************************************/ diff --git a/examples/shapes/shapes_math_angle_rotation.c b/examples/shapes/shapes_math_angle_rotation.c index 0e4802064..f895026f5 100644 --- a/examples/shapes/shapes_math_angle_rotation.c +++ b/examples/shapes/shapes_math_angle_rotation.c @@ -1,14 +1,17 @@ /******************************************************************************************* * -* raylib [shapes] example - Math angle rotation lines +* raylib [shapes] example - math angle rotation * * Example complexity rating: [★☆☆☆] 1/4 * -* Example originally created with raylib 5.5, last time updated with raylib 5.6 +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6 * * Example contributed by Kris (@krispy-snacc) and reviewed by Ramon Santamaria (@raysan5) * -* Example licensed under an unmodified zlib/libpng license +* 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 Kris (@krispy-snacc) * ********************************************************************************************/ @@ -25,7 +28,7 @@ int main(void) const int screenWidth = 720; const int screenHeight = 400; - InitWindow(screenWidth, screenHeight, "raylib [shapes] example - angle rotation lines"); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math angle rotation"); SetTargetFPS(60); Vector2 center = { screenWidth / 2.0f, screenHeight / 2.0f }; diff --git a/examples/shapes/shapes_math_sine_cosine.c b/examples/shapes/shapes_math_sine_cosine.c index f61d4f548..d8d13920e 100644 --- a/examples/shapes/shapes_math_sine_cosine.c +++ b/examples/shapes/shapes_math_sine_cosine.c @@ -6,12 +6,12 @@ * * Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev * -* Example contributed by Jopestpe (@jopestpe) +* Example contributed by Jopestpe (@jopestpe) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2025-2025 Jopestpe (@jopestpe) +* Copyright (c) 2025 Jopestpe (@jopestpe) * ********************************************************************************************/ diff --git a/projects/VS2022/examples/models_decals.vcxproj b/projects/VS2022/examples/models_decals.vcxproj new file mode 100644 index 000000000..a7a5e2f2b --- /dev/null +++ b/projects/VS2022/examples/models_decals.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 + + + + {028F0967-B253-45DA-B1C4-FACCE45D0D8D} + Win32Proj + models_decals + 10.0 + models_decals + + + + 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;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/shapes_lines_drawing.vcxproj b/projects/VS2022/examples/shapes_lines_drawing.vcxproj new file mode 100644 index 000000000..49159676b --- /dev/null +++ b/projects/VS2022/examples/shapes_lines_drawing.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 + + + + {666346D7-C84B-498D-AE17-53B20C62DB1A} + Win32Proj + shapes_lines_drawing + 10.0 + shapes_lines_drawing + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/shapes_math_sine_cosine.vcxproj b/projects/VS2022/examples/shapes_math_sine_cosine.vcxproj new file mode 100644 index 000000000..8b2457b83 --- /dev/null +++ b/projects/VS2022/examples/shapes_math_sine_cosine.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 + + + + {B7FDD40F-DDA4-468E-9C40-EEB175964A26} + Win32Proj + shapes_math_sine_cosine + 10.0 + shapes_math_sine_cosine + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;shcore.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 44ef64c34..c15632182 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -399,6 +399,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_math_angle_rotation" 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -4949,6 +4955,78 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5116,7 +5194,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} @@ -5125,7 +5203,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} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} + {2CCCD9E4-9058-4291-BD89-39C979F0CA1E} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C} {9DB1F875-6E65-4195-B23F-ED8095C0B99C} = {278D8859-20B1-428F-8448-064F46E1F021} {52BA9067-A5FC-4CE8-82AD-7204ECFDEF9F} = {278D8859-20B1-428F-8448-064F46E1F021} {8E132D5A-2C00-48D0-8747-97E41356F26F} = {278D8859-20B1-428F-8448-064F46E1F021} @@ -5150,6 +5228,9 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md index fcc1f8839..68efbe1ef 100644 --- a/tools/rexm/examples_report.md +++ b/tools/rexm/examples_report.md @@ -64,6 +64,7 @@ Example elements validated: | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_screen_recording | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -92,6 +93,7 @@ Example elements validated: | shapes_pie_chart | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_kaleidoscope | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_clock_of_clocks | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_math_sine_cosine | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_mouse_trail | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_simple_particles | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_starfield_effect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -173,6 +175,8 @@ Example elements validated: | shaders_texture_outline | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_texture_waves | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_julia_set | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_mandelbrot_set | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_color_correction | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_eratosthenes_sieve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_fog_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_simple_mask | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -204,6 +208,7 @@ Example elements validated: | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| web_basic_window | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shaders_mandelbrot_set | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_lines_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_math_angle_rotation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/examples_report_issues.md b/tools/rexm/examples_report_issues.md index 5de76a17a..8d24a251d 100644 --- a/tools/rexm/examples_report_issues.md +++ b/tools/rexm/examples_report_issues.md @@ -27,4 +27,4 @@ Example elements validated: | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| web_basic_window | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From fdc500756dad1f404356a2841b3e1cd8a14871ce Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 21:21:28 +0100 Subject: [PATCH 023/189] REXM: ADDED: More detailed log info --- tools/rexm/rexm.c | 95 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index d668655c8..41fb0cae6 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -464,12 +464,14 @@ int main(int argc, char *argv[]) // Create: raylib/examples//_example_name.png if (FileExists(TextFormat("%s/%s.png", GetDirectoryPath(inFileName), exName))) { + LOG("INFO: [%s] Copying file screenshot...\n", GetFileName(inFileName)); FileCopy(TextFormat("%s/%s.png", GetDirectoryPath(inFileName), exName), TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName)); } else // No screenshot available next to source file { // Copy screenshot template + LOG("WARNING: [%s] No screenshot found, using placeholder screenshot\n", GetFileName(inFileName)); FileCopy(exTemplateScreenshot, TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName)); } @@ -478,10 +480,13 @@ int main(int argc, char *argv[]) // Scan resources used in example to copy // NOTE: resources path will be relative to example source file directory int resPathCount = 0; + LOG("INFO: [%s] Scanning file for resources...\n", GetFileName(inFileName)); char **resPaths = ScanExampleResources(TextFormat("%s/%s.c", GetDirectoryPath(inFileName), exName), &resPathCount); if (resPathCount > 0) { + LOG("INFO: [%s] Required resources found: %i\n", GetFileName(inFileName), resPathCount); + for (int r = 0; r < resPathCount; r++) { // WARNING: Special case to consider: shaders, resource paths could use conditions: "glsl%i" @@ -494,7 +499,7 @@ int main(int argc, char *argv[]) { char *resPathUpdated = TextReplace(resPaths[r], "glsl%i", TextFormat("glsl%i", glslVer[v])); - LOG("INFO: Example resource required: %s\n", resPathUpdated); + LOG("INFO: [%s] Resource required [%i/%i]: %s\n", GetFileName(inFileName), r, resPathCount, resPathUpdated); if (FileExists(TextFormat("%s/%s", GetDirectoryPath(inFileName), resPathUpdated))) { @@ -515,7 +520,7 @@ int main(int argc, char *argv[]) } else { - LOG("INFO: Example resource required: %s\n", resPaths[r]); + LOG("INFO: [%s] Resource required [%i/%i]: %s\n", GetFileName(inFileName), r, resPathCount, resPaths[r]); if (FileExists(TextFormat("%s/%s", GetDirectoryPath(inFileName), resPaths[r]))) { @@ -543,6 +548,8 @@ int main(int argc, char *argv[]) char *exCollectionList = LoadFileText(exCollectionFilePath); if (TextFindIndex(exCollectionList, exName) == -1) // Example not found { + LOG("INFO: [%s] Adding example to collection list (%s)\n", GetFileName(inFileName), exCategory); + char *exCollectionListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated list copy, 2MB // Add example to the main list, by category @@ -560,9 +567,15 @@ int main(int argc, char *argv[]) // Get required example info from example file header (if provided) - // NOTE: If no example info is provided (other than category/name), just using some default values + // NOTE: Load example info from provided example header rlExampleInfo *exInfo = LoadExampleInfo(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + LOG("INFO: [%s] Example info: \n", GetFileName(inFileName)); + LOG(" > Author: %s (@%s)\n", exInfo->author, exInfo->authorGitHub); + LOG(" > Stars: %i\n", exInfo->stars); + LOG(" > Version-Update: %s-%s\n", exInfo->verCreated, exInfo->verUpdated); + LOG(" > Created-Reviewed: %i-%i\n", exInfo->yearCreated, exInfo->yearReviewed); + // Get example difficulty stars text char starsText[16] = { 0 }; for (int i = 0; i < 4; i++) @@ -599,13 +612,14 @@ int main(int argc, char *argv[]) UnloadFileText(exCollectionList); //------------------------------------------------------------------------------------------------ - // Update: Makefile, Makefile.Web, README.md, examples.js + // Update: Metadata, Makefile, Makefile.Web, README.md, examples.js //------------------------------------------------------------------------------------------------ UpdateRequiredFiles(); //------------------------------------------------------------------------------------------------ // Create: raylib/projects/VS2022/examples/_example_name.vcxproj //------------------------------------------------------------------------------------------------ + LOG("INFO: [%s] Creating example project\n", TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName)); // WARNING: When adding new project a unique UUID should be assigned! FileCopy(TextFormat("%s/../projects/VS2022/examples/core_basic_window.vcxproj", exBasePath), TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName)); @@ -619,6 +633,7 @@ 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)); AddVSProjectToSolution(exVSProjectSolutionFile, TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName), exCategory); //------------------------------------------------------------------------------------------------ @@ -633,17 +648,21 @@ int main(int argc, char *argv[]) // WARNING 1: EMSDK_PATH must be set to proper location when calling from GitHub Actions // WARNING 2: raylib.a and raylib.web.a must be available when compiling locally #if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", GetFileNameWithoutExt(inFileName)); //putenv("RAYLIB_DIR=C:\\GitHub\\raylib"); - putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); #else + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", GetFileNameWithoutExt(inFileName)); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); #endif // Update generated .html metadata + LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName)); UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); // Copy results to web side + LOG("INFO: [%s] Copy example build to raylib.com\n", exName); FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName)); FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exCategory, exName), @@ -732,7 +751,7 @@ int main(int argc, char *argv[]) // Recompile example (on raylib side) // WARNING: EMSDK_PATH must be set to proper location when calling from GitHub Actions #if defined(_WIN32) - putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename)); #else system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename)); @@ -776,6 +795,7 @@ int main(int argc, char *argv[]) // Remove example from collection for files update //------------------------------------------------------------------------------------------------ + LOG("INFO: [%s] Removing example from collection\n", exName); char *exCollectionList = LoadFileText(exCollectionFilePath); int exIndex = TextFindIndex(exCollectionList, TextFormat("%s;%s", exCategory, exName)); if (exIndex > 0) // Example found @@ -831,22 +851,33 @@ int main(int argc, char *argv[]) // Remove: raylib/examples//_example_name.c // Remove: raylib/examples//_example_name.png + LOG("INFO: [%s] Removing example code file\n", TextFormat("%s.c", exName)); FileRemove(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + LOG("INFO: [%s] Removing example screenshot file\n", TextFormat("%s.png", exName)); FileRemove(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName)); // Edit: Update required files: Makefile, Makefile.Web, README.md, examples.js UpdateRequiredFiles(); // Remove: raylib/projects/VS2022/examples/_example_name.vcxproj + LOG("INFO: [%s] Removing example project file\n", TextFormat("%s.vcxproj", exName)); FileRemove(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName)); // Edit: raylib/projects/VS2022/raylib.sln --> Remove example project + LOG("INFO: [%s] Removing example from raylib solution (.sln)\n", exName); RemoveVSProjectFromSolution(TextFormat("%s/../projects/VS2022/raylib.sln", exBasePath), exName); + // Remove: Delete example build from local copy (if exists) + FileRemove(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName)); + FileRemove(TextFormat("%s/%s/%s.data", exBasePath, exCategory, exName)); + FileRemove(TextFormat("%s/%s/%s.wasm", exBasePath, exCategory, exName)); + FileRemove(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName)); + // Remove: raylib.com/examples//_example_name.html // Remove: raylib.com/examples//_example_name.data // Remove: raylib.com/examples//_example_name.wasm // Remove: raylib.com/examples//_example_name.js + LOG("INFO: [%s] Deleting example from raylib.com\n", exName); FileRemove(TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName)); FileRemove(TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName)); FileRemove(TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName)); @@ -868,11 +899,10 @@ int main(int argc, char *argv[]) // Build: raylib.com/examples//_example_name.data // Build: raylib.com/examples//_example_name.wasm // Build: raylib.com/examples//_example_name.js - #if defined(_WIN32) // Set required environment variables //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); - putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); //putenv("MAKE=mingw32-make"); //ChangeDirectory(exBasePath); #endif @@ -880,22 +910,28 @@ int main(int argc, char *argv[]) { // Build example for PLATFORM_DESKTOP #if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); #else + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); #endif // Build example for PLATFORM_WEB #if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); #else + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); #endif // Update generated .html metadata + LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exRebuildList[i].name)), UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name), TextFormat("%s/%s/%s.c", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); // Copy results to web side + LOG("INFO: [%s] Copy example build to raylib.com\n", exRebuildList[i].name), FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name), TextFormat("%s/%s/%s.html", exWebPath, exRebuildList[i].category, exRebuildList[i].name)); FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exRebuildList[i].category, exRebuildList[i].name), @@ -933,10 +969,9 @@ int main(int argc, char *argv[]) VALID_INVALID_CATEGORY */ - // TODO: Log more details about the validation process - // 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"); FilePathList clist = LoadDirectoryFilesEx(exBasePath, ".c", true); char *exList = LoadFileText(exCollectionFilePath); @@ -1007,6 +1042,7 @@ int main(int argc, char *argv[]) UnloadDirectoryFiles(clist); // Check all examples in collection [examples_list.txt] -> Source of truth! + LOG("INFO: Validating examples in collection...\n"); int exCollectionCount = 0; rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, "ALL", false, &exCollectionCount); @@ -1016,6 +1052,8 @@ int main(int argc, char *argv[]) rlExampleInfo *exInfo = &exCollection[i]; exInfo->status = 0; + LOG("INFO: [%s] Validating example...\n", exInfo->name); + // Validate: raylib/examples//_example_name.c -> File exists? if (!FileExists(TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name))) exInfo->status |= VALID_MISSING_C; @@ -1138,11 +1176,16 @@ int main(int argc, char *argv[]) exInfo->status |= VALID_INCONSISTENT_INFO; } + if (exInfo->status == 0) LOG("INFO: [%s] Validation result: OK", exInfo->name); + else LOG("WARNING: [%s] Validation result: ISSUES FOUND", exInfo->name); + UnloadExampleInfo(exInfoHeader); } if (opCode == OP_UPDATE) { + LOG("INFO: Updating examples with issues in collection...\n"); + // Actions to fix/review anything possible from validation results //------------------------------------------------------------------------------------------------ // Check examples "status" information @@ -1162,16 +1205,16 @@ int main(int argc, char *argv[]) // NOTE: Some examples should be excluded from VS2022 solution because // they have specific platform/linkage requirements: - if ((strcmp(exInfo->name, "core_basic_window_web") == 0) || - (strcmp(exInfo->name, "core_input_gestures_web") == 0) || - (strcmp(exInfo->name, "raylib_opengl_interop") == 0) || - (strcmp(exInfo->name, "raymath_vector_angle") == 0)) continue; + if ((strcmp(exInfo->name, "web_basic_window") == 0) || + (strcmp(exInfo->name, "raylib_opengl_interop") == 0)) continue; // Review: Add: raylib/projects/VS2022/examples/_example_name.vcxproj // Review: Add: raylib/projects/VS2022/raylib.sln // Solves: VALID_MISSING_VCXPROJ, VALID_NOT_IN_VCXSOL if (exInfo->status & VALID_MISSING_VCXPROJ) { + LOG("WARNING: [%s] Missing VS2022 project file\n", exInfo->name); + LOG("INFO: [%s.vcxproj] Creating VS2022 project file\n", exInfo->name); FileCopy(TextFormat("%s/../projects/VS2022/examples/core_basic_window.vcxproj", exBasePath), TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name)); FileTextReplace(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name), @@ -1185,6 +1228,8 @@ int main(int argc, char *argv[]) // Add project (.vcxproj) to raylib solution (.sln) if (exInfo->status & VALID_NOT_IN_VCXSOL) { + LOG("WARNING: [%s.vcxproj] Project not included in raylib solution (.sln)\n", exInfo->name); + LOG("INFO: [%s.vcxproj] Adding project to raylib solution (.sln)\n", exInfo->name); AddVSProjectToSolution(exVSProjectSolutionFile, TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name), exInfo->category); @@ -1199,19 +1244,25 @@ int main(int argc, char *argv[]) if ((strcmp(exInfo->category, "others") != 0) && // Skipping "others" category ((exInfo->status & VALID_MISSING_WEB_OUTPUT) || (exInfo->status & VALID_MISSING_WEB_METADATA))) { + LOG("WARNING: [%s] Example not available on raylib web\n", exInfo->name); + // Build example for PLATFORM_WEB #if defined(_WIN32) - putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exInfo->name); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name)); #else + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->name); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name)); #endif // Update generated .html metadata + LOG("INFO: [%s.html] Updating HTML Metadata...\n", exInfo->name); UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exInfo->category, exInfo->name), TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name)); // Copy results to web side + LOG("INFO: [%s] Copy example build to raylib.com\n", exInfo->name); FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exInfo->category, exInfo->name), TextFormat("%s/%s/%s.html", exWebPath, exInfo->category, exInfo->name)); FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exInfo->category, exInfo->name), @@ -1228,6 +1279,8 @@ int main(int argc, char *argv[]) if (exInfo->status & VALID_INCONSISTENT_INFO) { // Update source code header info + LOG("WARNING: [%s.c] Inconsistent source code metadata\n", exInfo->name); + LOG("INFO: [%s.c] Updating source code metadata...\n", exInfo->name); UpdateSourceMetadata(TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name), exInfo); exInfo->status &= ~VALID_INCONSISTENT_INFO; @@ -1273,6 +1326,7 @@ int main(int argc, char *argv[]) | shapes_colors_palette | ✘ | ✔ | ✘ | ✔ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_format_text | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ | */ + LOG("INFO: [examples_report.md] Generating examples validation report...\n"); char *report = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); @@ -1324,6 +1378,8 @@ int main(int argc, char *argv[]) // Generate a report with only the examples missing some elements //----------------------------------------------------------------------------------------------------- + LOG("INFO: [examples_report_issues.md] Generating examples issues report...\n"); + char *reportIssues = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); repIndex = 0; @@ -1437,6 +1493,7 @@ static int UpdateRequiredFiles(void) // Edit: Example source code metadata for consistency //------------------------------------------------------------------------------------------------ + LOG("INFO: Updating all examples metadata...\n"); int exListCount = 0; rlExampleInfo *exList = LoadExamplesData(exCollectionFilePath, "ALL", true, &exListCount); for (int i = 0; i < exListCount; i++) @@ -1449,6 +1506,7 @@ static int UpdateRequiredFiles(void) // Edit: raylib/examples/Makefile --> Update from collection //------------------------------------------------------------------------------------------------ + LOG("INFO: Updating raylib/examples/Makefile\n"); char *mkText = LoadFileText(TextFormat("%s/Makefile", exBasePath)); char *mkTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated Makefile copy, 2MB @@ -1484,6 +1542,7 @@ 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)); char *mkwTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated Makefile copy, 2MB @@ -1602,6 +1661,7 @@ static int UpdateRequiredFiles(void) // Edit: raylib/examples/README.md --> Update from collection //------------------------------------------------------------------------------------------------ + LOG("INFO: Updating raylib/examples/README.md\n"); // NOTE: Using [examples_list.txt] to update/regen README.md // Lines format: | 01 | [core_basic_window](core/core_basic_window.c) | core_basic_window | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | char *mdText = LoadFileText(TextFormat("%s/README.md", exBasePath)); @@ -1710,6 +1770,7 @@ static int UpdateRequiredFiles(void) // Edit: raylib.com/common/examples.js --> Update from collection // NOTE: Entries format: exampleEntry('⭐️☆☆☆' , 'core' , 'basic_window'), //------------------------------------------------------------------------------------------------ + LOG("INFO: Updating raylib.com/common/examples.js\n"); char *jsText = LoadFileText(TextFormat("%s/../common/examples.js", exWebPath)); if (!jsText) { @@ -2233,7 +2294,7 @@ static int RemoveVSProjectFromSolution(const char *slnFile, const char *exName) char uuid[38] = { 0 }; strcpy(uuid, "ABCDEF00-0123-4567-89AB-000000000012"); // Temp value int textUpdatedOfsset = 0; - int exNameLen = strlen(exName); + int exNameLen = (int)strlen(exName); for (int i = 0, index = 0; i < lineCount; i++) { @@ -2304,7 +2365,7 @@ static void UpdateSourceMetadata(const char *exSrcPath, const rlExampleInfo *inf char exNameFormated[256] = { 0 }; // Example name without category and using spaces int exNameIndex = TextFindIndex(info->name, "_"); strcpy(exNameFormated, info->name + exNameIndex + 1); - int exNameLen = strlen(exNameFormated); + int exNameLen = (int)strlen(exNameFormated); for (int i = 0; i < exNameLen; i++) { if (exNameFormated[i] == '_') exNameFormated[i] = ' '; } // Update example header title (line #3 - ALWAYS) From a0f3f07bdc01ae3a548428883fbb9a93ad28dc25 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 21:23:08 +0100 Subject: [PATCH 024/189] Update examples_report.md --- tools/rexm/examples_report.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md index 68efbe1ef..7734a234c 100644 --- a/tools/rexm/examples_report.md +++ b/tools/rexm/examples_report.md @@ -97,6 +97,8 @@ Example elements validated: | shapes_mouse_trail | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_simple_particles | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_starfield_effect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_lines_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_math_angle_rotation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -163,6 +165,7 @@ Example elements validated: | models_tesseract_view | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_basic_voxel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_rotating_cube | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_ascii_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -209,6 +212,3 @@ Example elements validated: | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | web_basic_window | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_lines_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_math_angle_rotation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 5338e3912463d31053c69bf6fb78852cff8ade3f Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 21:23:11 +0100 Subject: [PATCH 025/189] 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 41fb0cae6..98134ee96 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1176,8 +1176,8 @@ int main(int argc, char *argv[]) exInfo->status |= VALID_INCONSISTENT_INFO; } - if (exInfo->status == 0) LOG("INFO: [%s] Validation result: OK", exInfo->name); - else LOG("WARNING: [%s] Validation result: ISSUES FOUND", exInfo->name); + if (exInfo->status == 0) LOG("INFO: [%s] Validation result: OK\n", exInfo->name); + else LOG("WARNING: [%s] Validation result: ISSUES FOUND\n", exInfo->name); UnloadExampleInfo(exInfoHeader); } From aae2c4b355099968e3d8aa50a2335a5764c33b72 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Oct 2025 21:25:25 +0100 Subject: [PATCH 026/189] Update rexm.c --- tools/rexm/rexm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 98134ee96..ffd4d0457 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1003,6 +1003,9 @@ int main(int argc, char *argv[]) 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 From 9aaf120bbe624d1e873181764fa3cc3e6d821716 Mon Sep 17 00:00:00 2001 From: JordSant <77529699+JordSant@users.noreply.github.com> Date: Mon, 27 Oct 2025 00:15:59 +0100 Subject: [PATCH 027/189] [examples] Fixed spaces `shaders_mandelbrot_set` (#5310) --- examples/shaders/shaders_mandelbrot_set.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/shaders/shaders_mandelbrot_set.c b/examples/shaders/shaders_mandelbrot_set.c index a373c518a..dc592b6e4 100644 --- a/examples/shaders/shaders_mandelbrot_set.c +++ b/examples/shaders/shaders_mandelbrot_set.c @@ -69,7 +69,7 @@ int main(void) float offset[2] = { startingOffset[0], startingOffset[1] }; float zoom = startingZoom; // Depending on the zoom the mximum number of iterations must be adapted to get more detail as we zzoom in - // The solution is not perfect, so a control has been added to increase/decrease the number of iterations with UP/DOWN keys + // The solution is not perfect, so a control has been added to increase/decrease the number of iterations with UP/DOWN keys #if defined(PLATFORM_DESKTOP) int maxIterations = 333; float maxIterationsMultiplier = 166.5f; @@ -134,8 +134,8 @@ int main(void) if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls - // Change number of max iterations with UP and DOWN keys - // WARNING: Increasing the number of max iterations greatly impacts performance + // Change number of max iterations with UP and DOWN keys + // WARNING: Increasing the number of max iterations greatly impacts performance if (IsKeyPressed(KEY_UP)) { maxIterationsMultiplier *= 1.4f; @@ -167,10 +167,10 @@ int main(void) updateShader = true; } - // In case a parameter has been changed, update the shader values + // In case a parameter has been changed, update the shader values if (updateShader) - { - // As we zoom in, increase the number of max iterations to get more detail + { + // As we zoom in, increase the number of max iterations to get more detail // Aproximate formula, but it works-ish maxIterations = (int)(sqrtf(2.0f*sqrtf(fabsf(1.0f - sqrtf(37.5f*zoom))))*maxIterationsMultiplier); From 5db5c9b4a16ad82be08b1f100e22fd7550ae1ac5 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 27 Oct 2025 00:20:48 +0100 Subject: [PATCH 028/189] 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 ffd4d0457..f45ce9be3 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -926,12 +926,12 @@ int main(int argc, char *argv[]) system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); #endif // Update generated .html metadata - LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exRebuildList[i].name)), + LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exRebuildList[i].name)); UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name), TextFormat("%s/%s/%s.c", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); // Copy results to web side - LOG("INFO: [%s] Copy example build to raylib.com\n", exRebuildList[i].name), + LOG("INFO: [%s] Copy example build to raylib.com\n", exRebuildList[i].name); FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name), TextFormat("%s/%s/%s.html", exWebPath, exRebuildList[i].category, exRebuildList[i].name)); FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exRebuildList[i].category, exRebuildList[i].name), From 3b6a68ba69078b021a0ff87118820f1bff8180f8 Mon Sep 17 00:00:00 2001 From: Uneven Prankster <33995085+GithubPrankster@users.noreply.github.com> Date: Mon, 27 Oct 2025 08:12:42 -0300 Subject: [PATCH 029/189] Improve support for `PLATFORM_DESKTOP_WIN32` in src/Makefile (#5311) Co-authored-by: Uneven Prankster --- src/Makefile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 4369d8084..48ff50b30 100644 --- a/src/Makefile +++ b/src/Makefile @@ -130,7 +130,7 @@ HOST_PLATFORM_OS ?= WINDOWS PLATFORM_OS ?= WINDOWS # Determine PLATFORM_OS when required -ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_WEB_RGFW PLATFORM_ANDROID)) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_DESKTOP_WIN32 PLATFORM_WEB PLATFORM_WEB_RGFW PLATFORM_ANDROID)) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! # ifeq ($(UNAME),Msys) -> Windows ifeq ($(OS),Windows_NT) @@ -252,6 +252,14 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW) #GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3 #GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE) endif +ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32) + GRAPHICS ?= GRAPHICS_API_OPENGL_33 + #GRAPHICS = GRAPHICS_API_OPENGL_11_SOFTWARE # Uncomment to use software rendering + #GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1 + #GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1 + #GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3 + #GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE) +endif ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) # On DRM OpenGL ES 2.0 must be used GRAPHICS = GRAPHICS_API_OPENGL_ES2 @@ -519,7 +527,7 @@ endif #------------------------------------------------------------------------------------------------ LDFLAGS = $(CUSTOM_LDFLAGS) -L. -L$(RAYLIB_RELEASE_PATH) -ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW)) +ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_DESKTOP_WIN32)) ifeq ($(PLATFORM_OS),WINDOWS) ifneq ($(CC), tcc) LDFLAGS += -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME)dll.a From f4ed8fc50e9b7534cc904c4a9ea5a5fc3ac25c44 Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:59:59 +0100 Subject: [PATCH 030/189] [rlsw] Simplify framebuffer logic and add blit/copy fast path (#5312) * consistency tweak * unified color and depth buffer * tweaks * review the storage of clear values + complete get/set depth value * copy/blit fast path * better simd read/write * framebuffer alignment * fix 'typo' my french slipped out --- src/external/rlsw.h | 636 ++++++++++++++++++-------------------------- 1 file changed, 257 insertions(+), 379 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index e049e707e..ba2716790 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -198,6 +198,7 @@ typedef double GLclampd; //#define GL_ATTRIB_STACK_DEPTH 0x0BB0 //#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 #define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 //#define GL_COLOR_WRITEMASK 0x0C23 //#define GL_CURRENT_INDEX 0x0B01 #define GL_CURRENT_COLOR 0x0B00 @@ -332,6 +333,7 @@ typedef double GLclampd; #define glViewport(x, y, w, h) swViewport((x), (y), (w), (h)) #define glScissor(x, y, w, h) swScissor((x), (y), (w), (h)) #define glClearColor(r, g, b, a) swClearColor((r), (g), (b), (a)) +#define glClearDepth(d) swClearDepth((d)) #define glClear(bitmask) swClear((bitmask)) #define glBlendFunc(sfactor, dfactor) swBlendFunc((sfactor), (dfactor)) #define glPolygonMode(face, mode) swPolygonMode((mode)) @@ -384,7 +386,6 @@ typedef double GLclampd; #define glBindTexture(tr, id) swBindTexture((id)) // OpenGL functions NOT IMPLEMENTED by rlsw -#define glClearDepth(X) ((void)(X)) #define glDepthMask(X) ((void)(X)) #define glColorMask(X,Y,Z,W) ((void)(X),(void)(Y),(void)(Z),(void)(W)) #define glPixelStorei(X,Y) ((void)(X),(void)(Y)) @@ -415,6 +416,7 @@ typedef enum { SW_VERSION = GL_VERSION, SW_EXTENSIONS = GL_EXTENSIONS, SW_COLOR_CLEAR_VALUE = GL_COLOR_CLEAR_VALUE, + SW_DEPTH_CLEAR_VALUE = GL_DEPTH_CLEAR_VALUE, SW_CURRENT_COLOR = GL_CURRENT_COLOR, SW_CURRENT_TEXTURE_COORDS = GL_CURRENT_TEXTURE_COORDS, SW_POINT_SIZE = GL_POINT_SIZE, @@ -529,7 +531,6 @@ SWAPI void swClose(void); SWAPI bool swResizeFramebuffer(int w, int h); SWAPI void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, void *pixels); SWAPI void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySrc, int wSrc, int hSrc, SWformat format, SWtype type, void *pixels); -SWAPI void *swGetColorBuffer(int *w, int *h); SWAPI void swEnable(SWstate state); SWAPI void swDisable(SWstate state); @@ -542,6 +543,7 @@ SWAPI void swViewport(int x, int y, int width, int height); SWAPI void swScissor(int x, int y, int width, int height); SWAPI void swClearColor(float r, float g, float b, float a); +SWAPI void swClearDepth(float depth); SWAPI void swClear(uint32_t bitmask); SWAPI void swBlendFunc(SWfactor sfactor, SWfactor dfactor); @@ -608,6 +610,7 @@ SWAPI void swBindTexture(uint32_t id); #define RLSW_IMPLEMENTATION #if defined(RLSW_IMPLEMENTATION) +#include #include #include #include // Required for: floorf(), fabsf() @@ -683,66 +686,67 @@ SWAPI void swBindTexture(uint32_t id); #define SW_DEPTH_PIXEL_SIZE (SW_DEPTH_BUFFER_BITS/8) #if (SW_COLOR_BUFFER_BITS == 8) - #define COLOR_TYPE uint8_t - #define COLOR_IS_PACKED 1 - #define PACK_COLOR(r,g,b) ((((uint8_t)((r)*7+0.5f))&0x07)<<5 | (((uint8_t)((g)*7+0.5f))&0x07)<<2 | ((uint8_t)((b)*3+0.5f))&0x03) - #define UNPACK_R(p) (((p)>>5)&0x07) - #define UNPACK_G(p) (((p)>>2)&0x07) - #define UNPACK_B(p) ((p)&0x03) - #define SCALE_R(v) ((v)*255+3)/7 - #define SCALE_G(v) ((v)*255+3)/7 - #define SCALE_B(v) ((v)*255+1)/3 - #define TO_FLOAT_R(v) ((v)*(1.0f/7.0f)) - #define TO_FLOAT_G(v) ((v)*(1.0f/7.0f)) - #define TO_FLOAT_B(v) ((v)*(1.0f/3.0f)) + #define SW_COLOR_TYPE uint8_t + #define SW_COLOR_IS_PACKED 1 + #define SW_COLOR_PACK_COMP 1 + #define SW_PACK_COLOR(r,g,b) ((((uint8_t)((r)*7+0.5f))&0x07)<<5 | (((uint8_t)((g)*7+0.5f))&0x07)<<2 | ((uint8_t)((b)*3+0.5f))&0x03) + #define SW_UNPACK_R(p) (((p)>>5)&0x07) + #define SW_UNPACK_G(p) (((p)>>2)&0x07) + #define SW_UNPACK_B(p) ((p)&0x03) + #define SW_SCALE_R(v) ((v)*255+3)/7 + #define SW_SCALE_G(v) ((v)*255+3)/7 + #define SW_SCALE_B(v) ((v)*255+1)/3 + #define SW_TO_FLOAT_R(v) ((v)*(1.0f/7.0f)) + #define SW_TO_FLOAT_G(v) ((v)*(1.0f/7.0f)) + #define SW_TO_FLOAT_B(v) ((v)*(1.0f/3.0f)) #elif (SW_COLOR_BUFFER_BITS == 16) - #define COLOR_TYPE uint16_t - #define COLOR_IS_PACKED 1 - #define PACK_COLOR(r,g,b) ((((uint16_t)((r)*31+0.5f))&0x1F)<<11 | (((uint16_t)((g)*63+0.5f))&0x3F)<<5 | ((uint16_t)((b)*31+0.5f))&0x1F) - #define UNPACK_R(p) (((p)>>11)&0x1F) - #define UNPACK_G(p) (((p)>>5)&0x3F) - #define UNPACK_B(p) ((p)&0x1F) - #define SCALE_R(v) ((v)*255+15)/31 - #define SCALE_G(v) ((v)*255+31)/63 - #define SCALE_B(v) ((v)*255+15)/31 - #define TO_FLOAT_R(v) ((v)*(1.0f/31.0f)) - #define TO_FLOAT_G(v) ((v)*(1.0f/63.0f)) - #define TO_FLOAT_B(v) ((v)*(1.0f/31.0f)) + #define SW_COLOR_TYPE uint16_t + #define SW_COLOR_IS_PACKED 1 + #define SW_COLOR_PACK_COMP 1 + #define SW_PACK_COLOR(r,g,b) ((((uint16_t)((r)*31+0.5f))&0x1F)<<11 | (((uint16_t)((g)*63+0.5f))&0x3F)<<5 | ((uint16_t)((b)*31+0.5f))&0x1F) + #define SW_UNPACK_R(p) (((p)>>11)&0x1F) + #define SW_UNPACK_G(p) (((p)>>5)&0x3F) + #define SW_UNPACK_B(p) ((p)&0x1F) + #define SW_SCALE_R(v) ((v)*255+15)/31 + #define SW_SCALE_G(v) ((v)*255+31)/63 + #define SW_SCALE_B(v) ((v)*255+15)/31 + #define SW_TO_FLOAT_R(v) ((v)*(1.0f/31.0f)) + #define SW_TO_FLOAT_G(v) ((v)*(1.0f/63.0f)) + #define SW_TO_FLOAT_B(v) ((v)*(1.0f/31.0f)) #else // 32 bits - #define COLOR_TYPE uint8_t - #define COLOR_IS_PACKED 0 + #define SW_COLOR_TYPE uint8_t + #define SW_COLOR_IS_PACKED 0 + #define SW_COLOR_PACK_COMP 4 #endif #if (SW_DEPTH_BUFFER_BITS == 8) - #define DEPTH_TYPE uint8_t - #define DEPTH_IS_PACKED 1 - #define DEPTH_MAX UINT8_MAX - #define DEPTH_SCALE (1.0f/UINT8_MAX) - #define PACK_DEPTH(d) ((DEPTH_TYPE)((d)*DEPTH_MAX)) - #define UNPACK_DEPTH(p) (p) + #define SW_DEPTH_TYPE uint8_t + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX UINT8_MAX + #define SW_DEPTH_SCALE (1.0f/UINT8_MAX) + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) + #define SW_UNPACK_DEPTH(p) (p) #elif (SW_DEPTH_BUFFER_BITS == 16) - #define DEPTH_TYPE uint16_t - #define DEPTH_IS_PACKED 1 - #define DEPTH_MAX UINT16_MAX - #define DEPTH_SCALE (1.0f/UINT16_MAX) - #define PACK_DEPTH(d) ((DEPTH_TYPE)((d)*DEPTH_MAX)) - #define UNPACK_DEPTH(p) (p) + #define SW_DEPTH_TYPE uint16_t + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX UINT16_MAX + #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) + #define SW_UNPACK_DEPTH(p) (p) #else // 24 bits - #define DEPTH_TYPE uint8_t - #define DEPTH_IS_PACKED 0 - #define DEPTH_MAX 0xFFFFFF - #define DEPTH_SCALE (1.0f/0xFFFFFF) - #define PACK_DEPTH_0(d) (((uint32_t)((d)*DEPTH_MAX)>>16)&0xFF) - #define PACK_DEPTH_1(d) (((uint32_t)((d)*DEPTH_MAX)>>8)&0xFF) - #define PACK_DEPTH_2(d) ((uint32_t)((d)*DEPTH_MAX)&0xFF) - #define UNPACK_DEPTH(p) (((p)[0]<<16)|((p)[1]<<8)|(p)[2]) + #define SW_DEPTH_TYPE uint8_t + #define SW_DEPTH_IS_PACKED 0 + #define SW_DEPTH_PACK_COMP 3 + #define SW_DEPTH_MAX 0xFFFFFF + #define SW_DEPTH_SCALE (1.0f/0xFFFFFF) + #define SW_PACK_DEPTH_0(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFF) + #define SW_PACK_DEPTH_1(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFF) + #define SW_PACK_DEPTH_2(d) ((uint32_t)((d)*SW_DEPTH_MAX)&0xFF) + #define SW_UNPACK_DEPTH(p) (((p)[0]<<16)|((p)[1]<<8)|(p)[2]) #endif -#define GET_COLOR_PTR(ptr, offset) ((void*)((uint8_t*)(ptr) + (offset)*SW_COLOR_PIXEL_SIZE)) -#define GET_DEPTH_PTR(ptr, offset) ((void*)((uint8_t*)(ptr) + (offset)*SW_DEPTH_PIXEL_SIZE)) -#define INC_COLOR_PTR(ptr) ((ptr) = (void*)((uint8_t*)(ptr) + SW_COLOR_PIXEL_SIZE)) -#define INC_DEPTH_PTR(ptr) ((ptr) = (void*)((uint8_t*)(ptr) + SW_DEPTH_PIXEL_SIZE)) - #define SW_STATE_CHECK(flags) (SW_STATE_CHECK_EX(RLSW.stateFlags, (flags))) #define SW_STATE_CHECK_EX(state, flags) (((state) & (flags)) == (flags)) @@ -809,8 +813,13 @@ typedef struct { } sw_texture_t; typedef struct { - void *color; - void *depth; + alignas(SW_COLOR_PIXEL_SIZE) + SW_COLOR_TYPE color[SW_COLOR_PACK_COMP]; + SW_DEPTH_TYPE depth[SW_DEPTH_PACK_COMP]; +} sw_pixel_t; + +typedef struct { + sw_pixel_t* pixels; int width; int height; int allocSz; @@ -818,8 +827,7 @@ typedef struct { typedef struct { sw_framebuffer_t framebuffer; // Main framebuffer - float clearColor[4]; // Color used to clear the screen - float clearDepth; // Depth value used to clear the screen + sw_pixel_t clearValue; // Clear value of the framebuffer float vpCenter[2]; // Viewport center float vpHalf[2]; // Viewport half dimensions @@ -1075,30 +1083,24 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) #if defined(SW_HAS_NEON) float32x4_t values = vld1q_f32(src); float32x4_t scaled = vmulq_n_f32(values, 255.0f); - scaled = vminq_f32(vmaxq_f32(scaled, vdupq_n_f32(0.0f)), vdupq_n_f32(255.0f)); - uint32x4_t clamped = vcvtq_u32_f32(scaled); - - uint16x4_t narrow16 = vmovn_u32(clamped); - uint8x8_t narrow8 = vmovn_u16(vcombine_u16(narrow16, narrow16)); - - vst1_lane_u32((uint32_t*)dst, vreinterpret_u32_u8(narrow8), 0); + int32x4_t clamped_s32 = vcvtq_s32_f32(scaled); // f32 -> s32 (truncated) + int16x4_t narrow16_s = vqmovn_s32(clamped_s32); + int16x8_t combined16_s = vcombine_s16(narrow16_s, narrow16_s); + uint8x8_t narrow8_u = vqmovun_s16(combined16_s); + vst1_lane_u32((uint32_t*)dst, vreinterpret_u32_u8(narrow8_u), 0); #elif defined(SW_HAS_SSE41) __m128 values = _mm_loadu_ps(src); __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); - scaled = _mm_max_ps(_mm_min_ps(scaled, _mm_set1_ps(255.0f)), _mm_setzero_ps()); - __m128i clamped = _mm_cvtps_epi32(scaled); - - clamped = _mm_packus_epi32(clamped, clamped); - clamped = _mm_packus_epi16(clamped, clamped); + __m128i clamped = _mm_cvtps_epi32(scaled); // f32 -> s32 (truncated) + clamped = _mm_packus_epi32(clamped, clamped); // s32 -> u16 (saturated < 0 to 0) + clamped = _mm_packus_epi16(clamped, clamped); // u16 -> u8 (saturated > 255 to 255) *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); #elif defined(SW_HAS_SSE2) __m128 values = _mm_loadu_ps(src); __m128 scaled = _mm_mul_ps(values, _mm_set1_ps(255.0f)); - scaled = _mm_max_ps(_mm_min_ps(scaled, _mm_set1_ps(255.0f)), _mm_setzero_ps()); - __m128i clamped = _mm_cvtps_epi32(scaled); - - clamped = _mm_packs_epi32(clamped, clamped); - clamped = _mm_packus_epi16(clamped, clamped); + __m128i clamped = _mm_cvtps_epi32(scaled); // f32 -> s32 (truncated) + clamped = _mm_packs_epi32(clamped, clamped); // s32 -> s16 (saturated) + clamped = _mm_packus_epi16(clamped, clamped); // s16 -> u8 (saturated < 0 to 0) *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); #else for (int i = 0; i < 4; i++) @@ -1106,7 +1108,7 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) float val = src[i]*255.0f; val = (val > 255.0f)? 255.0f : val; val = (val < 0.0f)? 0.0f : val; - dst[i] = (uint8_t)(val + 0.5f); + dst[i] = (uint8_t)val; } #endif } @@ -1114,13 +1116,9 @@ 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) - uint32x4_t bytes = vdupq_n_u32(0); - bytes = vld1q_lane_u32((const uint32_t*)src, bytes, 0); - - uint8x8_t bytes8 = vreinterpret_u8_u32(vget_low_u32(bytes)); + uint8x8_t bytes8 = vld1_u8(src); //< Read 8 bytes, faster, but let's hope we're not at 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); floats = vmulq_n_f32(floats, SW_INV_255); vst1q_f32(dst, floats); @@ -1204,15 +1202,8 @@ static inline bool sw_framebuffer_load(int w, int h) { int size = w*h; - RLSW.framebuffer.color = SW_MALLOC(SW_COLOR_PIXEL_SIZE*size); - if (RLSW.framebuffer.color == NULL) return false; - - RLSW.framebuffer.depth = SW_MALLOC(SW_DEPTH_PIXEL_SIZE*size); - if (RLSW.framebuffer.depth == NULL) - { - SW_FREE(RLSW.framebuffer.color); - return false; - } + RLSW.framebuffer.pixels = SW_MALLOC(sizeof(sw_pixel_t)*size); + if (RLSW.framebuffer.pixels == NULL) return false; RLSW.framebuffer.width = w; RLSW.framebuffer.height = h; @@ -1232,18 +1223,10 @@ static inline bool sw_framebuffer_resize(int w, int h) return true; } - void *newColor = SW_REALLOC(RLSW.framebuffer.color, SW_COLOR_PIXEL_SIZE*newSize); - if (newColor == NULL) return false; + void *newPixels = SW_REALLOC(RLSW.framebuffer.pixels, sizeof(sw_pixel_t)*newSize); + if (newPixels == NULL) return false; - void *newDepth = SW_REALLOC(RLSW.framebuffer.depth, SW_DEPTH_PIXEL_SIZE*newSize); - if (newDepth == NULL) - { - SW_FREE(newColor); - return false; - } - - RLSW.framebuffer.color = newColor; - RLSW.framebuffer.depth = newDepth; + RLSW.framebuffer.pixels = newPixels; RLSW.framebuffer.width = w; RLSW.framebuffer.height = h; @@ -1252,29 +1235,29 @@ static inline bool sw_framebuffer_resize(int w, int h) return true; } -static inline void sw_framebuffer_read_color(float dst[4], const void *src) +static inline void sw_framebuffer_read_color(float dst[4], const sw_pixel_t *src) { -#if COLOR_IS_PACKED - COLOR_TYPE pixel = ((COLOR_TYPE*)src)[0]; - dst[0] = TO_FLOAT_R(UNPACK_R(pixel)); - dst[1] = TO_FLOAT_G(UNPACK_G(pixel)); - dst[2] = TO_FLOAT_B(UNPACK_B(pixel)); +#if SW_COLOR_IS_PACKED + SW_COLOR_TYPE pixel = src->color[0]; + dst[0] = SW_TO_FLOAT_R(SW_UNPACK_R(pixel)); + dst[1] = SW_TO_FLOAT_G(SW_UNPACK_G(pixel)); + dst[2] = SW_TO_FLOAT_B(SW_UNPACK_B(pixel)); dst[3] = 1.0f; #else - sw_float_from_unorm8_simd(dst, src); + sw_float_from_unorm8_simd(dst, src->color); #endif } -static inline void sw_framebuffer_read_color8(uint8_t dst[4], const void *src) +static inline void sw_framebuffer_read_color8(uint8_t dst[4], const sw_pixel_t *src) { -#if COLOR_IS_PACKED - COLOR_TYPE pixel = ((COLOR_TYPE*)src)[0]; - dst[0] = SCALE_R(UNPACK_R(pixel)); - dst[1] = SCALE_G(UNPACK_G(pixel)); - dst[2] = SCALE_B(UNPACK_B(pixel)); +#if SW_COLOR_IS_PACKED + SW_COLOR_TYPE pixel = src->color[0]; + dst[0] = SW_SCALE_R(SW_UNPACK_R(pixel)); + dst[1] = SW_SCALE_G(SW_UNPACK_G(pixel)); + dst[2] = SW_SCALE_B(SW_UNPACK_B(pixel)); dst[3] = 255; #else - const COLOR_TYPE *p = (const COLOR_TYPE*)src; + const SW_COLOR_TYPE *p = src->color; dst[0] = p[0]; dst[1] = p[1]; dst[2] = p[2]; @@ -1282,231 +1265,139 @@ static inline void sw_framebuffer_read_color8(uint8_t dst[4], const void *src) #endif } -static inline void sw_framebuffer_write_color(void *dst, const float src[4]) +static inline float sw_framebuffer_read_depth(const sw_pixel_t *src) { -#if COLOR_IS_PACKED - ((COLOR_TYPE*)dst)[0] = PACK_COLOR(src[0], src[1], src[2]); +#if SW_DEPTH_IS_PACKED + return src->depth[0]*SW_DEPTH_SCALE; #else - sw_float_to_unorm8_simd(dst, src); + return SW_UNPACK_DEPTH(src->depth)*SW_DEPTH_SCALE; #endif } -static inline void sw_framebuffer_fill_color(void *ptr, int size, const float color[4]) +static inline void sw_framebuffer_write_color(sw_pixel_t *dst, const float src[4]) { -#if COLOR_IS_PACKED - COLOR_TYPE packed = PACK_COLOR(color[0], color[1], color[2]); - COLOR_TYPE *p = (COLOR_TYPE*)ptr; +#if SW_COLOR_IS_PACKED + dst->color[0] = SW_PACK_COLOR(src[0], src[1], src[2]); #else - COLOR_TYPE r = sw_clampi(color[0]*255, 0, 255); - COLOR_TYPE g = sw_clampi(color[1]*255, 0, 255); - COLOR_TYPE b = sw_clampi(color[2]*255, 0, 255); - COLOR_TYPE a = sw_clampi(color[3]*255, 0, 255); - COLOR_TYPE *p = (COLOR_TYPE*)ptr; + sw_float_to_unorm8_simd(dst->color, src); #endif - +} + +static inline void sw_framebuffer_write_depth(sw_pixel_t *dst, float depth) +{ +#if SW_DEPTH_IS_PACKED + dst->depth[0] = SW_PACK_DEPTH(depth); +#else + dst->depth[0] = SW_PACK_DEPTH_0(depth); + dst->depth[1] = SW_PACK_DEPTH_1(depth); + dst->depth[2] = SW_PACK_DEPTH_2(depth); +#endif +} + +static inline void sw_framebuffer_fill_color(sw_pixel_t *ptr, int size, const SW_COLOR_TYPE color[SW_COLOR_PACK_COMP]) +{ if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) { int w = RLSW.scMax[0] - RLSW.scMin[0] + 1; for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) { -#if COLOR_IS_PACKED - COLOR_TYPE *row = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; - for (int x = 0; x < w; x++) *row++ = packed; -#else - COLOR_TYPE *row = p + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); - for (int x = 0; x < w; x++) + sw_pixel_t *row = ptr + y*RLSW.framebuffer.width + RLSW.scMin[0]; + for (int x = 0; x < w; x++, row++) { - *row++ = r; - *row++ = g; - *row++ = b; - *row++ = a; + for (int i = 0; i < SW_COLOR_PACK_COMP; i++) row->color[i] = color[i]; } -#endif } } else { -#if COLOR_IS_PACKED - for (int i = 0; i < size; i++) *p++ = packed; -#else - for (int i = 0; i < size; i++) + for (int i = 0; i < size; i++, ptr++) { - *p++ = r; - *p++ = g; - *p++ = b; - *p++ = a; + for (int j = 0; j < SW_COLOR_PACK_COMP; j++) ptr->color[j] = color[j]; } -#endif } } -static inline float sw_framebuffer_read_depth(const void *src) +static inline void sw_framebuffer_fill_depth(sw_pixel_t *ptr, int size, const SW_DEPTH_TYPE depth[SW_DEPTH_PACK_COMP]) { -#if DEPTH_IS_PACKED - return ((DEPTH_TYPE*)src)[0]*DEPTH_SCALE; -#else - const DEPTH_TYPE *p = (const DEPTH_TYPE*)src; - uint32_t d = UNPACK_DEPTH(p); - return d*DEPTH_SCALE; -#endif -} - -static inline void sw_framebuffer_write_depth(void *dst, float depth) -{ -#if DEPTH_IS_PACKED - ((DEPTH_TYPE*)dst)[0] = PACK_DEPTH(depth); -#else - DEPTH_TYPE *p = (DEPTH_TYPE*)dst; - p[0] = PACK_DEPTH_0(depth); - p[1] = PACK_DEPTH_1(depth); - p[2] = PACK_DEPTH_2(depth); -#endif -} - -static inline void sw_framebuffer_fill_depth(void *ptr, int size, float value) -{ -#if DEPTH_IS_PACKED - DEPTH_TYPE d = PACK_DEPTH(value); - DEPTH_TYPE *p = (DEPTH_TYPE*)ptr; -#else - DEPTH_TYPE d0 = PACK_DEPTH_0(value); - DEPTH_TYPE d1 = PACK_DEPTH_1(value); - DEPTH_TYPE d2 = PACK_DEPTH_2(value); - DEPTH_TYPE *p = (DEPTH_TYPE*)ptr; -#endif - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) { int w = RLSW.scMax[0] - RLSW.scMin[0] + 1; for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) { -#if DEPTH_IS_PACKED - DEPTH_TYPE *row = p + y*RLSW.framebuffer.width + RLSW.scMin[0]; - for (int x = 0; x < w; x++) *row++ = d; -#else - DEPTH_TYPE *row = p + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); - for (int x = 0; x < w; x++) + sw_pixel_t *row = ptr + y*RLSW.framebuffer.width + RLSW.scMin[0]; + for (int x = 0; x < w; x++, row++) { - *row++ = d0; - *row++ = d1; - *row++ = d2; + for (int i = 0; i < SW_DEPTH_PACK_COMP; i++) row->depth[i] = depth[i]; } -#endif } } else { -#if DEPTH_IS_PACKED - for (int i = 0; i < size; i++) *p++ = d; -#else - for (int i = 0; i < size; i++) + for (int i = 0; i < size; i++, ptr++) { - *p++ = d0; - *p++ = d1; - *p++ = d2; + for (int j = 0; j < SW_DEPTH_PACK_COMP; j++) ptr->depth[j] = depth[j]; } -#endif } } -static inline void sw_framebuffer_fill(void *colorPtr, void *depthPtr, int size, float color[4], float depth) +static inline void sw_framebuffer_fill(sw_pixel_t *ptr, int size, sw_pixel_t value) { -#if COLOR_IS_PACKED - COLOR_TYPE packedColor = PACK_COLOR(color[0], color[1], color[2]); - COLOR_TYPE *pColor = (COLOR_TYPE*)colorPtr; -#else - COLOR_TYPE r = sw_clampi(color[0]*255, 0, 255); - COLOR_TYPE g = sw_clampi(color[1]*255, 0, 255); - COLOR_TYPE b = sw_clampi(color[2]*255, 0, 255); - COLOR_TYPE a = sw_clampi(color[3]*255, 0, 255); - COLOR_TYPE *pColor = (COLOR_TYPE*)colorPtr; -#endif - -#if DEPTH_IS_PACKED - DEPTH_TYPE d = PACK_DEPTH(depth); - DEPTH_TYPE *pDepth = (DEPTH_TYPE*)depthPtr; -#else - DEPTH_TYPE d0 = PACK_DEPTH_0(depth); - DEPTH_TYPE d1 = PACK_DEPTH_1(depth); - DEPTH_TYPE d2 = PACK_DEPTH_2(depth); - DEPTH_TYPE *pDepth = (DEPTH_TYPE*)depthPtr; -#endif - if (RLSW.stateFlags & SW_STATE_SCISSOR_TEST) { int w = RLSW.scMax[0] - RLSW.scMin[0] + 1; for (int y = RLSW.scMin[1]; y <= RLSW.scMax[1]; y++) { -#if COLOR_IS_PACKED - COLOR_TYPE *rowColor = pColor + y*RLSW.framebuffer.width + RLSW.scMin[0]; -#else - COLOR_TYPE *rowColor = pColor + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); -#endif - -#if DEPTH_IS_PACKED - DEPTH_TYPE *rowDepth = pDepth + y*RLSW.framebuffer.width + RLSW.scMin[0]; -#else - DEPTH_TYPE *rowDepth = pDepth + 3*(y*RLSW.framebuffer.width + RLSW.scMin[0]); -#endif - - for (int x = 0; x < w; x++) - { -#if COLOR_IS_PACKED - *rowColor++ = packedColor; -#else - *rowColor++ = r; - *rowColor++ = g; - *rowColor++ = b; - *rowColor++ = a; -#endif - -#if DEPTH_IS_PACKED - *rowDepth++ = d; -#else - *rowDepth++ = d0; - *rowDepth++ = d1; - *rowDepth++ = d2; -#endif - } + sw_pixel_t *row = ptr + y*RLSW.framebuffer.width + RLSW.scMin[0]; + for (int x = 0; x < w; x++, row++) *row = value; } } else { + for (int i = 0; i < size; i++, ptr++) *ptr = value; + } +} + +static inline void sw_framebuffer_copy_fast(void* dst) +{ + int size = RLSW.framebuffer.width*RLSW.framebuffer.height; + const sw_pixel_t *pixels = RLSW.framebuffer.pixels; + +#if SW_COLOR_BUFFER_BITS == 8 + uint8_t *dst8 = (uint8_t*)dst; + for (int i = 0; i < size; i++) dst8[i] = pixels[i].color[0]; +#elif SW_COLOR_BUFFER_BITS == 16 + uint16_t *dst16 = (uint16_t*)dst; + for (int i = 0; i < size; i++) dst16[i] = *(uint16_t*)pixels[i].color; +#else // 32 bits + uint32_t *dst32 = (uint32_t*)dst; + #if SW_GL_FRAMEBUFFER_COPY_BGRA for (int i = 0; i < size; i++) { -#if COLOR_IS_PACKED - *pColor++ = packedColor; -#else - *pColor++ = r; - *pColor++ = g; - *pColor++ = b; - *pColor++ = a; -#endif - -#if DEPTH_IS_PACKED - *pDepth++ = d; -#else - *pDepth++ = d0; - *pDepth++ = d1; - *pDepth++ = d2; -#endif + const uint8_t *c = pixels[i].color; + dst32[i] = (uint32_t)c[2] | ((uint32_t)c[1] << 8) | ((uint32_t)c[0] << 16) | ((uint32_t)c[3] << 24); } - } + #else // RGBA + for (int i = 0; i < size; i++) dst32[i] = *(uint32_t*)pixels[i].color; + #endif +#endif } #define DEFINE_FRAMEBUFFER_COPY_BEGIN(name, DST_PTR_T) \ -static inline void sw_framebuffer_copy_to_##name(int x, int y, int w, int h, DST_PTR_T *dst) \ +static inline void sw_framebuffer_copy_to_##name(int x, int y, int w, int h, DST_PTR_T *dst) \ { \ - const void *src = RLSW.framebuffer.color; \ + const int stride = RLSW.framebuffer.width; \ + const sw_pixel_t *src = RLSW.framebuffer.pixels + (y*stride + x); \ \ - for (int iy = y; iy < h; iy++) { \ - for (int ix = x; ix < w; ix++) { \ + for (int iy = 0; iy < h; iy++) { \ + const sw_pixel_t *line = src; \ + for (int ix = 0; ix < w; ix++) { \ uint8_t color[4]; \ - sw_framebuffer_read_color8(color, src); \ + sw_framebuffer_read_color8(color, line); \ #define DEFINE_FRAMEBUFFER_COPY_END() \ - INC_COLOR_PTR(src); \ + ++line; \ } \ + src += stride; \ } \ } @@ -1620,22 +1511,24 @@ static inline void sw_framebuffer_blit_to_##name( int xSrc, int ySrc, int wSrc, int hSrc, \ DST_PTR_T *dst) \ { \ - const uint8_t *srcBase = (uint8_t*)RLSW.framebuffer.color; \ - int fbWidth = RLSW.framebuffer.width; \ + const sw_pixel_t *srcBase = RLSW.framebuffer.pixels; \ + const int fbWidth = RLSW.framebuffer.width; \ \ - uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ - uint32_t yScale = ((uint32_t)hSrc << 16)/(uint32_t)hDst; \ + const uint32_t xScale = ((uint32_t)wSrc << 16)/(uint32_t)wDst; \ + const uint32_t yScale = ((uint32_t)hSrc << 16)/(uint32_t)hDst; \ \ for (int dy = 0; dy < hDst; dy++) { \ uint32_t yFix = ((uint32_t)ySrc << 16) + dy*yScale; \ int sy = yFix >> 16; \ + const sw_pixel_t *srcLine = srcBase + sy*fbWidth + xSrc; \ \ + const sw_pixel_t *srcPtr = srcLine; \ for (int dx = 0; dx < wDst; dx++) { \ uint32_t xFix = dx*xScale; \ int sx = xFix >> 16; \ - const void *srcPtr = GET_COLOR_PTR(srcBase, sy*fbWidth + sx); \ + const sw_pixel_t *pixel = srcPtr + sx; \ uint8_t color[4]; \ - sw_framebuffer_read_color8(color, srcPtr); \ + sw_framebuffer_read_color8(color, pixel); #define DEFINE_FRAMEBUFFER_BLIT_END() \ } \ @@ -2378,8 +2271,7 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, \ /* Pre-calculate the starting pointers for the framebuffer row */ \ int y = (int)start->screen[1]; \ - void *cptr = GET_COLOR_PTR(RLSW.framebuffer.color, y*RLSW.framebuffer.width + xStart); \ - void *dptr = GET_DEPTH_PTR(RLSW.framebuffer.depth, y*RLSW.framebuffer.width + xStart); \ + sw_pixel_t *ptr = RLSW.framebuffer.pixels + y*RLSW.framebuffer.width + xStart; \ \ /* Scanline rasterization */ \ for (int x = xStart; x < xEnd; x++) \ @@ -2395,12 +2287,12 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, if (ENABLE_DEPTH_TEST) \ { \ /* TODO: Implement different depth funcs? */ \ - float depth = sw_framebuffer_read_depth(dptr); \ + float depth = sw_framebuffer_read_depth(ptr); \ if (z > depth) goto discard; \ } \ \ /* TODO: Implement depth mask */ \ - sw_framebuffer_write_depth(dptr, z); \ + sw_framebuffer_write_depth(ptr, z); \ \ if (ENABLE_TEXTURE) \ { \ @@ -2417,13 +2309,13 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ - sw_framebuffer_read_color(dstColor, cptr); \ + sw_framebuffer_read_color(dstColor, ptr); \ sw_blend_colors(dstColor, srcColor); \ - sw_framebuffer_write_color(cptr, dstColor); \ + sw_framebuffer_write_color(ptr, dstColor); \ } \ else \ { \ - sw_framebuffer_write_color(cptr, srcColor); \ + sw_framebuffer_write_color(ptr, srcColor); \ } \ \ /* Increment the interpolation parameter, UVs, and pointers */ \ @@ -2439,9 +2331,7 @@ static inline void FUNC_NAME(const sw_texture_t *tex, const sw_vertex_t *start, u += dUdx; \ v += dVdx; \ } \ - \ - INC_COLOR_PTR(cptr); \ - INC_DEPTH_PTR(dptr); \ + ++ptr; \ } \ } @@ -2809,8 +2699,7 @@ static inline void FUNC_NAME(void) const sw_texture_t *tex; \ if (ENABLE_TEXTURE) tex = &RLSW.loadedTextures[RLSW.currentTexture]; \ \ - void *cDstBase = RLSW.framebuffer.color; \ - void *dDstBase = RLSW.framebuffer.depth; \ + sw_pixel_t *pixels = RLSW.framebuffer.pixels; \ int wDst = RLSW.framebuffer.width; \ \ float zScanline = v0->homogeneous[2] + dZdx*xSubstep + dZdy*ySubstep; \ @@ -2826,8 +2715,7 @@ static inline void FUNC_NAME(void) \ for (int y = yMin; y < yMax; y++) \ { \ - void *cptr = GET_COLOR_PTR(cDstBase, y*wDst + xMin); \ - void *dptr = GET_DEPTH_PTR(dDstBase, y*wDst + xMin); \ + sw_pixel_t *ptr = pixels + y*wDst + xMin; \ \ float z = zScanline; \ float u = uScanline; \ @@ -2855,12 +2743,12 @@ static inline void FUNC_NAME(void) if (ENABLE_DEPTH_TEST) \ { \ /* TODO: Implement different depth funcs? */ \ - float depth = sw_framebuffer_read_depth(dptr); \ + float depth = sw_framebuffer_read_depth(ptr); \ if (z > depth) goto discard; \ } \ \ /* TODO: Implement depth mask */ \ - sw_framebuffer_write_depth(dptr, z); \ + sw_framebuffer_write_depth(ptr, z); \ \ if (ENABLE_TEXTURE) \ { \ @@ -2875,11 +2763,11 @@ static inline void FUNC_NAME(void) if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ - sw_framebuffer_read_color(dstColor, cptr); \ + sw_framebuffer_read_color(dstColor, ptr); \ sw_blend_colors(dstColor, srcColor); \ - sw_framebuffer_write_color(cptr, dstColor); \ + sw_framebuffer_write_color(ptr, dstColor); \ } \ - else sw_framebuffer_write_color(cptr, srcColor); \ + else sw_framebuffer_write_color(ptr, srcColor); \ \ discard: \ z += dZdx; \ @@ -2887,15 +2775,12 @@ static inline void FUNC_NAME(void) color[1] += dCdx[1]; \ color[2] += dCdx[2]; \ color[3] += dCdx[3]; \ - \ if (ENABLE_TEXTURE) \ { \ u += dUdx; \ v += dVdx; \ } \ - \ - INC_COLOR_PTR(cptr); \ - INC_DEPTH_PTR(dptr); \ + ++ptr; \ } \ \ zScanline += dZdy; \ @@ -3119,8 +3004,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ float a = v0->color[3] + aInc*substep; \ \ const int fbWidth = RLSW.framebuffer.width; \ - void *cBuffer = RLSW.framebuffer.color; \ - void *dBuffer = RLSW.framebuffer.depth; \ + sw_pixel_t *pixels = RLSW.framebuffer.pixels; \ \ int numPixels = (int)(steps - substep) + 1; \ \ @@ -3130,28 +3014,26 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ int px = (int)(x - 0.5f); \ int py = (int)(y - 0.5f); \ \ - int offset = py*fbWidth + px; \ - void *dptr = GET_DEPTH_PTR(dBuffer, offset); \ + sw_pixel_t *ptr = pixels + py*fbWidth + px; \ \ if (ENABLE_DEPTH_TEST) \ { \ - float depth = sw_framebuffer_read_depth(dptr); \ + float depth = sw_framebuffer_read_depth(ptr); \ if (z > depth) goto discard; \ } \ \ - sw_framebuffer_write_depth(dptr, z); \ + sw_framebuffer_write_depth(ptr, z); \ \ - void *cptr = GET_COLOR_PTR(cBuffer, offset); \ float color[4] = {r, g, b, a}; \ \ if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ - sw_framebuffer_read_color(dstColor, cptr); \ + sw_framebuffer_read_color(dstColor, ptr); \ sw_blend_colors(dstColor, color); \ - sw_framebuffer_write_color(cptr, dstColor); \ + sw_framebuffer_write_color(ptr, dstColor); \ } \ - else sw_framebuffer_write_color(cptr, color); \ + else sw_framebuffer_write_color(ptr, color); \ \ discard: \ x += xInc; y += yInc; z += zInc; \ @@ -3292,27 +3174,24 @@ static inline void FUNC_NAME(int x, int y, float z, const float color[4]) \ } \ \ int offset = y*RLSW.framebuffer.width + x; \ - \ - void *dptr = GET_DEPTH_PTR(RLSW.framebuffer.depth, offset); \ + sw_pixel_t *ptr = RLSW.framebuffer.pixels + offset; \ \ if (ENABLE_DEPTH_TEST) \ { \ - float depth = sw_framebuffer_read_depth(dptr); \ + float depth = sw_framebuffer_read_depth(ptr); \ if (z > depth) return; \ } \ \ - sw_framebuffer_write_depth(dptr, z); \ - \ - void *cptr = GET_COLOR_PTR(RLSW.framebuffer.color, offset); \ + sw_framebuffer_write_depth(ptr, z); \ \ if (ENABLE_COLOR_BLEND) \ { \ float dstColor[4]; \ - sw_framebuffer_read_color(dstColor, cptr); \ + sw_framebuffer_read_color(dstColor, ptr); \ sw_blend_colors(dstColor, color); \ - sw_framebuffer_write_color(cptr, dstColor); \ + sw_framebuffer_write_color(ptr, dstColor); \ } \ - else sw_framebuffer_write_color(cptr, color); \ + else sw_framebuffer_write_color(ptr, color); \ } #define DEFINE_POINT_THICK_RASTER(FUNC_NAME, RASTER_FUNC) \ @@ -3598,11 +3477,9 @@ bool swInit(int w, int h) RLSW.freeTextureIds = (uint32_t *)SW_MALLOC(SW_MAX_TEXTURES*sizeof(uint32_t)); if (RLSW.loadedTextures == NULL) { swClose(); return false; } - RLSW.clearColor[0] = 0.0f; - RLSW.clearColor[1] = 0.0f; - RLSW.clearColor[2] = 0.0f; - RLSW.clearColor[3] = 1.0f; - RLSW.clearDepth = 1.0f; + const float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + sw_framebuffer_write_color(&RLSW.clearValue, clearColor); + sw_framebuffer_write_depth(&RLSW.clearValue, 1.0f); RLSW.currentMatrixMode = SW_MODELVIEW; RLSW.currentMatrix = &RLSW.stackModelview[0]; @@ -3669,8 +3546,7 @@ void swClose(void) } } - SW_FREE(RLSW.framebuffer.color); - SW_FREE(RLSW.framebuffer.depth); + SW_FREE(RLSW.framebuffer.pixels); SW_FREE(RLSW.loadedTextures); SW_FREE(RLSW.freeTextureIds); @@ -3686,17 +3562,8 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, { sw_pixelformat_t pFormat = (sw_pixelformat_t)sw_get_pixel_format(format, type); - if (w <= 0) - { - RLSW.errCode = SW_INVALID_VALUE; - return; - } - - if (h <= 0) - { - RLSW.errCode = SW_INVALID_VALUE; - return; - } + if (w <= 0) { RLSW.errCode = SW_INVALID_VALUE; return; } + if (h <= 0) { RLSW.errCode = SW_INVALID_VALUE; return; } if (w > RLSW.framebuffer.width) w = RLSW.framebuffer.width; if (h > RLSW.framebuffer.height) h = RLSW.framebuffer.height; @@ -3704,6 +3571,25 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, x = sw_clampi(x, 0, w); y = sw_clampi(y, 0, h); + if (x >= w || y >= h) return; + + if (x == 0 && y == 0 && w == RLSW.framebuffer.width && h == RLSW.framebuffer.height) + { + #if SW_COLOR_BUFFER_BITS == 32 + if (pFormat == SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) + { + sw_framebuffer_copy_fast(pixels); + return; + } + #elif SW_COLOR_BUFFER_BITS == 16 + if (pFormat == SW_PIXELFORMAT_UNCOMPRESSED_R5G6B5) + { + sw_framebuffer_copy_fast(pixels); + return; + } + #endif + } + switch (pFormat) { case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_framebuffer_copy_to_GRAYALPHA(x, y, w, h, (uint8_t *)pixels); break; @@ -3730,17 +3616,13 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr { sw_pixelformat_t pFormat = (sw_pixelformat_t)sw_get_pixel_format(format, type); - if (wSrc <= 0) + if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc) { - RLSW.errCode = SW_INVALID_VALUE; - return; + swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels); } - if (hSrc <= 0) - { - RLSW.errCode = SW_INVALID_VALUE; - return; - } + if (wSrc <= 0) { RLSW.errCode = SW_INVALID_VALUE; return; } + if (hSrc <= 0) { RLSW.errCode = SW_INVALID_VALUE; return; } if (wSrc > RLSW.framebuffer.width) wSrc = RLSW.framebuffer.width; if (hSrc > RLSW.framebuffer.height) hSrc = RLSW.framebuffer.height; @@ -3770,14 +3652,6 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr } } -void *swGetColorBuffer(int *w, int *h) -{ - if (w) *w = RLSW.framebuffer.width; - if (h) *h = RLSW.framebuffer.height; - - return RLSW.framebuffer.color; -} - void swEnable(SWstate state) { switch (state) @@ -3821,10 +3695,11 @@ void swGetFloatv(SWget name, float *v) { case SW_COLOR_CLEAR_VALUE: { - v[0] = RLSW.clearColor[0]; - v[1] = RLSW.clearColor[1]; - v[2] = RLSW.clearColor[2]; - v[3] = RLSW.clearColor[3]; + sw_framebuffer_read_color(v, &RLSW.clearValue); + } break; + case SW_DEPTH_CLEAR_VALUE: + { + v[0] = sw_framebuffer_read_depth(&RLSW.clearValue); } break; case SW_CURRENT_COLOR: { @@ -3932,10 +3807,13 @@ void swScissor(int x, int y, int width, int height) void swClearColor(float r, float g, float b, float a) { - RLSW.clearColor[0] = r; - RLSW.clearColor[1] = g; - RLSW.clearColor[2] = b; - RLSW.clearColor[3] = a; + float v[4] = { r, g, b, a }; + sw_framebuffer_write_color(&RLSW.clearValue, v); +} + +void swClearDepth(float depth) +{ + sw_framebuffer_write_depth(&RLSW.clearValue, depth); } void swClear(uint32_t bitmask) @@ -3944,15 +3822,15 @@ void swClear(uint32_t bitmask) if ((bitmask & (SW_COLOR_BUFFER_BIT | SW_DEPTH_BUFFER_BIT)) == (SW_COLOR_BUFFER_BIT | SW_DEPTH_BUFFER_BIT)) { - sw_framebuffer_fill(RLSW.framebuffer.color, RLSW.framebuffer.depth,size, RLSW.clearColor, RLSW.clearDepth); + sw_framebuffer_fill(RLSW.framebuffer.pixels, size, RLSW.clearValue); } else if (bitmask & (SW_COLOR_BUFFER_BIT)) { - sw_framebuffer_fill_color(RLSW.framebuffer.color, size, RLSW.clearColor); + sw_framebuffer_fill_color(RLSW.framebuffer.pixels, size, RLSW.clearValue.color); } else if (bitmask & SW_DEPTH_BUFFER_BIT) { - sw_framebuffer_fill_depth(RLSW.framebuffer.depth, size, RLSW.clearDepth); + sw_framebuffer_fill_depth(RLSW.framebuffer.pixels, size, RLSW.clearValue.depth); } } @@ -4525,7 +4403,7 @@ void swDrawArrays(SWdraw mode, int offset, int count) float u, v; if (texcoords) { - int idx = 2 * i; + int idx = 2*i; u = texcoords[idx]; v = texcoords[idx + 1]; } @@ -4536,8 +4414,8 @@ void swDrawArrays(SWdraw mode, int offset, int count) } float texcoord[2]; - texcoord[0] = texMatrix[0] * u + texMatrix[4] * v + texMatrix[12]; - texcoord[1] = texMatrix[1] * u + texMatrix[5] * v + texMatrix[13]; + texcoord[0] = texMatrix[0]*u + texMatrix[4]*v + texMatrix[12]; + texcoord[1] = texMatrix[1]*u + texMatrix[5]*v + texMatrix[13]; float color[4] = { defaultColor[0], @@ -4548,14 +4426,14 @@ void swDrawArrays(SWdraw mode, int offset, int count) if (colors) { - int idx = 4 * i; + int idx = 4*i; color[0] *= (float)colors[idx]*SW_INV_255; color[1] *= (float)colors[idx + 1]*SW_INV_255; color[2] *= (float)colors[idx + 2]*SW_INV_255; color[3] *= (float)colors[idx + 3]*SW_INV_255; } - int idx = 3 * i; + int idx = 3*i; float position[4] = { positions[idx], positions[idx + 1], @@ -4621,7 +4499,7 @@ void swDrawElements(SWdraw mode, int count, int type, const void *indices) float u, v; if (texcoords) { - int idx = 2 * index; + int idx = 2*index; u = texcoords[idx]; v = texcoords[idx + 1]; } @@ -4632,8 +4510,8 @@ void swDrawElements(SWdraw mode, int count, int type, const void *indices) } float texcoord[2]; - texcoord[0] = texMatrix[0] * u + texMatrix[4] * v + texMatrix[12]; - texcoord[1] = texMatrix[1] * u + texMatrix[5] * v + texMatrix[13]; + texcoord[0] = texMatrix[0]*u + texMatrix[4]*v + texMatrix[12]; + texcoord[1] = texMatrix[1]*u + texMatrix[5]*v + texMatrix[13]; float color[4] = { defaultColor[0], @@ -4644,14 +4522,14 @@ void swDrawElements(SWdraw mode, int count, int type, const void *indices) if (colors) { - int idx = 4 * index; + int idx = 4*index; color[0] *= (float)colors[idx]*SW_INV_255; color[1] *= (float)colors[idx + 1]*SW_INV_255; color[2] *= (float)colors[idx + 2]*SW_INV_255; color[3] *= (float)colors[idx + 3]*SW_INV_255; } - int idx = 3 * index; + int idx = 3*index; float position[4] = { positions[idx], positions[idx + 1], From 93a21c7e1300c073acc0a9c5b69d8cdfb6127255 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Oct 2025 19:55:28 +0100 Subject: [PATCH 031/189] Support other graphic backends on some platforms --- src/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 48ff50b30..0895d8f95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -262,16 +262,16 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32) endif ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) # On DRM OpenGL ES 2.0 must be used - GRAPHICS = GRAPHICS_API_OPENGL_ES2 + GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 endif ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0 - GRAPHICS = GRAPHICS_API_OPENGL_ES2 + GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 #GRAPHICS = GRAPHICS_API_OPENGL_ES3 endif ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) # By default use OpenGL ES 2.0 on Android - GRAPHICS = GRAPHICS_API_OPENGL_ES2 + GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 endif # Define default C compiler and archiver to pack library: CC, AR From 78870335e6e791055c38c007b28bca9eea37947d Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Oct 2025 19:55:35 +0100 Subject: [PATCH 032/189] Update rlgl.h --- src/rlgl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rlgl.h b/src/rlgl.h index e6a1c9432..99e9037d5 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -21,6 +21,7 @@ * Internal buffer (and resources) must be manually unloaded calling rlglClose() * * CONFIGURATION: +* #define GRAPHICS_API_OPENGL_11_SOFTWARE * #define GRAPHICS_API_OPENGL_11 * #define GRAPHICS_API_OPENGL_21 * #define GRAPHICS_API_OPENGL_33 From f106301d4678a392d67c564666ac77a4d5d1946c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Oct 2025 20:11:29 +0100 Subject: [PATCH 033/189] ADDED: Some code sample for RISC-V RVV vector instructions -WIP- --- src/external/rlsw.h | 96 ++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index ba2716790..cfb2d236f 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -616,69 +616,74 @@ SWAPI void swBindTexture(uint32_t id); #include // Required for: floorf(), fabsf() #if defined(__FMA__) && defined(__AVX2__) -# define SW_HAS_FMA_AVX2 -# include + #define SW_HAS_FMA_AVX2 + #include #endif #if defined(__FMA__) && defined(__AVX__) -# define SW_HAS_FMA_AVX -# include + #define SW_HAS_FMA_AVX + #include #endif #if defined(__AVX2__) -# define SW_HAS_AVX2 -# include + #define SW_HAS_AVX2 + #include #endif #if defined(__AVX__) -# define SW_HAS_AVX -# include + #define SW_HAS_AVX + #include #endif #if defined(__SSE4_2__) -# define SW_HAS_SSE42 -# include + #define SW_HAS_SSE42 + #include #endif #if defined(__SSE4_1__) -# define SW_HAS_SSE41 -# include + #define SW_HAS_SSE41 + #include #endif #if defined(__SSSE3__) -# define SW_HAS_SSSE3 -# include + #define SW_HAS_SSSE3 + #include #endif #if defined(__SSE3__) -# define SW_HAS_SSE3 -# include + #define SW_HAS_SSE3 + #include #endif #if defined(__SSE2__) -# define SW_HAS_SSE2 -# include + #define SW_HAS_SSE2 + #include #endif #if defined(__SSE__) -# define SW_HAS_SSE -# include + #define SW_HAS_SSE + #include #endif #if defined(__ARM_NEON) || defined(__aarch64__) -# if defined(__ARM_FEATURE_FMA) -# define SW_HAS_NEON_FMA -# else -# define SW_HAS_NEON -# endif -# include + #if defined(__ARM_FEATURE_FMA) + #define SW_HAS_NEON_FMA + #else + #define SW_HAS_NEON + #endif + #include +#endif + +#ifdef __riscv_vector + #define SW_HAS_RVV + #include #endif //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- #define SW_PI 3.14159265358979323846f -#define SW_INV_255 0.00392156862745098f +#define SW_INV_255 0.00392156862745098f // 1.0f/255.0f #define SW_DEG2RAD (SW_PI/180.0f) #define SW_RAD2DEG (180.0f/SW_PI) @@ -1102,6 +1107,27 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) clamped = _mm_packs_epi32(clamped, clamped); // s32 -> s16 (saturated) clamped = _mm_packus_epi16(clamped, clamped); // s16 -> u8 (saturated < 0 to 0) *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); +#elif defined(SW_HAS_RVV) + // TODO: Sample code generated by AI, needs testing and review + size_t vl = vsetvl_e32m1(4); // Load up to 4 floats into a vector register + vfloat32m1_t vsrc = vle32_v_f32m1(src, vl); // Load float32 values + + // Clamp to [0.0f, 1.0f] + vfloat32m1_t vzero = vfmv_v_f_f32m1(0.0f, vl); + vfloat32m1_t vone = vfmv_v_f_f32m1(1.0f, vl); + vsrc = vfmin_vv_f32m1(vsrc, vone, vl); + vsrc = vfmax_vv_f32m1(vsrc, vzero, vl); + + // Multiply by 255.0f and add 0.5f for rounding + vfloat32m1_t vscaled = vfmul_vf_f32m1(vsrc, 255.0f, vl); + vscaled = vfadd_vf_f32m1(vscaled, 0.5f, vl); + + // Convert to unsigned integer (truncate toward zero) + vuint32m1_t vu32 = vfcvt_xu_f_v_u32m1(vscaled, vl); + + // Narrow from u32 -> u8 + vuint8m1_t vu8 = vnclipu_wx_u8m1(vu32, 0, vl); // Round toward zero + vse8_v_u8m1(dst, vu8, vl); // Store result #else for (int i = 0; i < 4; i++) { @@ -1123,18 +1149,26 @@ static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) floats = vmulq_n_f32(floats, SW_INV_255); vst1q_f32(dst, floats); #elif defined(SW_HAS_SSE41) - __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); + __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t *)src); __m128i ints = _mm_cvtepu8_epi32(bytes); __m128 floats = _mm_cvtepi32_ps(ints); floats = _mm_mul_ps(floats, _mm_set1_ps(SW_INV_255)); _mm_storeu_ps(dst, floats); #elif defined(SW_HAS_SSE2) - __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t*)src); + __m128i bytes = _mm_cvtsi32_si128(*(const uint32_t *)src); bytes = _mm_unpacklo_epi8(bytes, _mm_setzero_si128()); __m128i ints = _mm_unpacklo_epi16(bytes, _mm_setzero_si128()); __m128 floats = _mm_cvtepi32_ps(ints); floats = _mm_mul_ps(floats, _mm_set1_ps(SW_INV_255)); _mm_storeu_ps(dst, floats); +#elif defined(SW_HAS_RVV) + // TODO: Sample code generated by AI, needs testing and review + size_t vl = vsetvl_e8m1(4); // Set vector length for 8-bit input elements + vuint8m1_t vsrc_u8 = vle8_v_u8m1(src, vl); // Load 4 unsigned 8-bit integers + vuint32m1_t vsrc_u32 = vwcvt_xu_u_v_u32m1(vsrc_u8, vl); // Widen to 32-bit unsigned integers + vfloat32m1_t vsrc_f32 = vfcvt_f_xu_v_f32m1(vsrc_u32, vl); // Convert to float32 + vfloat32m1_t vnorm = vfmul_vf_f32m1(vsrc_f32, SW_INV_255, vl); // Multiply by 1/255.0 to normalize + vse32_v_f32m1(dst, vnorm, vl); // Store result #else dst[0] = (float)src[0]*SW_INV_255; dst[1] = (float)src[1]*SW_INV_255; @@ -2672,8 +2706,8 @@ static inline void FUNC_NAME(void) float ySubstep = 1.0f - sw_fract(v0->screen[1]); \ \ /* Calculation of vertex gradients in X and Y */ \ - float dUdx, dVdx; \ - float dUdy, dVdy; \ + float dUdx = 0.0f, dVdx = 0.0f; \ + float dUdy = 0.0f, dVdy = 0.0f; \ if (ENABLE_TEXTURE) { \ dUdx = (v1->texcoord[0] - v0->texcoord[0])*wRcp; \ dVdx = (v1->texcoord[1] - v0->texcoord[1])*wRcp; \ From a844a943b5c89fc7c1bef550bd24cd5109649fa7 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Oct 2025 20:45:21 +0100 Subject: [PATCH 034/189] It seems alignas() is C11 and raylib is C99, so not fully supported #5312 Added a workaround but it has other probably undesired implications --- src/external/rlsw.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index cfb2d236f..6f59bba95 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -610,11 +610,19 @@ SWAPI void swBindTexture(uint32_t id); #define RLSW_IMPLEMENTATION #if defined(RLSW_IMPLEMENTATION) -#include #include #include #include // Required for: floorf(), fabsf() +#if defined(_MSC_VER) + #define ALIGNAS(x) __declspec(align(x)) +#elif defined(__GNUC__) || defined(__clang__) + #define ALIGNAS(x) __attribute__((aligned(x))) +#else + #include + #define ALIGNAS(x) alignas(x) +#endif + #if defined(__FMA__) && defined(__AVX2__) #define SW_HAS_FMA_AVX2 #include @@ -687,8 +695,8 @@ SWAPI void swBindTexture(uint32_t id); #define SW_DEG2RAD (SW_PI/180.0f) #define SW_RAD2DEG (180.0f/SW_PI) -#define SW_COLOR_PIXEL_SIZE (SW_COLOR_BUFFER_BITS/8) -#define SW_DEPTH_PIXEL_SIZE (SW_DEPTH_BUFFER_BITS/8) +#define SW_COLOR_PIXEL_SIZE 4 //(SW_COLOR_BUFFER_BITS >> 3) +#define SW_DEPTH_PIXEL_SIZE (SW_DEPTH_BUFFER_BITS >> 3) #if (SW_COLOR_BUFFER_BITS == 8) #define SW_COLOR_TYPE uint8_t @@ -817,14 +825,15 @@ typedef struct { float ty; // Texel height } sw_texture_t; -typedef struct { - alignas(SW_COLOR_PIXEL_SIZE) +// Pixel data type +// WARNING: ALIGNAS() macro requires a constant value (not operand) +typedef ALIGNAS(SW_COLOR_PIXEL_SIZE) struct { SW_COLOR_TYPE color[SW_COLOR_PACK_COMP]; SW_DEPTH_TYPE depth[SW_DEPTH_PACK_COMP]; } sw_pixel_t; typedef struct { - sw_pixel_t* pixels; + sw_pixel_t *pixels; int width; int height; int allocSz; From bf5c00f7e063ee0d236a48a9ba2be799d84c8b4c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Oct 2025 20:57:31 +0100 Subject: [PATCH 035/189] RE-ADDED: `swGetColorBuffer()` for convenience #5312 `PLATFORM_DRM` depends on it but if there is a better approach to get the buffer, it can just be removed again and replaced by alternative. --- src/external/rlsw.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 6f59bba95..f6c15ee1d 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -531,6 +531,7 @@ SWAPI void swClose(void); SWAPI bool swResizeFramebuffer(int w, int h); SWAPI void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, void *pixels); SWAPI void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySrc, int wSrc, int hSrc, SWformat format, SWtype type, void *pixels); +SWAPI void *swGetColorBuffer(int *w, int *h); SWAPI void swEnable(SWstate state); SWAPI void swDisable(SWstate state); @@ -3695,6 +3696,14 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr } } +void *swGetColorBuffer(int *w, int *h) +{ + if (w) *w = RLSW.framebuffer.width; + if (h) *h = RLSW.framebuffer.height; + + return (void *)RLSW.framebuffer.pixels->color; +} + void swEnable(SWstate state) { switch (state) From cbff0fa22c9b9eb9662971731c4cee2c6898661a Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Tue, 28 Oct 2025 23:50:04 +0100 Subject: [PATCH 036/189] [rlsw] Fix axis aligned quad detection (#5314) * fix `sw_quad_is_axis_aligned` * align fix * remove swGetColorBuffer and tweak DRM * review alignment --- src/external/rlsw.h | 96 +++++++++++++++++++++++++-------------- src/platforms/rcore_drm.c | 21 +-------- 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index f6c15ee1d..78ff3fa59 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -531,7 +531,6 @@ SWAPI void swClose(void); SWAPI bool swResizeFramebuffer(int w, int h); SWAPI void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, void *pixels); SWAPI void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySrc, int wSrc, int hSrc, SWformat format, SWtype type, void *pixels); -SWAPI void *swGetColorBuffer(int *w, int *h); SWAPI void swEnable(SWstate state); SWAPI void swDisable(SWstate state); @@ -616,12 +615,23 @@ SWAPI void swBindTexture(uint32_t id); #include // Required for: floorf(), fabsf() #if defined(_MSC_VER) - #define ALIGNAS(x) __declspec(align(x)) + #define SW_ALIGN(x) __declspec(align(x)) #elif defined(__GNUC__) || defined(__clang__) - #define ALIGNAS(x) __attribute__((aligned(x))) + #define SW_ALIGN(x) __attribute__((aligned(x))) #else - #include - #define ALIGNAS(x) alignas(x) + #define SW_ALIGN(x) // Do nothing if not available +#endif + +#if defined(_M_X64) || defined(__x86_64__) + #define SW_ARCH_X86_64 +#elif defined(_M_IX86) || defined(__i386__) + #define SW_ARCH_X86 +#elif defined(_M_ARM) || defined(__arm__) + #define SW_ARCH_ARM32 +#elif defined(_M_ARM64) || defined(__aarch64__) + #define SW_ARCH_ARM64 +#elif defined(__riscv) + #define SW_ARCH_RISCV #endif #if defined(__FMA__) && defined(__AVX2__) @@ -696,8 +706,15 @@ SWAPI void swBindTexture(uint32_t id); #define SW_DEG2RAD (SW_PI/180.0f) #define SW_RAD2DEG (180.0f/SW_PI) -#define SW_COLOR_PIXEL_SIZE 4 //(SW_COLOR_BUFFER_BITS >> 3) +#define SW_COLOR_PIXEL_SIZE (SW_COLOR_BUFFER_BITS >> 3) #define SW_DEPTH_PIXEL_SIZE (SW_DEPTH_BUFFER_BITS >> 3) +#define SW_PIXEL_SIZE (SW_COLOR_PIXEL_SIZE + SW_DEPTH_PIXEL_SIZE) + +#if (SW_PIXEL_SIZE <= 4) + #define SW_PIXEL_ALIGNMENT 4 +#else // if (SW_PIXEL_SIZE <= 8) + #define SW_PIXEL_ALIGNMENT 8 +#endif #if (SW_COLOR_BUFFER_BITS == 8) #define SW_COLOR_TYPE uint8_t @@ -827,10 +844,12 @@ typedef struct { } sw_texture_t; // Pixel data type -// WARNING: ALIGNAS() macro requires a constant value (not operand) -typedef ALIGNAS(SW_COLOR_PIXEL_SIZE) struct { +typedef SW_ALIGN(SW_PIXEL_ALIGNMENT) struct { SW_COLOR_TYPE color[SW_COLOR_PACK_COMP]; SW_DEPTH_TYPE depth[SW_DEPTH_PACK_COMP]; +#if (SW_PIXEL_SIZE % SW_PIXEL_ALIGNMENT != 0) + uint8_t padding[SW_PIXEL_ALIGNMENT - SW_PIXEL_SIZE % SW_PIXEL_ALIGNMENT]; +#endif } sw_pixel_t; typedef struct { @@ -2624,25 +2643,38 @@ static inline void sw_quad_clip_and_project(void) static inline bool sw_quad_is_axis_aligned(void) { - int horizontal = 0; - int vertical = 0; - + // Reject quads with perspective projection + // The fast path assumes affine (non-perspective) quads, + // so we require 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; - - const float *v0 = RLSW.vertexBuffer[i].position; - const float *v1 = RLSW.vertexBuffer[(i + 1)%4].position; - - float dx = v1[0] - v0[0]; - float dy = v1[1] - v0[1]; - - if ((fabsf(dx) > 1e-6f) && (fabsf(dy) < 1e-6f)) horizontal++; - else if ((fabsf(dy) > 1e-6f) && (fabsf(dx) < 1e-6f)) vertical++; - else return false; // Diagonal edge -> not axis-aligned } - return ((horizontal == 2) && (vertical == 2)); + // Epsilon tolerance in screen space (pixels) + const float epsilon = 0.5f; + + // Fetch screen-space positions for the four quad vertices + const float *p0 = RLSW.vertexBuffer[0].screen; + const float *p1 = RLSW.vertexBuffer[1].screen; + const float *p2 = RLSW.vertexBuffer[2].screen; + const float *p3 = RLSW.vertexBuffer[3].screen; + + // Compute edge vectors between consecutive vertices + // These define the four sides of the quad in screen space + float dx01 = p1[0] - p0[0], dy01 = p1[1] - p0[1]; + float dx12 = p2[0] - p1[0], dy12 = p2[1] - p1[1]; + float dx23 = p3[0] - p2[0], dy23 = p3[1] - p2[1]; + float dx30 = p0[0] - p3[0], dy30 = p0[1] - p3[1]; + + // Each edge must be either horizontal or vertical within epsilon tolerance + // If any edge deviates significantly from either axis, the quad is not axis-aligned + if (!((fabsf(dy01) < epsilon) || (fabsf(dx01) < epsilon))) return false; + if (!((fabsf(dy12) < epsilon) || (fabsf(dx12) < epsilon))) return false; + if (!((fabsf(dy23) < epsilon) || (fabsf(dx23) < epsilon))) return false; + if (!((fabsf(dy30) < epsilon) || (fabsf(dx30) < epsilon))) return false; + + return true; } static inline void sw_quad_sort_cw(const sw_vertex_t* *output) @@ -3660,11 +3692,6 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr { sw_pixelformat_t pFormat = (sw_pixelformat_t)sw_get_pixel_format(format, type); - if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc) - { - swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels); - } - if (wSrc <= 0) { RLSW.errCode = SW_INVALID_VALUE; return; } if (hSrc <= 0) { RLSW.errCode = SW_INVALID_VALUE; return; } @@ -3674,6 +3701,13 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr xSrc = sw_clampi(xSrc, 0, wSrc); 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 + if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc) + { + swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels); + } + switch (pFormat) { case SW_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: sw_framebuffer_blit_to_GRAYALPHA(xDst, yDst, wDst, hDst, xSrc, ySrc, wSrc, hSrc, (uint8_t *)pixels); break; @@ -3696,14 +3730,6 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr } } -void *swGetColorBuffer(int *w, int *h) -{ - if (w) *w = RLSW.framebuffer.width; - if (h) *h = RLSW.framebuffer.height; - - return (void *)RLSW.framebuffer.pixels->color; -} - void swEnable(SWstate state) { switch (state) diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index a08a76bce..da0d08aca 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -824,15 +824,6 @@ void SwapScreenBuffer(void) return; } - // Get the software rendered color buffer - int bufferWidth = 0, bufferHeight = 0; - void *colorBuffer = swGetColorBuffer(&bufferWidth, &bufferHeight); - if (!colorBuffer) - { - TRACELOG(LOG_ERROR, "DISPLAY: Failed to get software color buffer"); - return; - } - // Retrieving the dimensions of the display mode used drmModeModeInfo *mode = &platform.connector->modes[platform.modeIndex]; uint32_t width = mode->hdisplay; @@ -900,16 +891,8 @@ void SwapScreenBuffer(void) } // Copy the software rendered buffer to the dumb buffer with scaling if needed - if (bufferWidth == width && bufferHeight == height) - { - // Direct copy if sizes match - swCopyFramebuffer(0, 0, bufferWidth, bufferHeight, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer); - } - else - { - // Scale the software buffer to match the display mode - swBlitFramebuffer(0, 0, width, height, 0, 0, bufferWidth, bufferHeight, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer); - } + // NOTE: RLSW will make a simple copy if the dimensions match + swBlitFramebuffer(0, 0, width, height, 0, 0, width, height, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer); // Unmap the buffer munmap(dumbBuffer, creq.size); From f16d5ce1ddb0b0a447a30ef02d6a5a76d6fea4e2 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 29 Oct 2025 11:12:04 +0100 Subject: [PATCH 037/189] REVIEWED: Make sure SSE is being used when compiling with MSVC Added log info and some formatting for visibility --- src/external/rlsw.h | 167 ++++++++++++++++++++++++-------------------- 1 file changed, 91 insertions(+), 76 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 78ff3fa59..ab8756e56 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -94,11 +94,9 @@ #ifndef SW_MALLOC #define SW_MALLOC(sz) malloc(sz) #endif - #ifndef SW_REALLOC #define SW_REALLOC(ptr, newSz) realloc(ptr, newSz) #endif - #ifndef SW_FREE #define SW_FREE(ptr) free(ptr) #endif @@ -152,12 +150,6 @@ #define SW_CLIP_EPSILON 1e-4f #endif -#ifdef __cplusplus - #define CURLY_INIT(name) name -#else - #define CURLY_INIT(name) (name) -#endif - //---------------------------------------------------------------------------------- // OpenGL Compatibility Types //---------------------------------------------------------------------------------- @@ -610,9 +602,19 @@ SWAPI void swBindTexture(uint32_t id); #define RLSW_IMPLEMENTATION #if defined(RLSW_IMPLEMENTATION) -#include -#include -#include // Required for: floorf(), fabsf() +#include // Required for: malloc(), free() +#include // Required for: NULL, size_t, uint8_t, uint16_t, uint32_t... +#include // Required for: sinf(), cosf(), floorf(), fabsf(), sqrtf(), roundf() + +// Simple log system to avoid printf() calls if required +// NOTE: Avoiding those calls, also avoids const strings memory usage +#define SW_SUPPORT_LOG_INFO +#if defined(SW_SUPPORT_LOG_INFO) //&& defined(_DEBUG) // WARNING: LOG() output required for this tool + #include + #define SW_LOG(...) printf(__VA_ARGS__) +#else + #define SW_LOG(...) +#endif #if defined(_MSC_VER) #define SW_ALIGN(x) __declspec(align(x)) @@ -634,56 +636,47 @@ SWAPI void swBindTexture(uint32_t id); #define SW_ARCH_RISCV #endif +// Check for SIMD vector instructions #if defined(__FMA__) && defined(__AVX2__) #define SW_HAS_FMA_AVX2 #include #endif - #if defined(__FMA__) && defined(__AVX__) #define SW_HAS_FMA_AVX #include #endif - #if defined(__AVX2__) #define SW_HAS_AVX2 #include #endif - #if defined(__AVX__) #define SW_HAS_AVX #include #endif - #if defined(__SSE4_2__) #define SW_HAS_SSE42 #include #endif - #if defined(__SSE4_1__) #define SW_HAS_SSE41 #include #endif - #if defined(__SSSE3__) #define SW_HAS_SSSE3 #include #endif - #if defined(__SSE3__) #define SW_HAS_SSE3 #include #endif - -#if defined(__SSE2__) +#if defined(__SSE2__) || (defined(_M_AMD64) || defined(_M_X64)) // SSE2 x64 #define SW_HAS_SSE2 #include #endif - #if defined(__SSE__) #define SW_HAS_SSE #include #endif - #if defined(__ARM_NEON) || defined(__aarch64__) #if defined(__ARM_FEATURE_FMA) #define SW_HAS_NEON_FMA @@ -692,12 +685,17 @@ SWAPI void swBindTexture(uint32_t id); #endif #include #endif - -#ifdef __riscv_vector +#if defined(__riscv_vector) #define SW_HAS_RVV #include #endif +#ifdef __cplusplus + #define SW_CURLY_INIT(name) name +#else + #define SW_CURLY_INIT(name) (name) +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -717,68 +715,68 @@ SWAPI void swBindTexture(uint32_t id); #endif #if (SW_COLOR_BUFFER_BITS == 8) - #define SW_COLOR_TYPE uint8_t - #define SW_COLOR_IS_PACKED 1 - #define SW_COLOR_PACK_COMP 1 + #define SW_COLOR_TYPE uint8_t + #define SW_COLOR_IS_PACKED 1 + #define SW_COLOR_PACK_COMP 1 #define SW_PACK_COLOR(r,g,b) ((((uint8_t)((r)*7+0.5f))&0x07)<<5 | (((uint8_t)((g)*7+0.5f))&0x07)<<2 | ((uint8_t)((b)*3+0.5f))&0x03) - #define SW_UNPACK_R(p) (((p)>>5)&0x07) - #define SW_UNPACK_G(p) (((p)>>2)&0x07) - #define SW_UNPACK_B(p) ((p)&0x03) - #define SW_SCALE_R(v) ((v)*255+3)/7 - #define SW_SCALE_G(v) ((v)*255+3)/7 - #define SW_SCALE_B(v) ((v)*255+1)/3 - #define SW_TO_FLOAT_R(v) ((v)*(1.0f/7.0f)) - #define SW_TO_FLOAT_G(v) ((v)*(1.0f/7.0f)) - #define SW_TO_FLOAT_B(v) ((v)*(1.0f/3.0f)) + #define SW_UNPACK_R(p) (((p)>>5)&0x07) + #define SW_UNPACK_G(p) (((p)>>2)&0x07) + #define SW_UNPACK_B(p) ((p)&0x03) + #define SW_SCALE_R(v) ((v)*255+3)/7 + #define SW_SCALE_G(v) ((v)*255+3)/7 + #define SW_SCALE_B(v) ((v)*255+1)/3 + #define SW_TO_FLOAT_R(v) ((v)*(1.0f/7.0f)) + #define SW_TO_FLOAT_G(v) ((v)*(1.0f/7.0f)) + #define SW_TO_FLOAT_B(v) ((v)*(1.0f/3.0f)) #elif (SW_COLOR_BUFFER_BITS == 16) - #define SW_COLOR_TYPE uint16_t - #define SW_COLOR_IS_PACKED 1 - #define SW_COLOR_PACK_COMP 1 + #define SW_COLOR_TYPE uint16_t + #define SW_COLOR_IS_PACKED 1 + #define SW_COLOR_PACK_COMP 1 #define SW_PACK_COLOR(r,g,b) ((((uint16_t)((r)*31+0.5f))&0x1F)<<11 | (((uint16_t)((g)*63+0.5f))&0x3F)<<5 | ((uint16_t)((b)*31+0.5f))&0x1F) - #define SW_UNPACK_R(p) (((p)>>11)&0x1F) - #define SW_UNPACK_G(p) (((p)>>5)&0x3F) - #define SW_UNPACK_B(p) ((p)&0x1F) - #define SW_SCALE_R(v) ((v)*255+15)/31 - #define SW_SCALE_G(v) ((v)*255+31)/63 - #define SW_SCALE_B(v) ((v)*255+15)/31 - #define SW_TO_FLOAT_R(v) ((v)*(1.0f/31.0f)) - #define SW_TO_FLOAT_G(v) ((v)*(1.0f/63.0f)) - #define SW_TO_FLOAT_B(v) ((v)*(1.0f/31.0f)) + #define SW_UNPACK_R(p) (((p)>>11)&0x1F) + #define SW_UNPACK_G(p) (((p)>>5)&0x3F) + #define SW_UNPACK_B(p) ((p)&0x1F) + #define SW_SCALE_R(v) ((v)*255+15)/31 + #define SW_SCALE_G(v) ((v)*255+31)/63 + #define SW_SCALE_B(v) ((v)*255+15)/31 + #define SW_TO_FLOAT_R(v) ((v)*(1.0f/31.0f)) + #define SW_TO_FLOAT_G(v) ((v)*(1.0f/63.0f)) + #define SW_TO_FLOAT_B(v) ((v)*(1.0f/31.0f)) #else // 32 bits - #define SW_COLOR_TYPE uint8_t - #define SW_COLOR_IS_PACKED 0 - #define SW_COLOR_PACK_COMP 4 + #define SW_COLOR_TYPE uint8_t + #define SW_COLOR_IS_PACKED 0 + #define SW_COLOR_PACK_COMP 4 #endif #if (SW_DEPTH_BUFFER_BITS == 8) - #define SW_DEPTH_TYPE uint8_t - #define SW_DEPTH_IS_PACKED 1 - #define SW_DEPTH_PACK_COMP 1 - #define SW_DEPTH_MAX UINT8_MAX - #define SW_DEPTH_SCALE (1.0f/UINT8_MAX) - #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) - #define SW_UNPACK_DEPTH(p) (p) + #define SW_DEPTH_TYPE uint8_t + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX UINT8_MAX + #define SW_DEPTH_SCALE (1.0f/UINT8_MAX) + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) + #define SW_UNPACK_DEPTH(p) (p) #elif (SW_DEPTH_BUFFER_BITS == 16) - #define SW_DEPTH_TYPE uint16_t - #define SW_DEPTH_IS_PACKED 1 - #define SW_DEPTH_PACK_COMP 1 - #define SW_DEPTH_MAX UINT16_MAX - #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) - #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) - #define SW_UNPACK_DEPTH(p) (p) + #define SW_DEPTH_TYPE uint16_t + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX UINT16_MAX + #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) + #define SW_UNPACK_DEPTH(p) (p) #else // 24 bits - #define SW_DEPTH_TYPE uint8_t - #define SW_DEPTH_IS_PACKED 0 - #define SW_DEPTH_PACK_COMP 3 - #define SW_DEPTH_MAX 0xFFFFFF - #define SW_DEPTH_SCALE (1.0f/0xFFFFFF) - #define SW_PACK_DEPTH_0(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFF) - #define SW_PACK_DEPTH_1(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFF) - #define SW_PACK_DEPTH_2(d) ((uint32_t)((d)*SW_DEPTH_MAX)&0xFF) - #define SW_UNPACK_DEPTH(p) (((p)[0]<<16)|((p)[1]<<8)|(p)[2]) + #define SW_DEPTH_TYPE uint8_t + #define SW_DEPTH_IS_PACKED 0 + #define SW_DEPTH_PACK_COMP 3 + #define SW_DEPTH_MAX 0xFFFFFF + #define SW_DEPTH_SCALE (1.0f/0xFFFFFF) + #define SW_PACK_DEPTH_0(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFF) + #define SW_PACK_DEPTH_1(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFF) + #define SW_PACK_DEPTH_2(d) ((uint32_t)((d)*SW_DEPTH_MAX)&0xFF) + #define SW_UNPACK_DEPTH(p) (((p)[0]<<16)|((p)[1]<<8)|(p)[2]) #endif -#define SW_STATE_CHECK(flags) (SW_STATE_CHECK_EX(RLSW.stateFlags, (flags))) +#define SW_STATE_CHECK(flags) (SW_STATE_CHECK_EX(RLSW.stateFlags, (flags))) #define SW_STATE_CHECK_EX(state, flags) (((state) & (flags)) == (flags)) #define SW_STATE_SCISSOR_TEST (1 << 0) @@ -3607,6 +3605,23 @@ bool swInit(int w, int h) RLSW.loadedTextures[0].ty = 0.5f; RLSW.loadedTextureCount = 1; + + SW_LOG("INFO: RLSW: Software renderer initialized successfully\n"); +#if defined(SW_HAS_FMA_AVX) && defined(SW_HAS_FMA_AVX2) + SW_LOG("INFO: RLSW: Using SIMD instructions: FMA AVX\n"); +#endif +#if defined(SW_HAS_AVX) || defined(SW_HAS_AVX2) + SW_LOG("INFO: RLSW: Using SIMD instructions: AVX\n"); +#endif +#if defined(SW_HAS_SSE) || defined(SW_HAS_SSE2) || defined(SW_HAS_SSE3) || defined(SW_HAS_SSE41) || defined(SW_HAS_SSE42) + SW_LOG("INFO: RLSW: Using SIMD instructions: SSE\n"); +#endif +#if defined(SW_HAS_NEON_FMA) || defined(SW_HAS_NEON) + SW_LOG("INFO: RLSW: Using SIMD instructions: NEON\n"); +#endif +#if defined(SW_HAS_RVV) + SW_LOG("INFO: RLSW: Using SIMD instructions: RVV\n"); +#endif return true; } @@ -3626,7 +3641,7 @@ void swClose(void) SW_FREE(RLSW.loadedTextures); SW_FREE(RLSW.freeTextureIds); - RLSW = CURLY_INIT(sw_context_t) { 0 }; + RLSW = SW_CURLY_INIT(sw_context_t) { 0 }; } bool swResizeFramebuffer(int w, int h) From 3389c80f498307a7546d868f7a9fcf18d23c65ae Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 29 Oct 2025 11:33:08 +0100 Subject: [PATCH 038/189] Update rlsw.h --- src/external/rlsw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index ab8756e56..f102c3efd 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -3613,7 +3613,7 @@ bool swInit(int w, int h) #if defined(SW_HAS_AVX) || defined(SW_HAS_AVX2) SW_LOG("INFO: RLSW: Using SIMD instructions: AVX\n"); #endif -#if defined(SW_HAS_SSE) || defined(SW_HAS_SSE2) || defined(SW_HAS_SSE3) || defined(SW_HAS_SSE41) || defined(SW_HAS_SSE42) +#if defined(SW_HAS_SSE) || defined(SW_HAS_SSE2) || defined(SW_HAS_SSE3) || defined(SW_HAS_SSSE3) || defined(SW_HAS_SSE41) || defined(SW_HAS_SSE42) SW_LOG("INFO: RLSW: Using SIMD instructions: SSE\n"); #endif #if defined(SW_HAS_NEON_FMA) || defined(SW_HAS_NEON) From 127cc1c79ee93f957907f7824eee75ac00dde095 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 29 Oct 2025 22:45:37 +0100 Subject: [PATCH 039/189] REVIEWED: Makefile to support software renderer --- examples/Makefile | 14 +++++++++++++- src/Makefile | 13 +++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index c8500b665..b5e968079 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -486,7 +486,19 @@ endif ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) # Libraries for DRM compiling # NOTE: Required packages: libasound2-dev (ALSA) - LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic + LDLIBS = -lraylib -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl -latomic + # TODO: Examples compilation does not define GRAPHICS, is it required? + #ifeq ($(GRAPHICS),GRAPHICS_API_OPENGL_ES2) + # LDLIBS += -lGLESv2 -lEGL + #endif +endif +ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32) + # Libraries for Windows desktop compilation + LDFLAGS += -L..\src + LDLIBS = -lraylib -lgdi32 -lwinmm -lshcore + ifneq ($(GRAPHICS),GRAPHICS_API_OPENGL_11_SOFTWARE) + LDLIBS += -lopengl32 + endif endif ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # Libraries for web (HTML5) compiling diff --git a/src/Makefile b/src/Makefile index 0895d8f95..41867da1c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -228,7 +228,6 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) ifeq ($(ANDROID_ARCH),x86_64) ANDROID_COMPILER_ARCH = x86_64 endif - endif # Define raylib graphics api depending on selected platform @@ -261,8 +260,8 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32) #GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE) endif ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) - # On DRM OpenGL ES 2.0 must be used GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 + #GRAPHICS = GRAPHICS_API_OPENGL_11_SOFTWARE # Uncomment to use software rendering endif ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) # On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0 @@ -636,13 +635,19 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW) endif endif ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) - LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl + LDLIBS = -ldrm -lgbm -lpthread -lrt -lm -ldl + ifeq ($(GRAPHICS),GRAPHICS_API_OPENGL_ES2) + LDLIBS += -lGLESv2 -lEGL + endif ifeq ($(RAYLIB_MODULE_AUDIO),TRUE) LDLIBS += -latomic endif endif ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32) - LDLIBS = -lgdi32 -lwinmm -lopengl32 -lshcore + LDLIBS = -lgdi32 -lwinmm -lshcore + ifneq ($(GRAPHICS),GRAPHICS_API_OPENGL_11_SOFTWARE) + LDLIBS += -lopengl32 + endif endif ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -lc -lm From b2d455400c3946461943902e2b071eaf49407111 Mon Sep 17 00:00:00 2001 From: Dave Goehrig Date: Thu, 30 Oct 2025 19:15:14 +0100 Subject: [PATCH 040/189] Adding SwiftForth language binding (#5319) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index 7770f41c2..f2ffaea9e 100644 --- a/BINDINGS.md +++ b/BINDINGS.md @@ -31,6 +31,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers | [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 | | [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD | | [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT | +| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib | | [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC | | [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib | | [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib | From bca54047f9bb735e9fbc3173674a9c1e6503a708 Mon Sep 17 00:00:00 2001 From: Le Juez Victor <90587919+Bigfoot71@users.noreply.github.com> Date: Thu, 30 Oct 2025 19:17:18 +0100 Subject: [PATCH 041/189] [rlsw] Review depth formats and fix depth writing (#5317) * review depth format/writing * adding a note --- src/external/rlsw.h | 58 +++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index f102c3efd..9c510e945 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -114,11 +114,11 @@ #endif #ifndef SW_COLOR_BUFFER_BITS - #define SW_COLOR_BUFFER_BITS 32 //< 32 (rgba), 16 (rgb packed) or 8 (rgb packed) + #define SW_COLOR_BUFFER_BITS 32 //< 32 (rgba), 16 (rgb packed) or 8 (rgb packed) #endif #ifndef SW_DEPTH_BUFFER_BITS - #define SW_DEPTH_BUFFER_BITS 16 //< 24, 16 or 8 + #define SW_DEPTH_BUFFER_BITS 16 //< 32, 24 or 16 #endif #ifndef SW_MAX_PROJECTION_STACK_SIZE @@ -748,32 +748,32 @@ SWAPI void swBindTexture(uint32_t id); #define SW_COLOR_PACK_COMP 4 #endif -#if (SW_DEPTH_BUFFER_BITS == 8) - #define SW_DEPTH_TYPE uint8_t - #define SW_DEPTH_IS_PACKED 1 - #define SW_DEPTH_PACK_COMP 1 - #define SW_DEPTH_MAX UINT8_MAX - #define SW_DEPTH_SCALE (1.0f/UINT8_MAX) - #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) - #define SW_UNPACK_DEPTH(p) (p) -#elif (SW_DEPTH_BUFFER_BITS == 16) - #define SW_DEPTH_TYPE uint16_t - #define SW_DEPTH_IS_PACKED 1 - #define SW_DEPTH_PACK_COMP 1 - #define SW_DEPTH_MAX UINT16_MAX - #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) - #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) - #define SW_UNPACK_DEPTH(p) (p) -#else // 24 bits - #define SW_DEPTH_TYPE uint8_t - #define SW_DEPTH_IS_PACKED 0 - #define SW_DEPTH_PACK_COMP 3 - #define SW_DEPTH_MAX 0xFFFFFF - #define SW_DEPTH_SCALE (1.0f/0xFFFFFF) - #define SW_PACK_DEPTH_0(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFF) - #define SW_PACK_DEPTH_1(d) (((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFF) - #define SW_PACK_DEPTH_2(d) ((uint32_t)((d)*SW_DEPTH_MAX)&0xFF) - #define SW_UNPACK_DEPTH(p) (((p)[0]<<16)|((p)[1]<<8)|(p)[2]) +#if (SW_DEPTH_BUFFER_BITS == 16) + #define SW_DEPTH_TYPE uint16_t + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX UINT16_MAX + #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) + #define SW_UNPACK_DEPTH(p) (p) +#elif (SW_DEPTH_BUFFER_BITS == 24) + #define SW_DEPTH_TYPE uint8_t + #define SW_DEPTH_IS_PACKED 0 + #define SW_DEPTH_PACK_COMP 3 + #define SW_DEPTH_MAX 0xFFFFFFU + #define SW_DEPTH_SCALE (1.0f/0xFFFFFFU) + #define SW_PACK_DEPTH_0(d) ((uint8_t)(((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFFU)) + #define SW_PACK_DEPTH_1(d) ((uint8_t)(((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFFU)) + #define SW_PACK_DEPTH_2(d) ((uint8_t)((uint32_t)((d)*SW_DEPTH_MAX)&0xFFU)) + #define SW_UNPACK_DEPTH(p) ((((uint32_t)(p)[0]<<16)|((uint32_t)(p)[1]<<8)|(uint32_t)(p)[2])) +#else // 32 bits + #define SW_DEPTH_TYPE float + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX 1.0f + #define SW_DEPTH_SCALE 1.0f + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)(d)) + #define SW_UNPACK_DEPTH(p) (p) #endif #define SW_STATE_CHECK(flags) (SW_STATE_CHECK_EX(RLSW.stateFlags, (flags))) @@ -1346,6 +1346,8 @@ static inline void sw_framebuffer_write_color(sw_pixel_t *dst, const float src[4 static inline void sw_framebuffer_write_depth(sw_pixel_t *dst, float depth) { + depth = sw_saturate(depth); // REVIEW: An overflow can occur in certain circumstances with clipping, and needs to be reviewed... + #if SW_DEPTH_IS_PACKED dst->depth[0] = SW_PACK_DEPTH(depth); #else From dfc94f64d1e1db5231a68e8ea968378df16f2292 Mon Sep 17 00:00:00 2001 From: Arrangemonk <34814431+Arrangemonk@users.noreply.github.com> Date: Fri, 31 Oct 2025 20:43:27 +0100 Subject: [PATCH 042/189] =?UTF-8?q?Revert=20"UpdateModelAnimation=20does?= =?UTF-8?q?=20matrixtranspose(matrixinvert)=20only=20once=20per=E2=80=A6"?= =?UTF-8?q?=20(#5322)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e3a562ab57a9fa4a9dbaa3d5ffb67f31c25a4a36. --- src/rmodels.c | 79 ++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index 3c904c396..ed86fb19a 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -2352,8 +2352,6 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) Mesh mesh = model.meshes[m]; Vector3 animVertex = { 0 }; Vector3 animNormal = { 0 }; - Matrix boneMatrix = { 0 }; - Matrix InverseBoneMatrix = { 0 }; int boneId = 0; int boneCounter = 0; float boneWeight = 0.0; @@ -2361,50 +2359,47 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame) const int vValues = mesh.vertexCount*3; // Skip if missing bone data, causes segfault without on some models - if ((mesh.boneWeights == NULL) || (mesh.boneIds == NULL)) continue; + if ((mesh.boneWeights == NULL) || (mesh.boneIds == NULL)) continue; - // Iterates over 4 bones per vertex - for (int j = 0; j < 4; j++, boneCounter++) - { - boneWeight = mesh.boneWeights[boneCounter]; - boneId = mesh.boneIds[boneCounter]; + for (int vCounter = 0; vCounter < vValues; vCounter += 3) + { + mesh.animVertices[vCounter] = 0; + mesh.animVertices[vCounter + 1] = 0; + mesh.animVertices[vCounter + 2] = 0; + if (mesh.animNormals != NULL) + { + mesh.animNormals[vCounter] = 0; + mesh.animNormals[vCounter + 1] = 0; + mesh.animNormals[vCounter + 2] = 0; + } - // Early stop when no transformation will be applied - if (boneWeight == 0.0f) continue; + // Iterates over 4 bones per vertex + for (int j = 0; j < 4; j++, boneCounter++) + { + boneWeight = mesh.boneWeights[boneCounter]; + boneId = mesh.boneIds[boneCounter]; - boneMatrix = model.meshes[m].boneMatrices[boneId]; - InverseBoneMatrix = MatrixTranspose(MatrixInvert(boneMatrix)); + // Early stop when no transformation will be applied + if (boneWeight == 0.0f) continue; + animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] }; + animVertex = Vector3Transform(animVertex,model.meshes[m].boneMatrices[boneId]); + mesh.animVertices[vCounter] += animVertex.x*boneWeight; + mesh.animVertices[vCounter+1] += animVertex.y*boneWeight; + mesh.animVertices[vCounter+2] += animVertex.z*boneWeight; + updated = true; - for (int vCounter = 0; vCounter < vValues; vCounter += 3) - { - mesh.animVertices[vCounter] = 0; - mesh.animVertices[vCounter + 1] = 0; - mesh.animVertices[vCounter + 2] = 0; - if (mesh.animNormals != NULL) - { - mesh.animNormals[vCounter] = 0; - mesh.animNormals[vCounter + 1] = 0; - mesh.animNormals[vCounter + 2] = 0; - } - animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] }; - animVertex = Vector3Transform(animVertex, boneMatrix); - mesh.animVertices[vCounter] += animVertex.x*boneWeight; - mesh.animVertices[vCounter+1] += animVertex.y*boneWeight; - mesh.animVertices[vCounter+2] += animVertex.z*boneWeight; - updated = true; - - // Normals processing - // NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals) - if ((mesh.normals != NULL) && (mesh.animNormals != NULL)) - { - animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] }; - animNormal = Vector3Transform(animNormal, InverseBoneMatrix); - mesh.animNormals[vCounter] += animNormal.x*boneWeight; - mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight; - mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight; - } - } - } + // Normals processing + // NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals) + if ((mesh.normals != NULL) && (mesh.animNormals != NULL )) + { + animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] }; + animNormal = Vector3Transform(animNormal, MatrixTranspose(MatrixInvert(model.meshes[m].boneMatrices[boneId]))); + mesh.animNormals[vCounter] += animNormal.x*boneWeight; + mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight; + mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight; + } + } + } if (updated) { From 02466212100344b00bb3c9d438d2236144070aac Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 1 Nov 2025 21:06:18 +0100 Subject: [PATCH 043/189] REVIEWED: SIMD intrinsics checks and usage --- src/external/rlsw.h | 192 +++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 92 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 9c510e945..15ab89d4e 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -40,6 +40,14 @@ * 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 RLSW_USE_SIMD_INTRINSICS +* Detect and use SIMD intrinsics on the host compilation platform +* SIMD could improve rendering considerable vectorizing some raster operations +* but the target platforms running the compiled program with SIMD enabled +* must support the SIMD the program has been built for, making them only +* recommended under specific situations and only if the developers know +* what are they doing; this flag is not defined by default +* * rlsw capabilities could be customized just defining some internal * values before library inclusion (default values listed): * @@ -636,59 +644,58 @@ SWAPI void swBindTexture(uint32_t id); #define SW_ARCH_RISCV #endif -// Check for SIMD vector instructions -#if defined(__FMA__) && defined(__AVX2__) - #define SW_HAS_FMA_AVX2 - #include -#endif -#if defined(__FMA__) && defined(__AVX__) - #define SW_HAS_FMA_AVX - #include -#endif -#if defined(__AVX2__) - #define SW_HAS_AVX2 - #include -#endif -#if defined(__AVX__) - #define SW_HAS_AVX - #include -#endif -#if defined(__SSE4_2__) - #define SW_HAS_SSE42 - #include -#endif -#if defined(__SSE4_1__) - #define SW_HAS_SSE41 - #include -#endif -#if defined(__SSSE3__) - #define SW_HAS_SSSE3 - #include -#endif -#if defined(__SSE3__) - #define SW_HAS_SSE3 - #include -#endif -#if defined(__SSE2__) || (defined(_M_AMD64) || defined(_M_X64)) // SSE2 x64 - #define SW_HAS_SSE2 - #include -#endif -#if defined(__SSE__) - #define SW_HAS_SSE - #include -#endif -#if defined(__ARM_NEON) || defined(__aarch64__) - #if defined(__ARM_FEATURE_FMA) - #define SW_HAS_NEON_FMA - #else - #define SW_HAS_NEON +#if defined(RLSW_USE_SIMD_INTRINSICS) + // Check for SIMD vector instructions + // NOTE: Compiler is responsible to enable required flags for host device, + // supported features are detected at compiler init but varies depending on compiler + // TODO: This logic must be reviewed to avoid the inclusion of multiple headers + // and enable the higher level of SIMD available + #if defined(__FMA__) && defined(__AVX2__) + #define SW_HAS_FMA_AVX2 + #include + #elif defined(__FMA__) && defined(__AVX__) + #define SW_HAS_FMA_AVX + #include + #elif defined(__AVX2__) + #define SW_HAS_AVX2 + #include + #elif defined(__AVX__) + #define SW_HAS_AVX + #include #endif - #include -#endif -#if defined(__riscv_vector) - #define SW_HAS_RVV - #include -#endif + #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(__ARM_NEON) || defined(__aarch64__) + #if defined(__ARM_FEATURE_FMA) + #define SW_HAS_NEON_FMA + #else + #define SW_HAS_NEON + #endif + #include + #endif + #if defined(__riscv_vector) + // NOTE: Requires compilation flags: -march=rv64gcv -mabi=lp64d + #define SW_HAS_RVV + #include + #endif +#endif // RLSW_USE_SIMD_INTRINSICS #ifdef __cplusplus #define SW_CURLY_INIT(name) name @@ -749,31 +756,31 @@ SWAPI void swBindTexture(uint32_t id); #endif #if (SW_DEPTH_BUFFER_BITS == 16) - #define SW_DEPTH_TYPE uint16_t - #define SW_DEPTH_IS_PACKED 1 - #define SW_DEPTH_PACK_COMP 1 - #define SW_DEPTH_MAX UINT16_MAX - #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) - #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) - #define SW_UNPACK_DEPTH(p) (p) + #define SW_DEPTH_TYPE uint16_t + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX UINT16_MAX + #define SW_DEPTH_SCALE (1.0f/UINT16_MAX) + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)((d)*SW_DEPTH_MAX)) + #define SW_UNPACK_DEPTH(p) (p) #elif (SW_DEPTH_BUFFER_BITS == 24) - #define SW_DEPTH_TYPE uint8_t - #define SW_DEPTH_IS_PACKED 0 - #define SW_DEPTH_PACK_COMP 3 - #define SW_DEPTH_MAX 0xFFFFFFU - #define SW_DEPTH_SCALE (1.0f/0xFFFFFFU) - #define SW_PACK_DEPTH_0(d) ((uint8_t)(((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFFU)) - #define SW_PACK_DEPTH_1(d) ((uint8_t)(((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFFU)) - #define SW_PACK_DEPTH_2(d) ((uint8_t)((uint32_t)((d)*SW_DEPTH_MAX)&0xFFU)) - #define SW_UNPACK_DEPTH(p) ((((uint32_t)(p)[0]<<16)|((uint32_t)(p)[1]<<8)|(uint32_t)(p)[2])) + #define SW_DEPTH_TYPE uint8_t + #define SW_DEPTH_IS_PACKED 0 + #define SW_DEPTH_PACK_COMP 3 + #define SW_DEPTH_MAX 0xFFFFFFU + #define SW_DEPTH_SCALE (1.0f/0xFFFFFFU) + #define SW_PACK_DEPTH_0(d) ((uint8_t)(((uint32_t)((d)*SW_DEPTH_MAX)>>16)&0xFFU)) + #define SW_PACK_DEPTH_1(d) ((uint8_t)(((uint32_t)((d)*SW_DEPTH_MAX)>>8)&0xFFU)) + #define SW_PACK_DEPTH_2(d) ((uint8_t)((uint32_t)((d)*SW_DEPTH_MAX)&0xFFU)) + #define SW_UNPACK_DEPTH(p) ((((uint32_t)(p)[0]<<16)|((uint32_t)(p)[1]<<8)|(uint32_t)(p)[2])) #else // 32 bits - #define SW_DEPTH_TYPE float - #define SW_DEPTH_IS_PACKED 1 - #define SW_DEPTH_PACK_COMP 1 - #define SW_DEPTH_MAX 1.0f - #define SW_DEPTH_SCALE 1.0f - #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)(d)) - #define SW_UNPACK_DEPTH(p) (p) + #define SW_DEPTH_TYPE float + #define SW_DEPTH_IS_PACKED 1 + #define SW_DEPTH_PACK_COMP 1 + #define SW_DEPTH_MAX 1.0f + #define SW_DEPTH_SCALE 1.0f + #define SW_PACK_DEPTH(d) ((SW_DEPTH_TYPE)(d)) + #define SW_UNPACK_DEPTH(p) (p) #endif #define SW_STATE_CHECK(flags) (SW_STATE_CHECK_EX(RLSW.stateFlags, (flags))) @@ -1136,25 +1143,26 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) *(uint32_t*)dst = _mm_cvtsi128_si32(clamped); #elif defined(SW_HAS_RVV) // TODO: Sample code generated by AI, needs testing and review - size_t vl = vsetvl_e32m1(4); // Load up to 4 floats into a vector register - vfloat32m1_t vsrc = vle32_v_f32m1(src, vl); // Load float32 values + // NOTE: RVV 1.0 specs define the use of __riscv_ prefix for instrinsic functions + size_t vl = __riscv_vsetvl_e32m1(4); // Load up to 4 floats into a vector register + vfloat32m1_t vsrc = __riscv_vle32_v_f32m1(src, vl); // Load float32 values // Clamp to [0.0f, 1.0f] - vfloat32m1_t vzero = vfmv_v_f_f32m1(0.0f, vl); - vfloat32m1_t vone = vfmv_v_f_f32m1(1.0f, vl); - vsrc = vfmin_vv_f32m1(vsrc, vone, vl); - vsrc = vfmax_vv_f32m1(vsrc, vzero, vl); + vfloat32m1_t vzero = __riscv_vfmv_v_f_f32m1(0.0f, vl); + vfloat32m1_t vone = __riscv_vfmv_v_f_f32m1(1.0f, vl); + vsrc = __riscv_vfmin_vv_f32m1(vsrc, vone, vl); + vsrc = __riscv_vfmax_vv_f32m1(vsrc, vzero, vl); // Multiply by 255.0f and add 0.5f for rounding - vfloat32m1_t vscaled = vfmul_vf_f32m1(vsrc, 255.0f, vl); - vscaled = vfadd_vf_f32m1(vscaled, 0.5f, vl); + vfloat32m1_t vscaled = __riscv_vfmul_vf_f32m1(vsrc, 255.0f, vl); + vscaled = __riscv_vfadd_vf_f32m1(vscaled, 0.5f, vl); // Convert to unsigned integer (truncate toward zero) - vuint32m1_t vu32 = vfcvt_xu_f_v_u32m1(vscaled, vl); + vuint32m1_t vu32 = __riscv_vfcvt_xu_f_v_u32m1(vscaled, vl); // Narrow from u32 -> u8 - vuint8m1_t vu8 = vnclipu_wx_u8m1(vu32, 0, vl); // Round toward zero - vse8_v_u8m1(dst, vu8, vl); // Store result + vuint8m1_t vu8 = __riscv_vnclipu_wx_u8m1(vu32, 0, vl); // Round toward zero + __riscv_vse8_v_u8m1(dst, vu8, vl); // Store result #else for (int i = 0; i < 4; i++) { @@ -1190,12 +1198,12 @@ static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) _mm_storeu_ps(dst, floats); #elif defined(SW_HAS_RVV) // TODO: Sample code generated by AI, needs testing and review - size_t vl = vsetvl_e8m1(4); // Set vector length for 8-bit input elements - vuint8m1_t vsrc_u8 = vle8_v_u8m1(src, vl); // Load 4 unsigned 8-bit integers - vuint32m1_t vsrc_u32 = vwcvt_xu_u_v_u32m1(vsrc_u8, vl); // Widen to 32-bit unsigned integers - vfloat32m1_t vsrc_f32 = vfcvt_f_xu_v_f32m1(vsrc_u32, vl); // Convert to float32 - vfloat32m1_t vnorm = vfmul_vf_f32m1(vsrc_f32, SW_INV_255, vl); // Multiply by 1/255.0 to normalize - vse32_v_f32m1(dst, vnorm, vl); // Store result + size_t vl = __riscv_vsetvl_e8m1(4); // Set vector length for 8-bit input elements + vuint8m1_t vsrc_u8 = __riscv_vle8_v_u8m1(src, vl); // Load 4 unsigned 8-bit integers + vuint32m1_t vsrc_u32 = __riscv_vwcvt_xu_u_v_u32m1(vsrc_u8, vl); // Widen to 32-bit unsigned integers + vfloat32m1_t vsrc_f32 = __riscv_vfcvt_f_xu_v_f32m1(vsrc_u32, vl); // Convert to float32 + vfloat32m1_t vnorm = __riscv_vfmul_vf_f32m1(vsrc_f32, SW_INV_255, vl); // Multiply by 1/255.0 to normalize + __riscv_vse32_v_f32m1(dst, vnorm, vl); // Store result #else dst[0] = (float)src[0]*SW_INV_255; dst[1] = (float)src[1]*SW_INV_255; From 5fbf67a6307f685b0126815a529720bf92886526 Mon Sep 17 00:00:00 2001 From: JohnnyCena123 Date: Sun, 2 Nov 2025 20:24:47 +0200 Subject: [PATCH 044/189] [rcore] Use `FLAG_*` macros where possible (#5169) * use FLAG_* macros where possible * rename `FLAG_CHECK()` to `FLAG_IS_SET()` * remove unnecessary equality checks * fix issues --------- Co-authored-by: Ray --- src/platforms/rcore_android.c | 28 ++--- src/platforms/rcore_desktop_glfw.c | 166 ++++++++++++++--------------- src/platforms/rcore_desktop_rgfw.c | 131 +++++++++++------------ src/platforms/rcore_desktop_sdl.c | 161 +++++++++++++--------------- src/platforms/rcore_drm.c | 32 +++--- src/platforms/rcore_template.c | 4 +- src/platforms/rcore_web.c | 164 ++++++++++++++-------------- src/rcore.c | 18 ++-- 8 files changed, 341 insertions(+), 363 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 47dcce32b..4f106ee3b 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -796,10 +796,10 @@ int InitPlatform(void) //AConfiguration_getScreenLong(platform.app->config); // Set some default window flags - CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false - CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_HIDDEN); // false + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // false + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // true + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // false //---------------------------------------------------------------------------- // Initialize App command system @@ -883,11 +883,11 @@ void ClosePlatform(void) static int InitGraphicsDevice(void) { CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); EGLint samples = 0; EGLint sampleBuffer = 0; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { samples = 4; sampleBuffer = 1; @@ -992,7 +992,7 @@ static int InitGraphicsDevice(void) CORE.Window.ready = true; - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow(); return 0; } @@ -1059,7 +1059,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Set font white rectangle for shapes drawing, so shapes and text can be batched together // WARNING: rshapes module is required, if not available, default internal white rectangle is used Rectangle rec = GetFontDefault().recs[95]; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + 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 SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); @@ -1102,14 +1102,14 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) case APP_CMD_GAINED_FOCUS: { platform.appEnabled = true; - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); //ResumeMusicStream(); } break; case APP_CMD_PAUSE: break; case APP_CMD_LOST_FOCUS: { platform.appEnabled = false; - CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); //PauseMusicStream(); } break; case APP_CMD_TERM_WINDOW: @@ -1187,8 +1187,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) if (type == AINPUT_EVENT_TYPE_MOTION) { - if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) || - ((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD)) + 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 CORE.Input.Gamepad.ready[0] = true; @@ -1251,8 +1251,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) //int32_t AKeyEvent_getMetaState(event); // Handle gamepad button presses and releases - if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) || - ((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD)) + 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 CORE.Input.Gamepad.ready[0] = true; diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 5dde1df67..78b513b40 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -195,14 +195,14 @@ void ToggleFullscreen(void) TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor"); CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + 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); } else { CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); glfwSetWindowMonitor(platform.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); } @@ -211,7 +211,7 @@ void ToggleFullscreen(void) else { CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); @@ -222,7 +222,7 @@ void ToggleFullscreen(void) // 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 - if (CORE.Window.flags & FLAG_VSYNC_HINT) glfwSwapInterval(1); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) glfwSwapInterval(1); } // Toggle borderless windowed mode @@ -256,7 +256,7 @@ void ToggleBorderlessWindowed(void) // Set undecorated flag glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE); - CORE.Window.flags |= FLAG_WINDOW_UNDECORATED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); // Get monitor position and size int monitorPosX = 0; @@ -272,13 +272,13 @@ void ToggleBorderlessWindowed(void) // Refocus window glfwFocusWindow(platform.handle); - CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } else { // Remove undecorated flag glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); - CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); // 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 @@ -288,7 +288,7 @@ void ToggleBorderlessWindowed(void) // Refocus window glfwFocusWindow(platform.handle); - CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); CORE.Window.position.x = CORE.Window.previousPosition.x; CORE.Window.position.y = CORE.Window.previousPosition.y; @@ -305,7 +305,7 @@ void MaximizeWindow(void) if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) { glfwMaximizeWindow(platform.handle); - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } } @@ -323,8 +323,8 @@ void RestoreWindow(void) { // Restores the specified window if it was previously iconified (minimized) or maximized glfwRestoreWindow(platform.handle); - CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; - CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } } @@ -337,109 +337,109 @@ void SetWindowState(unsigned int flags) // NOTE: In most cases the functions already change the flags internally // State change: FLAG_VSYNC_HINT - if (((CORE.Window.flags & FLAG_VSYNC_HINT) != (flags & FLAG_VSYNC_HINT)) && ((flags & FLAG_VSYNC_HINT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT) != FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) && FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) { glfwSwapInterval(1); - CORE.Window.flags |= FLAG_VSYNC_HINT; + FLAG_SET(CORE.Window.flags, FLAG_VSYNC_HINT); } // State change: FLAG_BORDERLESS_WINDOWED_MODE // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running - if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) != (flags & FLAG_BORDERLESS_WINDOWED_MODE)) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE) != FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) && FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) { ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function } // State change: FLAG_FULLSCREEN_MODE - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) != (flags & FLAG_FULLSCREEN_MODE) && ((flags & FLAG_FULLSCREEN_MODE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) != FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) && FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { ToggleFullscreen(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_RESIZABLE - if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) && FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_TRUE); - CORE.Window.flags |= FLAG_WINDOW_RESIZABLE; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE); } // State change: FLAG_WINDOW_UNDECORATED - if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) != (flags & FLAG_WINDOW_UNDECORATED)) && (flags & FLAG_WINDOW_UNDECORATED)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED) != FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) && FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) { glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_FALSE); - CORE.Window.flags |= FLAG_WINDOW_UNDECORATED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); } // State change: FLAG_WINDOW_HIDDEN - if (((CORE.Window.flags & FLAG_WINDOW_HIDDEN) != (flags & FLAG_WINDOW_HIDDEN)) && ((flags & FLAG_WINDOW_HIDDEN) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN) != FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) && FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) { glfwHideWindow(platform.handle); - CORE.Window.flags |= FLAG_WINDOW_HIDDEN; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN); } // State change: FLAG_WINDOW_MINIMIZED - if (((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) != (flags & FLAG_WINDOW_MINIMIZED)) && ((flags & FLAG_WINDOW_MINIMIZED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED) != FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) && FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) { //GLFW_ICONIFIED MinimizeWindow(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_MAXIMIZED - if (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) != (flags & FLAG_WINDOW_MAXIMIZED)) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED) != FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) && FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) { //GLFW_MAXIMIZED MaximizeWindow(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_UNFOCUSED - if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) != (flags & FLAG_WINDOW_UNFOCUSED)) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED) != FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) && FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) { glfwSetWindowAttrib(platform.handle, GLFW_FOCUS_ON_SHOW, GLFW_FALSE); - CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); } // State change: FLAG_WINDOW_TOPMOST - if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) != (flags & FLAG_WINDOW_TOPMOST)) && ((flags & FLAG_WINDOW_TOPMOST) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST) != FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) && FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) { glfwSetWindowAttrib(platform.handle, GLFW_FLOATING, GLFW_TRUE); - CORE.Window.flags |= FLAG_WINDOW_TOPMOST; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST); } // State change: FLAG_WINDOW_ALWAYS_RUN - if (((CORE.Window.flags & FLAG_WINDOW_ALWAYS_RUN) != (flags & FLAG_WINDOW_ALWAYS_RUN)) && ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN) != FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) && FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) { - CORE.Window.flags |= FLAG_WINDOW_ALWAYS_RUN; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); } // The following states can not be changed after window creation // State change: FLAG_WINDOW_TRANSPARENT - if (((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) != (flags & FLAG_WINDOW_TRANSPARENT)) && ((flags & FLAG_WINDOW_TRANSPARENT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT) != FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) && FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "WINDOW: Framebuffer transparency can only be configured before window initialization"); } // State change: FLAG_WINDOW_HIGHDPI - if (((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) != (flags & FLAG_WINDOW_HIGHDPI)) && ((flags & FLAG_WINDOW_HIGHDPI) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI) != FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) && FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) { TRACELOG(LOG_WARNING, "WINDOW: High DPI can only be configured before window initialization"); } // State change: FLAG_WINDOW_MOUSE_PASSTHROUGH - if (((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) != (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)) && ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH) != FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) && FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) { glfwSetWindowAttrib(platform.handle, GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE); - CORE.Window.flags |= FLAG_WINDOW_MOUSE_PASSTHROUGH; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH); } // State change: FLAG_MSAA_4X_HINT - if (((CORE.Window.flags & FLAG_MSAA_4X_HINT) != (flags & FLAG_MSAA_4X_HINT)) && ((flags & FLAG_MSAA_4X_HINT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT) != FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) && FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) { TRACELOG(LOG_WARNING, "WINDOW: MSAA can only be configured before window initialization"); } // State change: FLAG_INTERLACED_HINT - if (((CORE.Window.flags & FLAG_INTERLACED_HINT) != (flags & FLAG_INTERLACED_HINT)) && ((flags & FLAG_INTERLACED_HINT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_INTERLACED_HINT) != FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) && FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "WINDOW: Interlaced mode can only be configured before window initialization"); } @@ -452,107 +452,107 @@ void ClearWindowState(unsigned int flags) // NOTE: In most cases the functions already change the flags internally // State change: FLAG_VSYNC_HINT - if (((CORE.Window.flags & FLAG_VSYNC_HINT) > 0) && ((flags & FLAG_VSYNC_HINT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) && (FLAG_IS_SET(flags, FLAG_VSYNC_HINT))) { glfwSwapInterval(0); - CORE.Window.flags &= ~FLAG_VSYNC_HINT; + FLAG_CLEAR(CORE.Window.flags, FLAG_VSYNC_HINT); } // State change: FLAG_BORDERLESS_WINDOWED_MODE // NOTE: This must be handled before FLAG_FULLSCREEN_MODE because ToggleBorderlessWindowed() needs to get some fullscreen values if fullscreen is running - if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) && (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE))) { ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function } // State change: FLAG_FULLSCREEN_MODE - if (((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) && ((flags & FLAG_FULLSCREEN_MODE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) && (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE))) { ToggleFullscreen(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_RESIZABLE - if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) && (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))) { glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_FALSE); - CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_RESIZABLE); } // State change: FLAG_WINDOW_HIDDEN - if (((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) && ((flags & FLAG_WINDOW_HIDDEN) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) && (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN))) { glfwShowWindow(platform.handle); - CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_HIDDEN); } // State change: FLAG_WINDOW_MINIMIZED - if (((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) && ((flags & FLAG_WINDOW_MINIMIZED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) && (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED))) { RestoreWindow(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_MAXIMIZED - if (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) && (FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED))) { RestoreWindow(); // NOTE: Window state flag updated inside function } // State change: FLAG_WINDOW_UNDECORATED - if (((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) && ((flags & FLAG_WINDOW_UNDECORATED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) && (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED))) { glfwSetWindowAttrib(platform.handle, GLFW_DECORATED, GLFW_TRUE); - CORE.Window.flags &= ~FLAG_WINDOW_UNDECORATED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNDECORATED); } // State change: FLAG_WINDOW_UNFOCUSED - if (((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) && ((flags & FLAG_WINDOW_UNFOCUSED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) && (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED))) { glfwSetWindowAttrib(platform.handle, GLFW_FOCUS_ON_SHOW, GLFW_TRUE); - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); } // State change: FLAG_WINDOW_TOPMOST - if (((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) && ((flags & FLAG_WINDOW_TOPMOST) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) && (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST))) { glfwSetWindowAttrib(platform.handle, GLFW_FLOATING, GLFW_FALSE); - CORE.Window.flags &= ~FLAG_WINDOW_TOPMOST; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_TOPMOST); } // State change: FLAG_WINDOW_ALWAYS_RUN - if (((CORE.Window.flags & FLAG_WINDOW_ALWAYS_RUN) > 0) && ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN)) && (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN))) { - CORE.Window.flags &= ~FLAG_WINDOW_ALWAYS_RUN; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); } // The following states can not be changed after window creation // State change: FLAG_WINDOW_TRANSPARENT - if (((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) && ((flags & FLAG_WINDOW_TRANSPARENT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) && (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT))) { TRACELOG(LOG_WARNING, "WINDOW: Framebuffer transparency can only be configured before window initialization"); } // State change: FLAG_WINDOW_HIGHDPI - if (((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) && ((flags & FLAG_WINDOW_HIGHDPI) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) && (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI))) { TRACELOG(LOG_WARNING, "WINDOW: High DPI can only be configured before window initialization"); } // State change: FLAG_WINDOW_MOUSE_PASSTHROUGH - if (((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) && ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) && (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH))) { glfwSetWindowAttrib(platform.handle, GLFW_MOUSE_PASSTHROUGH, GLFW_FALSE); - CORE.Window.flags &= ~FLAG_WINDOW_MOUSE_PASSTHROUGH; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH); } // State change: FLAG_MSAA_4X_HINT - if (((CORE.Window.flags & FLAG_MSAA_4X_HINT) > 0) && ((flags & FLAG_MSAA_4X_HINT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) && (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT))) { TRACELOG(LOG_WARNING, "WINDOW: MSAA can only be configured before window initialization"); } // State change: FLAG_INTERLACED_HINT - if (((CORE.Window.flags & FLAG_INTERLACED_HINT) > 0) && ((flags & FLAG_INTERLACED_HINT) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_INTERLACED_HINT)) && (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT))) { TRACELOG(LOG_WARNING, "RPI: Interlaced mode can only be configured before window initialization"); } @@ -1391,31 +1391,31 @@ int InitPlatform(void) unsigned int requestedWindowFlags = CORE.Window.flags; // Check window creation flags - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true; - if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden - if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window else glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); // Decorated window - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // Resizable window + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // Resizable window else glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); // Avoid window being resizable // Disable FLAG_WINDOW_MINIMIZED, not supported on initialization - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // Disable FLAG_WINDOW_MAXIMIZED, not supported on initialization - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); - if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); else glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE); - if ((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) glfwWindowHint(GLFW_FLOATING, GLFW_TRUE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) glfwWindowHint(GLFW_FLOATING, GLFW_TRUE); else glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); // NOTE: Some GLFW flags are not supported on HTML5 - if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); // Transparent framebuffer else glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE); // Opaque framebuffer // HACK: Most of this was written before GLFW_SCALE_FRAMEBUFFER existed and @@ -1428,7 +1428,7 @@ int InitPlatform(void) glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); #endif - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { // since we skipped it before, now make sure to set this on macOS #if defined(__APPLE__) @@ -1445,10 +1445,10 @@ int InitPlatform(void) else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); // Mouse passthrough - if ((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE); else glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_FALSE); - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { // NOTE: MSAA is only enabled for main framebuffer, not user-created FBOs TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4"); @@ -1640,7 +1640,7 @@ int InitPlatform(void) // 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 // to be activated on web platforms since VSync is enforced there - if (CORE.Window.flags & FLAG_VSYNC_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) { // WARNING: It seems to hit a critical render path in Intel HD Graphics glfwSwapInterval(1); @@ -1650,7 +1650,7 @@ int InitPlatform(void) int fbWidth = CORE.Window.screen.width; int fbHeight = CORE.Window.screen.height; - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { // NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling // Framebuffer scaling should be activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE); @@ -1682,7 +1682,7 @@ int InitPlatform(void) return -1; } - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + 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; } @@ -1726,7 +1726,7 @@ int InitPlatform(void) glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback); glfwSetDropCallback(platform.handle, WindowDropCallback); - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback); } @@ -1847,22 +1847,22 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s // GLFW3 WindowIconify Callback, runs when window is minimized/restored static void WindowIconifyCallback(GLFWwindow *window, int iconified) { - if (iconified) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; // The window was iconified - else CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // The window was restored + if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored } // GLFW3 WindowMaximize Callback, runs when window is maximized/restored static void WindowMaximizeCallback(GLFWwindow *window, int maximized) { - if (maximized) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // The window was maximized - else CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; // The window was restored + if (maximized) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored } // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused) { - if (focused) CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // The window was focused - else CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; // The window lost focus + if (focused) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was maximized + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was restored } // GLFW3 Window Drop Callback, runs when drop files into window @@ -1905,8 +1905,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i else if (action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1; // WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys - if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) || - ((key == KEY_NUM_LOCK) && ((mods & GLFW_MOD_NUM_LOCK) > 0))) CORE.Input.Keyboard.currentKeyState[key] = 1; + if (((key == KEY_CAPS_LOCK) && (FLAG_IS_SET(mods, GLFW_MOD_CAPS_LOCK))) || + ((key == KEY_NUM_LOCK) && (FLAG_IS_SET(mods, GLFW_MOD_NUM_LOCK)))) CORE.Input.Keyboard.currentKeyState[key] = 1; // Check if there is space available in the key queue if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS)) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 86842140d..863e57a99 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -303,7 +303,7 @@ void ToggleFullscreen(void) platform.mon = RGFW_window_getMonitor(platform.window); CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); RGFW_monitor_scaleToWindow(platform.mon, platform.window); RGFW_window_setFullscreen(platform.window, 1); @@ -311,7 +311,7 @@ void ToggleFullscreen(void) else { CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); if (platform.mon.mode.area.w) { @@ -330,7 +330,7 @@ void ToggleFullscreen(void) // 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 - if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1); } // Toggle borderless windowed mode @@ -372,7 +372,7 @@ void MinimizeWindow(void) // Restore window from being minimized/maximized void RestoreWindow(void) { - if (!(CORE.Window.flags & FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); RGFW_window_restore(platform.window); } @@ -382,72 +382,68 @@ void SetWindowState(unsigned int flags) { if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead"); - CORE.Window.flags |= flags; + FLAG_SET(CORE.Window.flags, flags); - if (flags & FLAG_VSYNC_HINT) + if (FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) { RGFW_window_swapInterval(platform.window, 1); } - if (flags & FLAG_FULLSCREEN_MODE) + if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { if (!CORE.Window.fullscreen) ToggleFullscreen(); } - if (flags & FLAG_WINDOW_RESIZABLE) + if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { RGFW_window_setMaxSize(platform.window, RGFW_AREA(0, 0)); RGFW_window_setMinSize(platform.window, RGFW_AREA(0, 0)); } - if (flags & FLAG_WINDOW_UNDECORATED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) { RGFW_window_setBorder(platform.window, 0); } - if (flags & FLAG_WINDOW_HIDDEN) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) { RGFW_window_hide(platform.window); } - if (flags & FLAG_WINDOW_MINIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) { RGFW_window_minimize(platform.window); } - if (flags & FLAG_WINDOW_MAXIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) { RGFW_window_maximize(platform.window); } - if (flags & FLAG_WINDOW_UNFOCUSED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) { - CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; - platform.window->_flags &= ~RGFW_windowFocusOnShow; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); + FLAG_CLEAR(platform.window->_flags, RGFW_windowFocusOnShow); RGFW_window_setFlags(platform.window, platform.window->_flags); } - if (flags & FLAG_WINDOW_TOPMOST) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) { RGFW_window_setFloating(platform.window, RGFW_TRUE); } - if (flags & FLAG_WINDOW_ALWAYS_RUN) - { - CORE.Window.flags |= FLAG_WINDOW_ALWAYS_RUN; - } - if (flags & FLAG_WINDOW_TRANSPARENT) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "WINDOW: Framebuffer transparency can only be configured before window initialization"); } - if (flags & FLAG_WINDOW_HIGHDPI) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) { TRACELOG(LOG_WARNING, "WINDOW: High DPI can only be configured before window initialization"); } - if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) { RGFW_window_setMousePassthrough(platform.window, 1); } - if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) { ToggleBorderlessWindowed(); } - if (flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) { RGFW_setGLHint(RGFW_glSamples, 4); } - if (flags & FLAG_INTERLACED_HINT) + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "RPI: Interlaced mode can only be configured before window initialization"); } @@ -456,77 +452,72 @@ void SetWindowState(unsigned int flags) // Clear window configuration state flags void ClearWindowState(unsigned int flags) { - CORE.Window.flags &= ~flags; + FLAG_CLEAR(CORE.Window.flags, flags); - if (flags & FLAG_VSYNC_HINT) + if (FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) { RGFW_window_swapInterval(platform.window, 0); } - if (flags & FLAG_FULLSCREEN_MODE) + if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { if (CORE.Window.fullscreen) ToggleFullscreen(); } - if (flags & FLAG_WINDOW_RESIZABLE) + if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); } - if (flags & FLAG_WINDOW_UNDECORATED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) { RGFW_window_setBorder(platform.window, 1); } - if (flags & FLAG_WINDOW_HIDDEN) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) { - if (!(CORE.Window.flags & FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); RGFW_window_show(platform.window); } - if (flags & FLAG_WINDOW_MINIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) { - if (!(CORE.Window.flags & FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); RGFW_window_restore(platform.window); } - if (flags & FLAG_WINDOW_MAXIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) { - if (!(CORE.Window.flags & FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) RGFW_window_focus(platform.window); RGFW_window_restore(platform.window); } - if (flags & FLAG_WINDOW_UNFOCUSED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) { RGFW_window_setFlags(platform.window, platform.window->_flags | RGFW_windowFocusOnShow); - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; } - if (flags & FLAG_WINDOW_TOPMOST) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) { RGFW_window_setFloating(platform.window, RGFW_FALSE); } - if (flags & FLAG_WINDOW_ALWAYS_RUN) - { - CORE.Window.flags &= ~FLAG_WINDOW_ALWAYS_RUN; - } - if (flags & FLAG_WINDOW_TRANSPARENT) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "WINDOW: Framebuffer transparency can only be configured before window initialization"); } - if (flags & FLAG_WINDOW_HIGHDPI) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) { TRACELOG(LOG_WARNING, "WINDOW: High DPI can only be configured before window initialization"); } - if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) { RGFW_window_setMousePassthrough(platform.window, 0); } - if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) { if (CORE.Window.fullscreen) ToggleBorderlessWindowed(); } - if (flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) { RGFW_setGLHint(RGFW_glSamples, 0); } - if (flags & FLAG_INTERLACED_HINT) + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "RPI: Interlaced mode can only be configured before window initialization"); } @@ -983,7 +974,7 @@ void PollInputEvents(void) CORE.Window.resizedLastFrame = false; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; - if (platform.window->_flags & RGFW_HOLD_MOUSE) + if (FLAG_IS_SET(platform.window->_flags, RGFW_HOLD_MOUSE)) { CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f }; @@ -1062,18 +1053,18 @@ void PollInputEvents(void) } break; case RGFW_windowMaximized: { - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // The window was maximized + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized } break; case RGFW_windowMinimized: { - CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; // The window was iconified + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified } break; case RGFW_windowRestored: { if (RGFW_window_isMaximized(platform.window)) - CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; // The window was restored + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored if (RGFW_window_isMinimized(platform.window)) - CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // The window was restored + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored } break; case RGFW_windowMoved: { @@ -1159,7 +1150,7 @@ void PollInputEvents(void) } break; case RGFW_mousePosChanged: { - if (platform.window->_flags & RGFW_HOLD_MOUSE) + if (FLAG_IS_SET(platform.window->_flags, RGFW_HOLD_MOUSE)) { CORE.Input.Mouse.currentPosition.x += (float)event->vector.x; CORE.Input.Mouse.currentPosition.y += (float)event->vector.y; @@ -1283,24 +1274,24 @@ int InitPlatform(void) unsigned int flags = RGFW_windowCenter | RGFW_windowAllowDND; // Check window creation flags - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { CORE.Window.fullscreen = true; - flags |= RGFW_windowFullscreen; + FLAG_SET(flags, RGFW_windowFullscreen); } - if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) { CORE.Window.fullscreen = true; - flags |= RGFW_windowedFullscreen; + FLAG_SET(flags, RGFW_windowedFullscreen); } - if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= RGFW_windowNoBorder; - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) flags |= RGFW_windowNoResize; - if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= RGFW_windowTransparent; - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) flags |= RGFW_windowFullscreen; - if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) flags |= RGFW_windowHide; - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) flags |= RGFW_windowMaximize; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, RGFW_windowNoBorder); + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) FLAG_SET(flags, RGFW_windowNoResize); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) FLAG_SET(flags, RGFW_windowTransparent); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) FLAG_SET(flags, RGFW_windowFullscreen); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, RGFW_windowHide); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_SET(flags, RGFW_windowMaximize); // NOTE: Some OpenGL context attributes must be set before window creation // Check selection OpenGL version @@ -1320,9 +1311,9 @@ int InitPlatform(void) RGFW_setGLHint(RGFW_glMinor, 3); } - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) RGFW_setGLHint(RGFW_glSamples, 4); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) RGFW_setGLHint(RGFW_glSamples, 4); - if (!(CORE.Window.flags & FLAG_WINDOW_UNFOCUSED)) flags |= RGFW_windowFocusOnShow | RGFW_windowFocus; + 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.mon.mode.area.w = 0; @@ -1345,8 +1336,8 @@ int InitPlatform(void) // TODO: Is this needed by raylib now? // If so, rcore_desktop_sdl should be updated too //SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - - if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); + + if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1); RGFW_window_makeCurrent(platform.window); // Check surface and context activation diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 03bad80f9..0b6376a50 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -468,16 +468,16 @@ void ToggleFullscreen(void) if ((monitor >= 0) && (monitor < monitorCount)) #endif { - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { SDL_SetWindowFullscreen(platform.window, 0); - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); CORE.Window.fullscreen = false; } else { SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN); - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); CORE.Window.fullscreen = true; } } @@ -496,15 +496,15 @@ void ToggleBorderlessWindowed(void) if ((monitor >= 0) && (monitor < monitorCount)) #endif { - if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) { SDL_SetWindowFullscreen(platform.window, 0); - CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } else { SDL_SetWindowFullscreen(platform.window, SDL_WINDOW_FULLSCREEN_DESKTOP); - CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); @@ -514,14 +514,14 @@ void ToggleBorderlessWindowed(void) void MaximizeWindow(void) { SDL_MaximizeWindow(platform.window); - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } // Set window state: minimized void MinimizeWindow(void) { SDL_MinimizeWindow(platform.window); - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); } // Restore window from being minimized/maximized @@ -536,13 +536,13 @@ void SetWindowState(unsigned int flags) { if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead"); - CORE.Window.flags |= flags; + FLAG_SET(CORE.Window.flags, flags); - if (flags & FLAG_VSYNC_HINT) + if (FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) { SDL_GL_SetSwapInterval(1); } - if (flags & FLAG_FULLSCREEN_MODE) + if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { const int monitor = SDL_GetWindowDisplayIndex(platform.window); const int monitorCount = SDL_GetNumVideoDisplays(); @@ -558,55 +558,51 @@ void SetWindowState(unsigned int flags) } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); } - if (flags & FLAG_WINDOW_RESIZABLE) + if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { SDL_SetWindowResizable(platform.window, SDL_TRUE); } - if (flags & FLAG_WINDOW_UNDECORATED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) { SDL_SetWindowBordered(platform.window, SDL_FALSE); } - if (flags & FLAG_WINDOW_HIDDEN) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) { SDL_HideWindow(platform.window); } - if (flags & FLAG_WINDOW_MINIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) { SDL_MinimizeWindow(platform.window); } - if (flags & FLAG_WINDOW_MAXIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) { SDL_MaximizeWindow(platform.window); } - if (flags & FLAG_WINDOW_UNFOCUSED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) { // NOTE: To be able to implement this part it seems that we should // do it ourselves, via 'windows.h', 'X11/Xlib.h' or even 'Cocoa.h' TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_WINDOW_TOPMOST) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) { SDL_SetWindowAlwaysOnTop(platform.window, SDL_FALSE); } - if (flags & FLAG_WINDOW_ALWAYS_RUN) - { - CORE.Window.flags |= FLAG_WINDOW_ALWAYS_RUN; - } - if (flags & FLAG_WINDOW_TRANSPARENT) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_WINDOW_HIGHDPI) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIGHDPI)) { // NOTE: Such a function does not seem to exist TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) { //SDL_SetWindowGrab(platform.window, SDL_FALSE); TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) { const int monitor = SDL_GetWindowDisplayIndex(platform.window); const int monitorCount = SDL_GetNumVideoDisplays(); @@ -621,12 +617,12 @@ void SetWindowState(unsigned int flags) } else TRACELOG(LOG_WARNING, "SDL: Failed to find selected monitor"); } - if (flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Enable multisampling buffers SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); // Enable multisampling } - if (flags & FLAG_INTERLACED_HINT) + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_SDL"); } @@ -635,74 +631,69 @@ void SetWindowState(unsigned int flags) // Clear window configuration state flags void ClearWindowState(unsigned int flags) { - CORE.Window.flags &= ~flags; + FLAG_CLEAR(CORE.Window.flags, flags); - if (flags & FLAG_VSYNC_HINT) + if (FLAG_IS_SET(flags, FLAG_VSYNC_HINT)) { SDL_GL_SetSwapInterval(0); } - if (flags & FLAG_FULLSCREEN_MODE) + if (FLAG_IS_SET(flags, FLAG_FULLSCREEN_MODE)) { SDL_SetWindowFullscreen(platform.window, 0); CORE.Window.fullscreen = false; } - if (flags & FLAG_WINDOW_RESIZABLE) + if (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) { SDL_SetWindowResizable(platform.window, SDL_FALSE); } - if (flags & FLAG_WINDOW_UNDECORATED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNDECORATED)) { SDL_SetWindowBordered(platform.window, SDL_TRUE); } - if (flags & FLAG_WINDOW_HIDDEN) + if (FLAG_IS_SET(flags, FLAG_WINDOW_HIDDEN)) { SDL_ShowWindow(platform.window); } - if (flags & FLAG_WINDOW_MINIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) { SDL_RestoreWindow(platform.window); } - if (flags & FLAG_WINDOW_MAXIMIZED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED)) { SDL_RestoreWindow(platform.window); } - if (flags & FLAG_WINDOW_UNFOCUSED) + if (FLAG_IS_SET(flags, FLAG_WINDOW_UNFOCUSED)) { //SDL_RaiseWindow(platform.window); TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_WINDOW_TOPMOST) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TOPMOST)) { SDL_SetWindowAlwaysOnTop(platform.window, SDL_FALSE); } - if (flags & FLAG_WINDOW_ALWAYS_RUN) - { - CORE.Window.flags &= ~FLAG_WINDOW_ALWAYS_RUN; - } - if (flags & FLAG_WINDOW_TRANSPARENT) + if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_WINDOW_HIGHDPI) { // NOTE: There also doesn't seem to be a feature to disable high DPI once enabled TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) + if (FLAG_IS_SET(flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) { //SDL_SetWindowGrab(platform.window, SDL_TRUE); TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_SDL"); } - if (flags & FLAG_BORDERLESS_WINDOWED_MODE) + if (FLAG_IS_SET(flags, FLAG_BORDERLESS_WINDOWED_MODE)) { SDL_SetWindowFullscreen(platform.window, 0); } - if (flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(flags, FLAG_MSAA_4X_HINT)) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); // Disable multisampling buffers SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); // Disable multisampling } - if (flags & FLAG_INTERLACED_HINT) + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_SDL"); } @@ -847,7 +838,7 @@ void SetWindowMonitor(int monitor) // 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 - const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0)? true : false; + const bool wasFullscreen = (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))? true : false; const int screenWidth = CORE.Window.screen.width; const int screenHeight = CORE.Window.screen.height; @@ -1410,7 +1401,7 @@ void PollInputEvents(void) CORE.Window.resizedLastFrame = false; - if ((CORE.Window.eventWaiting) || (((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) && ((CORE.Window.flags & FLAG_WINDOW_ALWAYS_RUN) == 0))) + if ((CORE.Window.eventWaiting) || (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED) && !FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN))) { SDL_WaitEvent(NULL); CORE.Time.previous = GetTime(); @@ -1498,7 +1489,7 @@ void PollInputEvents(void) #ifndef USING_VERSION_SDL3 // Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms) to remove the FLAG_WINDOW_MAXIMIZED accordingly - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) { int borderTop = 0; int borderLeft = 0; @@ -1508,7 +1499,7 @@ void PollInputEvents(void) SDL_Rect usableBounds; SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(platform.window), &usableBounds); - if ((width + borderLeft + borderRight != usableBounds.w) && (height + borderTop + borderBottom != usableBounds.h)) CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + if ((width + borderLeft + borderRight != usableBounds.w) && (height + borderTop + borderBottom != usableBounds.h)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } #endif } break; @@ -1524,43 +1515,43 @@ void PollInputEvents(void) case SDL_WINDOWEVENT_MINIMIZED: { - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); } break; case SDL_WINDOWEVENT_MAXIMIZED: { - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } break; case SDL_WINDOWEVENT_RESTORED: { - if ((SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MINIMIZED) == 0) + if (!FLAG_IS_SET(SDL_GetWindowFlags(platform.window), SDL_WINDOW_MINIMIZED)) { - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); } #ifdef USING_VERSION_SDL3 - if ((SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MAXIMIZED) == 0) + if (!FLAG_IS_SET(SDL_GetWindowFlags(platform.window), SDL_WINDOW_MAXIMIZED)) { - if ((CORE.Window.flags & SDL_WINDOW_MAXIMIZED) > 0) CORE.Window.flags &= ~SDL_WINDOW_MAXIMIZED; + if (FLAG_IS_SET(CORE.Window.flags, SDL_WINDOW_MAXIMIZED)) FLAG_CLEAR(CORE.Window.flags, SDL_WINDOW_MAXIMIZED); } #endif } break; case SDL_WINDOWEVENT_HIDDEN: { - if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) == 0) CORE.Window.flags |= FLAG_WINDOW_HIDDEN; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN); } break; case SDL_WINDOWEVENT_SHOWN: { - if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_HIDDEN); } break; case SDL_WINDOWEVENT_FOCUS_GAINED: { - if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); } break; case SDL_WINDOWEVENT_FOCUS_LOST: { - if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0) CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); } break; #ifndef USING_VERSION_SDL3 @@ -1930,38 +1921,34 @@ int InitPlatform(void) // Initialize graphic device: display/window and graphic context //---------------------------------------------------------------------------- unsigned int flags = 0; - flags |= SDL_WINDOW_SHOWN; - flags |= SDL_WINDOW_INPUT_FOCUS; - flags |= SDL_WINDOW_MOUSE_FOCUS; - flags |= SDL_WINDOW_MOUSE_CAPTURE; // Window has mouse captured + FLAG_SET(flags, SDL_WINDOW_SHOWN); + FLAG_SET(flags, SDL_WINDOW_INPUT_FOCUS); + FLAG_SET(flags, SDL_WINDOW_MOUSE_FOCUS); + FLAG_SET(flags, SDL_WINDOW_MOUSE_CAPTURE); // Window has mouse captured // Check window creation flags - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) { CORE.Window.fullscreen = true; - flags |= SDL_WINDOW_FULLSCREEN; + FLAG_SET(flags, SDL_WINDOW_FULLSCREEN); } - //if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) == 0) flags |= SDL_WINDOW_HIDDEN; - if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= SDL_WINDOW_BORDERLESS; - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) flags |= SDL_WINDOW_RESIZABLE; - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) flags |= SDL_WINDOW_MINIMIZED; - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) flags |= SDL_WINDOW_MAXIMIZED; - - if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) + //if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) FLAG_SET(flags, SDL_WINDOW_RESIZABLE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_SET(flags, SDL_WINDOW_MINIMIZED); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_SET(flags, SDL_WINDOW_MAXIMIZED); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) { - flags &= ~SDL_WINDOW_INPUT_FOCUS; - flags &= ~SDL_WINDOW_MOUSE_FOCUS; + FLAG_CLEAR(flags, SDL_WINDOW_INPUT_FOCUS); + FLAG_CLEAR(flags, SDL_WINDOW_MOUSE_FOCUS); } + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) FLAG_SET(flags, SDL_WINDOW_ALWAYS_ON_TOP); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) FLAG_CLEAR(flags, SDL_WINDOW_MOUSE_CAPTURE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) FLAG_SET(flags, SDL_WINDOW_ALLOW_HIGHDPI); - if ((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) flags |= SDL_WINDOW_ALWAYS_ON_TOP; - if ((CORE.Window.flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) flags &= ~SDL_WINDOW_MOUSE_CAPTURE; - - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) flags |= SDL_WINDOW_ALLOW_HIGHDPI; - - //if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= SDL_WINDOW_TRANSPARENT; // Alternative: SDL_GL_ALPHA_SIZE = 8 - - //if ((CORE.Window.flags & FLAG_FULLSCREEN_DESKTOP) > 0) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + //if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) FLAG_SET(flags, SDL_WINDOW_TRANSPARENT); // Alternative: SDL_GL_ALPHA_SIZE = 8 + //if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_DESKTOP)) FLAG_SET(flags, SDL_WINDOW_FULLSCREEN_DESKTOP); // NOTE: Some OpenGL context attributes must be set before window creation @@ -2004,7 +1991,7 @@ int InitPlatform(void) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); } - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); @@ -2047,7 +2034,7 @@ int InitPlatform(void) if (platform.glContext != NULL) { - SDL_GL_SetSwapInterval((CORE.Window.flags & FLAG_VSYNC_HINT)? 1 : 0); + SDL_GL_SetSwapInterval((FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT))? 1: 0); // Load OpenGL extensions // NOTE: GL procedures address loader is required to load extensions diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index da0d08aca..c0fa5a5f3 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1148,7 +1148,7 @@ int InitPlatform(void) // Initialize graphic device: display/window and graphic context //---------------------------------------------------------------------------- CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); #if defined(DEFAULT_GRAPHIC_DEVICE_DRM) platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR); @@ -1297,7 +1297,7 @@ int InitPlatform(void) CORE.Window.screen.height = CORE.Window.display.height; } - const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT; + const bool allowInterlaced = FLAG_IS_SET(CORE.Window.flags, FLAG_INTERLACED_HINT); const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60; // Try to find an exact matching mode @@ -1328,7 +1328,7 @@ int InitPlatform(void) TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", platform.connector->modes[platform.modeIndex].name, platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay, - (platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p', + FLAG_IS_SET(platform.connector->modes[platform.modeIndex].flags, DRM_MODE_FLAG_INTERLACE)? 'i' : 'p', platform.connector->modes[platform.modeIndex].vrefresh); drmModeFreeEncoder(enc); @@ -1384,7 +1384,7 @@ int InitPlatform(void) EGLint samples = 0; EGLint sampleBuffer = 0; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { samples = 4; sampleBuffer = 1; @@ -1561,17 +1561,17 @@ int InitPlatform(void) TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); #endif - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + 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 SetWindowPosition(GetMonitorWidth(GetCurrentMonitor())/2 - CORE.Window.screen.width/2, GetMonitorHeight(GetCurrentMonitor())/2 - CORE.Window.screen.height/2); // Set some default window flags - CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false - CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true - CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_HIDDEN); // false + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // false + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // true + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // false //---------------------------------------------------------------------------- // Initialize timing system @@ -1720,8 +1720,8 @@ static void InitKeyboard(void) // New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing // NOTE: ISIG controls if ^C and ^Z generate break signals or not - keyboardNewSettings.c_lflag &= ~(ICANON | ECHO | ISIG); - //keyboardNewSettings.c_iflag &= ~(ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF); + FLAG_CLEAR(keyboardNewSettings.c_lflag, ICANON | ECHO | ISIG); + //FLAG_CLEAR(keyboardNewSettings.c_iflag, ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF); keyboardNewSettings.c_cc[VMIN] = 1; keyboardNewSettings.c_cc[VTIME] = 0; @@ -2402,7 +2402,7 @@ static int FindMatchingConnectorMode(const drmModeConnector *connector, const dr for (size_t i = 0; i < connector->count_modes; i++) { TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, connector->modes[i].hdisplay, connector->modes[i].vdisplay, - connector->modes[i].vrefresh, (connector->modes[i].flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive"); + connector->modes[i].vrefresh, (FLAG_IS_SET(connector->modes[i].flags, DRM_MODE_FLAG_INTERLACE) > 0)? "interlaced" : "progressive"); if (0 == BINCMP(&platform.crtc->mode, &platform.connector->modes[i])) return i; } @@ -2423,9 +2423,9 @@ static int FindExactConnectorMode(const drmModeConnector *connector, uint width, { const drmModeModeInfo *const mode = &platform.connector->modes[i]; - TRACELOG(LOG_TRACE, "DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive"); + TRACELOG(LOG_TRACE, "DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (FLAG_IS_SET(mode->flags, DRM_MODE_FLAG_INTERLACE) > 0)? "interlaced" : "progressive"); - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !allowInterlaced) continue; + if ((FLAG_IS_SET(mode->flags, DRM_MODE_FLAG_INTERLACE) > 0) && !allowInterlaced) continue; if ((mode->hdisplay == width) && (mode->vdisplay == height) && (mode->vrefresh == fps)) return i; } @@ -2449,7 +2449,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt const drmModeModeInfo *const mode = &platform.connector->modes[i]; TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, - (mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive"); + (FLAG_IS_SET(mode->flags, DRM_MODE_FLAG_INTERLACE) > 0)? "interlaced" : "progressive"); if ((mode->hdisplay < width) || (mode->vdisplay < height)) { @@ -2457,7 +2457,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt continue; } - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !allowInterlaced) + if ((FLAG_IS_SET(mode->flags, DRM_MODE_FLAG_INTERLACE) > 0) && !allowInterlaced) { TRACELOG(LOG_TRACE, "DISPLAY: DRM shouldn't choose an interlaced mode"); continue; diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index 36629fc69..bc03a3cdb 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -460,11 +460,11 @@ int InitPlatform(void) // Below example illustrates that process using EGL library //---------------------------------------------------------------------------- CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); EGLint samples = 0; EGLint sampleBuffer = 0; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { samples = 4; sampleBuffer = 1; diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index c8fe0cfe7..5f8afd7e4 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -181,8 +181,8 @@ void ToggleFullscreen(void) const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); if (wasFullscreen) { - if (CORE.Window.flags & FLAG_FULLSCREEN_MODE) enterFullscreen = false; - else if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) enterFullscreen = true; + 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); @@ -194,8 +194,8 @@ void ToggleFullscreen(void) EM_ASM(document.exitFullscreen();); CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; - CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } else enterFullscreen = true; @@ -210,7 +210,7 @@ void ToggleFullscreen(void) }, 100); ); CORE.Window.fullscreen = true; - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } // NOTE: Old notes below: @@ -263,7 +263,7 @@ void ToggleFullscreen(void) TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); CORE.Window.fullscreen = true; // Toggle fullscreen flag - CORE.Window.flags |= FLAG_FULLSCREEN_MODE; + FLAG_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } else { @@ -275,7 +275,7 @@ void ToggleFullscreen(void) TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); CORE.Window.fullscreen = false; // Toggle fullscreen flag - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } */ } @@ -289,8 +289,8 @@ void ToggleBorderlessWindowed(void) const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0); if (wasFullscreen) { - if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) enterBorderless = false; - else if (CORE.Window.flags & FLAG_FULLSCREEN_MODE) enterBorderless = true; + 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); @@ -302,8 +302,8 @@ void ToggleBorderlessWindowed(void) EM_ASM(document.exitFullscreen();); CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; - CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } else enterBorderless = true; @@ -322,14 +322,14 @@ void ToggleBorderlessWindowed(void) }, 100); }, 100); ); - CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } // Set window state: maximized, if resizable void MaximizeWindow(void) { - if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) + if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && !(FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED))) { platform.unmaximizedWidth = CORE.Window.screen.width; platform.unmaximizedHeight = CORE.Window.screen.height; @@ -339,7 +339,7 @@ void MaximizeWindow(void) if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight); - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } } @@ -352,11 +352,11 @@ void MinimizeWindow(void) // Restore window from being minimized/maximized void RestoreWindow(void) { - if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED)) + if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED))) { if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight); - CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } } @@ -369,13 +369,13 @@ void SetWindowState(unsigned int flags) // NOTE: In most cases the functions already change the flags internally // State change: FLAG_VSYNC_HINT - if ((flags & FLAG_VSYNC_HINT) > 0) + 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 ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) + 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); @@ -383,13 +383,13 @@ void SetWindowState(unsigned int flags) { 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 ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) || canvasStyleWidth > canvasWidth) ToggleBorderlessWindowed(); + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) || canvasStyleWidth > canvasWidth) ToggleBorderlessWindowed(); } else ToggleBorderlessWindowed(); } // State change: FLAG_FULLSCREEN_MODE - if ((flags & FLAG_FULLSCREEN_MODE) > 0) + 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); @@ -397,38 +397,38 @@ void SetWindowState(unsigned int flags) { const int canvasWidth = EM_ASM_INT( { return Module.canvas.width; }, 0); const int screenWidth = EM_ASM_INT( { return screen.width; }, 0); - if ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) || screenWidth == canvasWidth ) ToggleFullscreen(); + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE)) || screenWidth == canvasWidth ) ToggleFullscreen(); } else ToggleFullscreen(); } // State change: FLAG_WINDOW_RESIZABLE - if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE)) && (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))) { glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_TRUE); - CORE.Window.flags |= FLAG_WINDOW_RESIZABLE; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE); } // State change: FLAG_WINDOW_UNDECORATED - if ((flags & FLAG_WINDOW_UNDECORATED) > 0) + 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 ((flags & FLAG_WINDOW_HIDDEN) > 0) + 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 ((flags & FLAG_WINDOW_MINIMIZED) > 0) + 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 (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) != (flags & FLAG_WINDOW_MAXIMIZED)) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0)) + 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 (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) { @@ -440,24 +440,24 @@ void SetWindowState(unsigned int flags) if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight); - CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } } // State change: FLAG_WINDOW_UNFOCUSED - if ((flags & FLAG_WINDOW_UNFOCUSED) > 0) + 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 ((flags & FLAG_WINDOW_TOPMOST) > 0) + 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 ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0) + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) { TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform"); } @@ -466,31 +466,31 @@ void SetWindowState(unsigned int flags) // NOTE: Review for PLATFORM_WEB // State change: FLAG_WINDOW_TRANSPARENT - if ((flags & FLAG_WINDOW_TRANSPARENT) > 0) + 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 ((flags & FLAG_WINDOW_HIGHDPI) > 0) + 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 ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) + 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 ((flags & FLAG_MSAA_4X_HINT) > 0) + 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 ((flags & FLAG_INTERLACED_HINT) > 0) + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "SetWindowState(FLAG_INTERLACED_HINT) not available on target platform"); } @@ -503,90 +503,90 @@ void ClearWindowState(unsigned int flags) // NOTE: In most cases the functions already change the flags internally // State change: FLAG_VSYNC_HINT - if ((flags & FLAG_VSYNC_HINT) > 0) + 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 ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) + 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 ((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) || (screenWidth == canvasWidth)) EM_ASM(document.exitFullscreen();); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE) || (screenWidth == canvasWidth)) EM_ASM(document.exitFullscreen();); } - CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } // State change: FLAG_FULLSCREEN_MODE - if ((flags & FLAG_FULLSCREEN_MODE) > 0) + 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 ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE) || (canvasStyleWidth > canvasWidth)) EM_ASM(document.exitFullscreen();); } CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); } // State change: FLAG_WINDOW_RESIZABLE - if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) && (FLAG_IS_SET(flags, FLAG_WINDOW_RESIZABLE))) { glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_FALSE); - CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_RESIZABLE); } // State change: FLAG_WINDOW_HIDDEN - if ((flags & FLAG_WINDOW_HIDDEN) > 0) + 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 ((flags & FLAG_WINDOW_MINIMIZED) > 0) + 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 (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0)) + if ((FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) && (FLAG_IS_SET(flags, FLAG_WINDOW_MAXIMIZED))) { if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) { if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight); - CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); } } // State change: FLAG_WINDOW_UNDECORATED - if ((flags & FLAG_WINDOW_UNDECORATED) > 0) + 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 ((flags & FLAG_WINDOW_UNFOCUSED) > 0) + 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 ((flags & FLAG_WINDOW_TOPMOST) > 0) + 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 ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0) + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) { TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform"); } @@ -595,31 +595,31 @@ void ClearWindowState(unsigned int flags) // NOTE: Review for PLATFORM_WEB // State change: FLAG_WINDOW_TRANSPARENT - if ((flags & FLAG_WINDOW_TRANSPARENT) > 0) + 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 ((flags & FLAG_WINDOW_HIGHDPI) > 0) + 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 ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0) + 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 ((flags & FLAG_MSAA_4X_HINT) > 0) + 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 ((flags & FLAG_INTERLACED_HINT) > 0) + if (FLAG_IS_SET(flags, FLAG_INTERLACED_HINT)) { TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_INTERLACED_HINT) not available on target platform"); } @@ -663,7 +663,7 @@ void SetWindowMinSize(int width, int height) CORE.Window.screenMin.height = height; // Trigger the resize event once to update the window minimum width and height - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); } // Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) @@ -673,7 +673,7 @@ void SetWindowMaxSize(int width, int height) CORE.Window.screenMax.height = height; // Trigger the resize event once to update the window maximum width and height - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE) != 0) EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); } // Set window dimensions @@ -1122,27 +1122,27 @@ int InitPlatform(void) // glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers // Check window creation flags - if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE)) CORE.Window.fullscreen = true; - if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // Visible window else glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); // Window initially hidden - if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); // Border and buttons on Window else glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); // Decorated window - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // Resizable window + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // Resizable window else glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); // Avoid window being resizable // Disable FLAG_WINDOW_MINIMIZED, not supported on initialization - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // Disable FLAG_WINDOW_MAXIMIZED, not supported on initialization - if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED; + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); - if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)) glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); else glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE); - if ((CORE.Window.flags & FLAG_WINDOW_TOPMOST) > 0) glfwWindowHint(GLFW_FLOATING, GLFW_TRUE); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) glfwWindowHint(GLFW_FLOATING, GLFW_TRUE); else glfwWindowHint(GLFW_FLOATING, GLFW_FALSE); // NOTE: Some GLFW flags are not supported on HTML5 @@ -1150,10 +1150,10 @@ int InitPlatform(void) // Scale content area based on the monitor content scale where window is placed on // NOTE: This feature requires emscripten 3.1.51 - //if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); + //if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); //else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) { // NOTE: MSAA is only enabled for main framebuffer, not user-created FBOs TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4"); @@ -1296,7 +1296,7 @@ int InitPlatform(void) glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback); glfwSetDropCallback(platform.handle, WindowDropCallback); - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { // Window content (framebuffer) scale callback glfwSetWindowContentScaleCallback(platform.handle, WindowContentScaleCallback); @@ -1338,7 +1338,7 @@ int InitPlatform(void) return -1; } - if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow(); + 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; } @@ -1423,7 +1423,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height) if (IsWindowFullscreen()) return; // Set current screen size - if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 windowScaleDPI = GetWindowScaleDPI(); @@ -1448,15 +1448,15 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s // GLFW3: Called on windows minimized/restored static void WindowIconifyCallback(GLFWwindow *window, int iconified) { - if (iconified) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED; // The window was iconified - else CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // The window was restored + if (iconified) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored } // GLFW3: Called on windows get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused) { - if (focused) CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // The window was focused - else CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED; // The window lost focus + if (focused) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus } // GLFW3: Called on file-drop over the window @@ -1782,8 +1782,8 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte if (!wasFullscreen) { CORE.Window.fullscreen = false; - CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; - CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE; + FLAG_CLEAR(CORE.Window.flags, FLAG_FULLSCREEN_MODE); + FLAG_CLEAR(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } @@ -1794,7 +1794,7 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData) { // Don't resize non-resizeable windows - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) return 1; + if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) return 1; // This event is called whenever the window changes sizes, // so the size of the canvas object is explicitly retrieved below @@ -1844,8 +1844,8 @@ static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent // Emscripten: Called on visibility change events static EM_BOOL EmscriptenVisibilityChangeCallback(int eventType, const EmscriptenVisibilityChangeEvent *visibilityChangeEvent, void *userData) { - if (visibilityChangeEvent->hidden) CORE.Window.flags |= FLAG_WINDOW_HIDDEN; // The window was hidden - else CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // The window was restored + 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 } //------------------------------------------------------------------------------------------------------- diff --git a/src/rcore.c b/src/rcore.c index d06e3089b..cb6c89881 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -280,7 +280,7 @@ __declspec(dllimport) unsigned int __stdcall timeEndPeriod(unsigned int uPeriod) #define FLAG_SET(n, f) ((n) |= (f)) #define FLAG_CLEAR(n, f) ((n) &= ~(f)) #define FLAG_TOGGLE(n, f) ((n) ^= (f)) -#define FLAG_CHECK(n, f) ((n) & (f)) +#define FLAG_IS_SET(n, f) (((n) & (f)) > 0) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -725,7 +725,7 @@ void InitWindow(int width, int height, const char *title) // Set font white rectangle for shapes drawing, so shapes and text can be batched together // WARNING: rshapes module is required, if not available, default internal white rectangle is used Rectangle rec = GetFontDefault().recs[95]; - if (CORE.Window.flags & FLAG_MSAA_4X_HINT) + 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 SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); @@ -797,25 +797,25 @@ bool IsWindowFullscreen(void) // Check if window is currently hidden bool IsWindowHidden(void) { - return ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0); + return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)); } // Check if window has been minimized bool IsWindowMinimized(void) { - return ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0); + return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)); } // Check if window has been maximized bool IsWindowMaximized(void) { - return ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0); + return (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED)); } // Check if window has the focus bool IsWindowFocused(void) { - return ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0); + return (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED)); } // Check if window has been resizedLastFrame @@ -827,7 +827,7 @@ bool IsWindowResized(void) // Check if one specific window flag is enabled bool IsWindowState(unsigned int flag) { - return ((CORE.Window.flags & flag) > 0); + return (FLAG_IS_SET(CORE.Window.flags, flag)); } // Get current screen width @@ -1208,7 +1208,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 && ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)) + 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)); @@ -1931,7 +1931,7 @@ void SetConfigFlags(unsigned int flags) // Selected flags are set but not evaluated at this point, // flag evaluation happens at InitWindow() or SetWindowState() - CORE.Window.flags |= flags; + FLAG_SET(CORE.Window.flags, flags); } //---------------------------------------------------------------------------------- From 3cf3b309c6caff366e13ed0e8db897ca7b375bf3 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 2 Nov 2025 19:40:45 +0100 Subject: [PATCH 045/189] REVIEWED: Flags set/clear #5169 --- src/platforms/rcore_desktop_glfw.c | 8 ++++---- src/platforms/rcore_desktop_rgfw.c | 4 ++++ src/platforms/rcore_desktop_sdl.c | 10 +++++++--- src/platforms/rcore_desktop_win32.c | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 78b513b40..dbe2062a0 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1854,15 +1854,15 @@ static void WindowIconifyCallback(GLFWwindow *window, int iconified) // GLFW3 WindowMaximize Callback, runs when window is maximized/restored static void WindowMaximizeCallback(GLFWwindow *window, int maximized) { - if (maximized) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized - else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored + if (maximized) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored } // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused) { - if (focused) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was maximized - else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was restored + if (focused) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused + else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus } // GLFW3 Window Drop Callback, runs when drop files into window diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 863e57a99..177c88fc7 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -423,6 +423,10 @@ void SetWindowState(unsigned int flags) { RGFW_window_setFloating(platform.window, RGFW_TRUE); } + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) + { + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); + } if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "WINDOW: Framebuffer transparency can only be configured before window initialization"); diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 0b6376a50..841fc4479 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -588,6 +588,10 @@ void SetWindowState(unsigned int flags) { SDL_SetWindowAlwaysOnTop(platform.window, SDL_FALSE); } + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN) + { + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); + } if (FLAG_IS_SET(flags, FLAG_WINDOW_TRANSPARENT)) { TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_SDL"); @@ -1933,7 +1937,7 @@ int InitPlatform(void) FLAG_SET(flags, SDL_WINDOW_FULLSCREEN); } - //if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN); + //if (!FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIDDEN)) FLAG_SET(flags, SDL_WINDOW_HIDDEN); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_UNDECORATED)) FLAG_SET(flags, SDL_WINDOW_BORDERLESS); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_RESIZABLE)) FLAG_SET(flags, SDL_WINDOW_RESIZABLE); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) FLAG_SET(flags, SDL_WINDOW_MINIMIZED); @@ -1943,9 +1947,9 @@ int InitPlatform(void) FLAG_CLEAR(flags, SDL_WINDOW_INPUT_FOCUS); FLAG_CLEAR(flags, SDL_WINDOW_MOUSE_FOCUS); } - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) FLAG_SET(flags, SDL_WINDOW_ALWAYS_ON_TOP); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TOPMOST)) FLAG_SET(flags, SDL_WINDOW_ALWAYS_ON_TOP); if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) FLAG_CLEAR(flags, SDL_WINDOW_MOUSE_CAPTURE); - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) FLAG_SET(flags, SDL_WINDOW_ALLOW_HIGHDPI); + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) FLAG_SET(flags, SDL_WINDOW_ALLOW_HIGHDPI); //if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_TRANSPARENT)) FLAG_SET(flags, SDL_WINDOW_TRANSPARENT); // Alternative: SDL_GL_ALPHA_SIZE = 8 //if (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_DESKTOP)) FLAG_SET(flags, SDL_WINDOW_FULLSCREEN_DESKTOP); diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 1dadd5586..ce80eb41b 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -271,7 +271,7 @@ static DWORD MakeWindowStyle(unsigned flags) // Minimized takes precedence over maximized int mized = MIZED_NONE; - if (FLAG_CHECK(flags, FLAG_WINDOW_MINIMIZED)) mized = MIZED_MIN; + if (FLAG_IS_SET(flags, FLAG_WINDOW_MINIMIZED)) mized = MIZED_MIN; if (flags & FLAG_WINDOW_MAXIMIZED) mized = MIZED_MAX; switch (mized) From 46e8343a3085ce2212dde39e9f10f98f77d516df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Sun, 2 Nov 2025 20:45:51 +0200 Subject: [PATCH 046/189] [examples] Added `core_viewport_scaling` (#5313) * example - core_viewport_scaling * Code convention update --- examples/Makefile | 1 + examples/Makefile.Web | 1 + examples/README.md | 1 + examples/core/core_viewport_scaling.c | 351 +++++++++++ examples/core/core_viewport_scaling.png | Bin 0 -> 8699 bytes examples/examples_list.txt | 1 + .../examples/core_viewport_scaling.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 27 + 8 files changed, 951 insertions(+) create mode 100644 examples/core/core_viewport_scaling.c create mode 100644 examples/core/core_viewport_scaling.png create mode 100644 projects/VS2022/examples/core_viewport_scaling.vcxproj diff --git a/examples/Makefile b/examples/Makefile index b5e968079..6fcf218ee 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -551,6 +551,7 @@ CORE = \ core/core_storage_values \ core/core_text_file_loading \ core/core_undo_redo \ + core/core_viewport_scaling \ core/core_vr_simulator \ core/core_window_flags \ core/core_window_letterbox \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 07f8d8fb8..3ac776435 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -539,6 +539,7 @@ CORE = \ core/core_storage_values \ core/core_text_file_loading \ core/core_undo_redo \ + core/core_viewport_scaling \ core/core_vr_simulator \ core/core_window_flags \ core/core_window_letterbox \ diff --git a/examples/README.md b/examples/README.md index 4d0b25d56..28a2107e4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -64,6 +64,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [core_high_dpi](core/core_high_dpi.c) | core_high_dpi | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) | | [core_render_texture](core/core_render_texture.c) | core_render_texture | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_undo_redo](core/core_undo_redo.c) | core_undo_redo | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | +| [core_viewport_scaling](core/core_viewport_scaling.c) | core_viewport_scaling | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) | | [core_input_actions](core/core_input_actions.c) | core_input_actions | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) | | [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) | diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c new file mode 100644 index 000000000..e70b89829 --- /dev/null +++ b/examples/core/core_viewport_scaling.c @@ -0,0 +1,351 @@ +/******************************************************************************************* +* +* raylib [core] example - viewport scaling +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.5, last time updated with raylib 5.5 +* +* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 Agnis Aldins (@nezvers) +* +********************************************************************************************/ + +#include "raylib.h" + +// For itteration purposes and teaching example +#define RESOLUTION_COUNT 4 + +enum ViewportType +{ + // Only upscale, useful for pixel art + KEEP_ASPECT_INTEGER, + KEEP_HEIGHT_INTEGER, + KEEP_WIDTH_INTEGER, + // Can also downscale + KEEP_ASPECT, + KEEP_HEIGHT, + KEEP_WIDTH, + // For itteration purposes and as a teaching example + VIEWPORT_TYPE_COUNT, +}; + +//-------------------------------------------------------------------------------------- +// Module Functions Declaration +//-------------------------------------------------------------------------------------- +static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); + +static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); + +static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); + +static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); + +static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); + +static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); + +static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target); + +// Example how to calculate position on RenderTexture +static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //--------------------------------------------------------- + // Preset resolutions that could be created by subdividing screen resolution + Vector2 resolutionList[RESOLUTION_COUNT] = { + (Vector2){64, 64}, + (Vector2){256, 240}, + (Vector2){320, 180}, + // 4K doesn't work with integer scaling but included for example purposes with non-integer scaling + (Vector2){3840, 2160}, + }; + int resolutionIndex = 0; + + int screenWidth = 800; + int screenHeight = 450; + int gameWidth = 64; + int gameHeight = 64; + + RenderTexture2D target = (RenderTexture2D){0}; + Rectangle sourceRect = (Rectangle){0}; + Rectangle destRect = (Rectangle){0}; + + // For displaying on GUI + const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = { + "KEEP_ASPECT_INTEGER", + "KEEP_HEIGHT_INTEGER", + "KEEP_WIDTH_INTEGER", + "KEEP_ASPECT", + "KEEP_HEIGHT", + "KEEP_WIDTH", + }; + enum ViewportType viewportType = KEEP_ASPECT_INTEGER; + + SetConfigFlags(FLAG_WINDOW_RESIZABLE); + InitWindow(screenWidth, screenHeight, "raylib [core] example - Viewport Scaling"); + ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //---------------------------------------------------------- + + // Button rectangles + Rectangle decreaseResolutionButton = (Rectangle){200, 30, 10, 10}; + Rectangle increaseResolutionButton = (Rectangle){215, 30, 10, 10}; + Rectangle decreaseTypeButton = (Rectangle){200, 45, 10, 10}; + Rectangle increaseTypeButton = (Rectangle){215, 45, 10, 10}; + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //----------------------------------------------------- + if (IsWindowResized()){ + ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + } + Vector2 mousePosition = GetMousePosition(); + bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT); + + // Check buttons and rescale + if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed){ + resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1) % RESOLUTION_COUNT; + gameWidth = resolutionList[resolutionIndex].x; + gameHeight = 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; + ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + } + if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed){ + viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1) % VIEWPORT_TYPE_COUNT; + ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + } + if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed){ + viewportType = (viewportType + 1) % VIEWPORT_TYPE_COUNT; + ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + } + + Vector2 textureMousePosition = Screen2RenderTexturePosition(mousePosition, &sourceRect, &destRect); + + // Draw + //----------------------------------------------------- + // Draw our scene to the render texture + BeginTextureMode(target); + ClearBackground(WHITE); + DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.f, LIME); + + + EndTextureMode(); + + // Draw render texture to main framebuffer + BeginDrawing(); + ClearBackground(BLACK); + + // Draw our render texture with rotation applied + const Vector2 ORIGIN_POSITION = (Vector2){ 0.0f, 0.0f }; + const float ROTATION = 0.f; + DrawTexturePro(target.texture, sourceRect, destRect, ORIGIN_POSITION, ROTATION, WHITE); + + // Draw Native resolution (GUI or anything) + // 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); + + DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK); + DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK); + + DrawText(TextFormat("Type: %s", ViewportTypeNames[viewportType]), 15, 45, 10, BLACK); + Vector2 scaleRatio = (Vector2){destRect.width / sourceRect.width, destRect.height / -sourceRect.height}; + if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f) + { + DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK); + } + else + { + DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK); + } + DrawText(TextFormat("Source size: %.2f x %.2f", sourceRect.width, -sourceRect.height), 15, 75, 10, BLACK); + DrawText(TextFormat("Destination size: %.2f x %.2f", destRect.width, destRect.height), 15, 90, 10, BLACK); + + // Draw buttons + DrawRectangleRec(decreaseTypeButton, SKYBLUE); + DrawRectangleRec(increaseTypeButton, SKYBLUE); + DrawRectangleRec(decreaseResolutionButton, SKYBLUE); + DrawRectangleRec(increaseResolutionButton, SKYBLUE); + DrawText("<", decreaseTypeButton.x + 3, decreaseTypeButton.y + 1, 10, BLACK); + DrawText(">", increaseTypeButton.x + 3, increaseTypeButton.y + 1, 10, BLACK); + DrawText("<", decreaseResolutionButton.x + 3, decreaseResolutionButton.y + 1, 10, BLACK); + DrawText(">", increaseResolutionButton.x + 3, increaseResolutionButton.y + 1, 10, BLACK); + + EndDrawing(); + //----------------------------------------------------- + } + + // De-Initialization + //--------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //---------------------------------------------------------- + + return 0; +} + +//-------------------------------------------------------------------------------------- +// Module Functions Definition +//-------------------------------------------------------------------------------------- +static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) +{ + sourceRect->x = 0.f; + sourceRect->y = (float)gameHeight; + sourceRect->width = (float)gameWidth; + sourceRect->height = (float)-gameHeight; + + const int ratio_x = (screenWidth/gameWidth); + const int ratio_y = (screenHeight/gameHeight); + const float resizeRatio = (float)(ratio_x < ratio_y ? ratio_x : ratio_y); + + destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); + destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); + destRect->width = (float)(int)(gameWidth * resizeRatio); + destRect->height = (float)(int)(gameHeight * resizeRatio); +} + +static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) +{ + const float resizeRatio = (float)(screenHeight/gameHeight); + sourceRect->x = 0.f; + sourceRect->y = 0.f; + sourceRect->width = (float)(int)(screenWidth / resizeRatio); + sourceRect->height = (float)-gameHeight; + + destRect->x = (float)(int)((screenWidth - (sourceRect->width * resizeRatio)) * 0.5); + destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); + destRect->width = (float)(int)(sourceRect->width * resizeRatio); + destRect->height = (float)(int)(gameHeight * resizeRatio); +} + +static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) +{ + const float resizeRatio = (float)(screenWidth/gameWidth); + sourceRect->x = 0.f; + sourceRect->y = 0.f; + sourceRect->width = (float)gameWidth; + sourceRect->height = (float)(int)(screenHeight / resizeRatio); + + destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); + destRect->y = (float)(int)((screenHeight - (sourceRect->height * resizeRatio)) * 0.5); + destRect->width = (float)(int)(gameWidth * resizeRatio); + destRect->height = (float)(int)(sourceRect->height * resizeRatio); + + sourceRect->height *= -1.f; +} + +static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) +{ + sourceRect->x = 0.f; + sourceRect->y = (float)gameHeight; + sourceRect->width = (float)gameWidth; + sourceRect->height = (float)-gameHeight; + + const float ratio_x = ((float)screenWidth/(float)gameWidth); + const float ratio_y = ((float)screenHeight/(float)gameHeight); + const float resizeRatio = (ratio_x < ratio_y ? ratio_x : ratio_y); + + destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); + destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); + destRect->width = (float)(int)(gameWidth * resizeRatio); + destRect->height = (float)(int)(gameHeight * resizeRatio); +} + +static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) +{ + const float resizeRatio = ((float)screenHeight/(float)gameHeight); + sourceRect->x = 0.f; + sourceRect->y = 0.f; + sourceRect->width = (float)(int)((float)screenWidth / resizeRatio); + sourceRect->height = (float)-gameHeight; + + destRect->x = (float)(int)((screenWidth - (sourceRect->width * resizeRatio)) * 0.5); + destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); + destRect->width = (float)(int)(sourceRect->width * resizeRatio); + destRect->height = (float)(int)(gameHeight * resizeRatio); +} + +static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) +{ + const float resizeRatio = ((float)screenWidth/(float)gameWidth); + sourceRect->x = 0.f; + sourceRect->y = 0.f; + sourceRect->width = (float)gameWidth; + sourceRect->height = (float)(int)((float)screenHeight / resizeRatio); + + destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); + destRect->y = (float)(int)((screenHeight - (sourceRect->height * resizeRatio)) * 0.5); + destRect->width = (float)(int)(gameWidth * resizeRatio); + destRect->height = (float)(int)(sourceRect->height * resizeRatio); + + sourceRect->height *= -1.f; +} + +static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target) +{ + *screenWidth = GetScreenWidth(); + *screenHeight = GetScreenHeight(); + + switch(viewportType) + { + case KEEP_ASPECT_INTEGER: + { + KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); + break; + } + case KEEP_HEIGHT_INTEGER: + { + KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); + break; + } + case KEEP_WIDTH_INTEGER: + { + KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); + break; + } + case KEEP_ASPECT: + { + KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); + break; + } + case KEEP_HEIGHT: + { + KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); + break; + } + case KEEP_WIDTH: + { + KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); + break; + } + default: {} + } + UnloadRenderTexture(*target); + *target = LoadRenderTexture(sourceRect->width, -sourceRect->height); +} + +// Example how to calculate position on RenderTexture +static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect) +{ + Vector2 relativePosition = {point.x - scaledRect->x, point.y - scaledRect->y}; + Vector2 ratio = {textureRect->width / scaledRect->width, -textureRect->height / scaledRect->height}; + + return (Vector2){relativePosition.x * ratio.x, relativePosition.y * ratio.x}; +} \ No newline at end of file diff --git a/examples/core/core_viewport_scaling.png b/examples/core/core_viewport_scaling.png new file mode 100644 index 0000000000000000000000000000000000000000..68fad6209adf6ec0967b0ddb737a749b512c880c GIT binary patch literal 8699 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 + + + + 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 + + + + {AD66AA6A-1E36-4FF0-8670-4F9834BCDB91} + Win32Proj + core_viewport_scaling + 10.0 + core_viewport_scaling + + + + 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 c15632182..8ace665a9 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -405,6 +405,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_decals", "examples\m 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5027,6 +5029,30 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5231,6 +5257,7 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From cc83b2bd8e272c889ad2f5e6ee88f075be5a6642 Mon Sep 17 00:00:00 2001 From: Tiago Ferreira Date: Sun, 2 Nov 2025 18:46:57 +0000 Subject: [PATCH 047/189] fix: cursor lock/unlock inconsistent behaviour on glfw, rgfw, sl (#5323) --- src/platforms/rcore_desktop_glfw.c | 2 ++ src/platforms/rcore_desktop_rgfw.c | 7 +++++-- src/platforms/rcore_desktop_sdl.c | 11 ++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index dbe2062a0..c67b91845 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1070,6 +1070,7 @@ void EnableCursor(void) if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); + CORE.Input.Mouse.cursorHidden = false; CORE.Input.Mouse.cursorLocked = false; } @@ -1083,6 +1084,7 @@ void DisableCursor(void) if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); + CORE.Input.Mouse.cursorHidden = true; CORE.Input.Mouse.cursorLocked = true; } diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 177c88fc7..47160af54 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -838,8 +838,9 @@ void EnableCursor(void) // Set cursor position in the middle SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); - RGFW_window_showMouse(platform.window, true); - CORE.Input.Mouse.cursorHidden = false; + ShowCursor(); + + CORE.Input.Mouse.cursorLocked = true; } // Disables cursor (lock cursor) @@ -848,6 +849,8 @@ void DisableCursor(void) RGFW_disableCursor = true; RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0)); HideCursor(); + + CORE.Input.Mouse.cursorLocked = true; } // Swap back buffer with front buffer (screen drawing) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 841fc4479..99ef6338c 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1237,13 +1237,7 @@ void EnableCursor(void) { SDL_SetRelativeMouseMode(SDL_FALSE); -#if defined(USING_VERSION_SDL3) - // NOTE: SDL_ShowCursor() has been split into three functions: - // SDL_ShowCursor(), SDL_HideCursor(), and SDL_CursorVisible() - SDL_ShowCursor(); -#else - SDL_ShowCursor(SDL_ENABLE); -#endif + ShowCursor(); CORE.Input.Mouse.cursorLocked = false; } @@ -1253,6 +1247,9 @@ void DisableCursor(void) { SDL_SetRelativeMouseMode(SDL_TRUE); + HideCursor(); + + platform.cursorRelative = true; CORE.Input.Mouse.cursorLocked = true; } From 81004135a46b68e17a401d8ff203d5cc52a5a397 Mon Sep 17 00:00:00 2001 From: EDBC_REPO <109326461+EDBCREPO@users.noreply.github.com> Date: Sun, 2 Nov 2025 14:48:11 -0400 Subject: [PATCH 048/189] adding Matrix MatrixCompose( translate, rotation, scale ) to raymath.h (#5324) --- src/raymath.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/raymath.h b/src/raymath.h index 65a20de59..9a9aa8be2 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -2552,6 +2552,38 @@ RMAPI int QuaternionEquals(Quaternion p, Quaternion q) return result; } +// Compose a transformation matrix from rotational, translational and scaling components +RMAPI Matrix MatrixCompose( Vector3 translation, Quaternion rotation, Vector3 scale ) +{ + + //Initialize Vectors + Vector3 right = { 1, 0, 0 }; + Vector3 up = { 0, 1, 0 }; + Vector3 forward = { 0, 0, 1 }; + + //Scale Vectors + right = Vector3Scale( right , scale.x ); + up = Vector3Scale( up , scale.y ); + forward = Vector3Scale( forward , scale.z ); + + //Rotate Vectors + right = Vector3RotateByQuaternion( right , rotation ); + up = Vector3RotateByQuaternion( up , rotation ); + forward = Vector3RotateByQuaternion( forward, rotation ); + + // Set matrix output + Matrix result = { + right.x, up.x, forward.x, position.x, + right.y, up.y, forward.y, position.y, + right.z, up.z, forward.z, position.z, + 0, 0, 0, 1 + }; + + // Return matrix output + return result; + +} + // Decompose a transformation matrix into its rotational, translational and scaling components and remove shear RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotation, Vector3 *scale) { From 87d49262f828c957059b766bc7aba9a2124310ee Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 2 Nov 2025 19:53:45 +0100 Subject: [PATCH 049/189] REVIEWED: raymath: `MatrixCompose()` --- src/raymath.h | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 9a9aa8be2..1e1565426 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -2553,38 +2553,37 @@ RMAPI int QuaternionEquals(Quaternion p, Quaternion q) } // Compose a transformation matrix from rotational, translational and scaling components -RMAPI Matrix MatrixCompose( Vector3 translation, Quaternion rotation, Vector3 scale ) +// TODO: This function is not following raymath conventions defined in header: NOT self-contained +RMAPI Matrix MatrixCompose(Vector3 translation, Quaternion rotation, Vector3 scale) { + // Initialize vectors + Vector3 right = { 1.0f, 0.0f, 0.0f }; + Vector3 up = { 0.0f, 1.0f, 0.0f }; + Vector3 forward = { 0.0f, 0.0f, 1.0f }; - //Initialize Vectors - Vector3 right = { 1, 0, 0 }; - Vector3 up = { 0, 1, 0 }; - Vector3 forward = { 0, 0, 1 }; + // Scale vectors + right = Vector3Scale(right, scale.x); + up = Vector3Scale(up, scale.y); + forward = Vector3Scale(forward , scale.z); - //Scale Vectors - right = Vector3Scale( right , scale.x ); - up = Vector3Scale( up , scale.y ); - forward = Vector3Scale( forward , scale.z ); - - //Rotate Vectors - right = Vector3RotateByQuaternion( right , rotation ); - up = Vector3RotateByQuaternion( up , rotation ); - forward = Vector3RotateByQuaternion( forward, rotation ); + // Rotate vectors + right = Vector3RotateByQuaternion(right, rotation); + up = Vector3RotateByQuaternion(up, rotation); + forward = Vector3RotateByQuaternion(forward, rotation); - // Set matrix output + // Set result matrix output Matrix result = { right.x, up.x, forward.x, position.x, right.y, up.y, forward.y, position.y, right.z, up.z, forward.z, position.z, - 0, 0, 0, 1 + 0.0f, 0.0f, 0.0f, 1.0f }; - // Return matrix output return result; - } // Decompose a transformation matrix into its rotational, translational and scaling components and remove shear +// TODO: This function is not following raymath conventions defined in header: NOT self-contained RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotation, Vector3 *scale) { float eps = (float)1e-9; @@ -2619,10 +2618,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio // X Scale scl.x = Vector3Length(matColumns[0]); - if (scl.x > eps) - { - matColumns[0] = Vector3Scale(matColumns[0], 1.0f / scl.x); - } + if (scl.x > eps) matColumns[0] = Vector3Scale(matColumns[0], 1.0f / scl.x); // Compute XY shear and make col2 orthogonal shear[0] = Vector3DotProduct(matColumns[0], matColumns[1]); From ee3be5799a1858be98d6afe7e0aedfcea975eaa3 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 2 Nov 2025 19:59:46 +0100 Subject: [PATCH 050/189] Update raymath.h --- src/raymath.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index 1e1565426..32dfd2b0a 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -2573,9 +2573,9 @@ RMAPI Matrix MatrixCompose(Vector3 translation, Quaternion rotation, Vector3 sca // Set result matrix output Matrix result = { - right.x, up.x, forward.x, position.x, - right.y, up.y, forward.y, position.y, - right.z, up.z, forward.z, position.z, + 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 }; From 91addeb889d10d0df12e09bd2780802bf2417622 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 2 Nov 2025 20:04:43 +0100 Subject: [PATCH 051/189] 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 f45ce9be3..4e417e987 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -50,12 +50,12 @@ #include "raylib.h" -#include +#include // Required for: NULL, calloc(), free() #include // Required for: rename(), remove() #include // Required for: strcmp(), strcpy() #define SUPPORT_LOG_INFO -#if defined(SUPPORT_LOG_INFO) && defined(_DEBUG) +#if defined(SUPPORT_LOG_INFO) //&& defined(_DEBUG) #define LOG(...) printf("REXM: "__VA_ARGS__) #else #define LOG(...) From ed68a4fccef55fe7feaa12d3dd27347aa9969bd3 Mon Sep 17 00:00:00 2001 From: komunre <49118681+komunre@users.noreply.github.com> Date: Mon, 3 Nov 2025 15:43:20 +0700 Subject: [PATCH 052/189] Fixed bugs in SDL backend (#5325) --- src/platforms/rcore_desktop_sdl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 99ef6338c..b1ca43a60 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -588,7 +588,7 @@ void SetWindowState(unsigned int flags) { SDL_SetWindowAlwaysOnTop(platform.window, SDL_FALSE); } - if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN) + if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) { FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN); } @@ -1249,7 +1249,9 @@ void DisableCursor(void) HideCursor(); - platform.cursorRelative = true; + // ???? + //platform.cursorRelative = true; + CORE.Input.Mouse.cursorHidden = true; CORE.Input.Mouse.cursorLocked = true; } From cfb43fa9991f6e44be178f61f407749cc613250d Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 3 Nov 2025 09:45:18 +0100 Subject: [PATCH 053/189] Update rcore_desktop_sdl.c --- src/platforms/rcore_desktop_sdl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index b1ca43a60..f7ee57ee4 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1238,7 +1238,6 @@ void EnableCursor(void) SDL_SetRelativeMouseMode(SDL_FALSE); ShowCursor(); - CORE.Input.Mouse.cursorLocked = false; } @@ -1248,10 +1247,6 @@ void DisableCursor(void) SDL_SetRelativeMouseMode(SDL_TRUE); HideCursor(); - - // ???? - //platform.cursorRelative = true; - CORE.Input.Mouse.cursorHidden = true; CORE.Input.Mouse.cursorLocked = true; } From e92832fc6d7046946d1bfb0623a3141a351b864c Mon Sep 17 00:00:00 2001 From: NoNameAuthenticated Date: Tue, 4 Nov 2025 11:50:54 -0500 Subject: [PATCH 054/189] Update rcore_desktop_sdl.c (#5332) --- src/platforms/rcore_desktop_sdl.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index f7ee57ee4..cf11037cb 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -463,7 +463,7 @@ void ToggleFullscreen(void) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -491,7 +491,7 @@ void ToggleBorderlessWindowed(void) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -548,7 +548,7 @@ void SetWindowState(unsigned int flags) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -612,7 +612,7 @@ void SetWindowState(unsigned int flags) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -833,7 +833,7 @@ void SetWindowMonitor(int monitor) { const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -961,7 +961,7 @@ Vector2 GetMonitorPosition(int monitor) { const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -989,7 +989,7 @@ int GetMonitorWidth(int monitor) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -1010,7 +1010,7 @@ int GetMonitorHeight(int monitor) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -1031,7 +1031,7 @@ int GetMonitorPhysicalWidth(int monitor) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -1055,7 +1055,7 @@ int GetMonitorPhysicalHeight(int monitor) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -1079,7 +1079,7 @@ int GetMonitorRefreshRate(int monitor) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif @@ -1099,7 +1099,7 @@ const char *GetMonitorName(int monitor) const int monitorCount = SDL_GetNumVideoDisplays(); #if defined(USING_VERSION_SDL3) // SDL3 Migration: Monitor is an id instead of index now, returns 0 on failure - if ((monitor > 0) && (monitor <= monitorCount)) + if (SDL_GetDisplayProperties(monitor) != 0) // Returns 0 on failure, so a value other than zero indicates that the monitor id is valid #else if ((monitor >= 0) && (monitor < monitorCount)) #endif From 48c1619d208c07a01ff913d9c5ab86403ab2db27 Mon Sep 17 00:00:00 2001 From: iann Date: Tue, 4 Nov 2025 10:52:53 -0600 Subject: [PATCH 055/189] added consistent behavior for texture in opengl11 draw states and fixed loadobj texcoord behavior for opengl11 context (#5328) --- src/rmodels.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/rmodels.c b/src/rmodels.c index ed86fb19a..c09a94652 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1435,7 +1435,7 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform) #define GL_COLOR_ARRAY 0x8076 #define GL_TEXTURE_COORD_ARRAY 0x8078 - rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id); + if (mesh.texcoords && material.maps[MATERIAL_MAP_DIFFUSE].texture.id > 0) rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id); if (mesh.animVertices) rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.animVertices); else rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.vertices); @@ -4429,10 +4429,12 @@ static Model LoadOBJ(const char *fileName) model.meshes[i].vertices = (float *)MemAlloc(sizeof(float)*vertexCount*3); model.meshes[i].normals = (float *)MemAlloc(sizeof(float)*vertexCount*3); - model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2); #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2); model.meshes[i].colors = (unsigned char *)MemAlloc(sizeof(unsigned char)*vertexCount*4); #else + if (objAttributes.texcoords != NULL && objAttributes.num_texcoords > 0) model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2); + else model.meshes[i].texcoords = NULL; model.meshes[i].colors = NULL; #endif } @@ -4488,16 +4490,11 @@ static Model LoadOBJ(const char *fileName) for (int i = 0; i < 3; i++) model.meshes[meshIndex].vertices[localMeshVertexCount*3 + i] = objAttributes.vertices[vertIndex*3 + i]; - if ((objAttributes.texcoords != NULL) && (texcordIndex != TINYOBJ_INVALID_INDEX) && (texcordIndex >= 0)) + if ((objAttributes.texcoords != NULL) && (texcordIndex != TINYOBJ_INVALID_INDEX) && (texcordIndex >= 0) && (model.meshes[meshIndex].texcoords)) { for (int i = 0; i < 2; i++) model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + i] = objAttributes.texcoords[texcordIndex*2 + i]; model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1]; } - else - { - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 0] = 0.0f; - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1] = 0.0f; - } if ((objAttributes.normals != NULL) && (normalIndex != TINYOBJ_INVALID_INDEX) && (normalIndex >= 0)) { From 12ce106661bc9c8f74ea3f3069291e5fc4e7d50a Mon Sep 17 00:00:00 2001 From: JohnnyCena123 Date: Tue, 4 Nov 2025 19:17:37 +0200 Subject: [PATCH 056/189] [rcore][glfw] fix `IsWindowFocused()` inverted logic (#5333) --- src/platforms/rcore_desktop_glfw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index c67b91845..bf383031b 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1863,8 +1863,8 @@ static void WindowMaximizeCallback(GLFWwindow *window, int maximized) // GLFW3 WindowFocus Callback, runs when window get/lose focus static void WindowFocusCallback(GLFWwindow *window, int focused) { - if (focused) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused - else FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus + if (focused) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window was focused + else FLAG_SET(CORE.Window.flags, FLAG_WINDOW_UNFOCUSED); // The window lost focus } // GLFW3 Window Drop Callback, runs when drop files into window From 3843f771fbac00e1c028ce2ec552b36ba34c1de5 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:51:18 +0100 Subject: [PATCH 057/189] Update core_clipboard_text.c --- examples/core/core_clipboard_text.c | 30 ++++++++--------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/examples/core/core_clipboard_text.c b/examples/core/core_clipboard_text.c index 2be64154b..c9d22c54a 100644 --- a/examples/core/core_clipboard_text.c +++ b/examples/core/core_clipboard_text.c @@ -31,14 +31,14 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text"); - const char* clipboardText = NULL; + const char *clipboardText = NULL; // List of text the user can switch through and copy - const char* copyableText[] = {"raylib is fun", "hello, clipboard!", "potato chips"}; + const char *copyableText[] = { "raylib is fun", "hello, clipboard!", "potato chips" }; unsigned int textIndex = 0; - const char* popupText = NULL; + const char *popupText = NULL; // Initialize timers // The amount of time the pop-up text is on screen, before fading @@ -53,6 +53,8 @@ int main(void) float textAlpha = 0.0f; // Offset amount for animations const int offsetAmount = -4; + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -70,7 +72,6 @@ int main(void) if (copyAnim > 0) copyAnim -= GetFrameTime(); if (textAnim > 0) textAnim -= GetFrameTime(); - // React to the user pressing paste if (pastePressed) { // Most operating systems hide this information until the user presses Ctrl-V on the window. @@ -81,17 +82,13 @@ int main(void) if (IsImageValid(image)) { - // Unload the image UnloadImage(image); - // Update visuals popupText = "clipboard contains image"; } else { - // Get text from the user's clipboard clipboardText = GetClipboardText(); - // Update visuals popupText = "text pasted"; pasteAnim = animMaxTime; } @@ -114,7 +111,6 @@ int main(void) copyAnim = animMaxTime; copyAnimMult = 1; textAlpha = 1; - // Update the text that pops up at the bottom of the screen popupText = "text copied"; } @@ -141,15 +137,8 @@ int main(void) copyAnim = animMaxTime; copyAnimMult = -1; - if (textIndex == 0) - { - // Loop back to the other end - textIndex = (sizeof(copyableText) / sizeof(const char*)) - 1; // Length of array minus one - } - else - { - textIndex -= 1; - } + if (textIndex == 0) textIndex = (sizeof(copyableText)/sizeof(const char*)) - 1; + else textIndex -= 1; } //---------------------------------------------------------------------------------- @@ -189,10 +178,7 @@ int main(void) DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha)); // Fade-out animation - if (textTimer < 0) - { - textAlpha -= GetFrameTime(); - } + if (textTimer < 0) textAlpha -= GetFrameTime(); } EndDrawing(); From 9ff87b38b830324a5d085cc02eb0127320d7f06e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:51:23 +0100 Subject: [PATCH 058/189] Update raygui.h --- examples/core/raygui.h | 870 ++++++++++++++++++++++++++--------------- 1 file changed, 556 insertions(+), 314 deletions(-) diff --git a/examples/core/raygui.h b/examples/core/raygui.h index a3fc51f0f..17ced6ef5 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -4,7 +4,7 @@ * * 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. +* available as a standalone library, as long as input and drawing functions are provided * * FEATURES: * - Immediate-mode gui, minimal retained data @@ -27,7 +27,7 @@ * - 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). +* by default any previously loaded font (texture, recs, glyphs) * - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions * * CONTROLS PROVIDED: @@ -65,7 +65,7 @@ * - 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). +* It also provides a set of functions for styling the controls based on its properties (size, color) * * * RAYGUI STYLE (guiStyle): @@ -81,7 +81,7 @@ * * 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. +* 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) @@ -100,7 +100,7 @@ * 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. +* 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: * @@ -112,20 +112,20 @@ * * 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. +* 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. +* 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 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). +* 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) @@ -141,12 +141,17 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 4.5-dev (Sep-2024) Current dev version... +* 5.0-dev (2025) Current dev version... * ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes * ADDED: GuiValueBoxFloat() * ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP * ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH +* ADDED: GuiLoadIconsFromMemory() * ADDED: Multiple new icons +* 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 @@ -156,6 +161,8 @@ * 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 * @@ -259,16 +266,16 @@ * 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. +* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria +* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria +* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria * * DEPENDENCIES: * raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing * * STANDALONE MODE: * By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled -* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs. +* 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: * @@ -309,7 +316,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -334,7 +341,7 @@ #define RAYGUI_VERSION_MAJOR 4 #define RAYGUI_VERSION_MINOR 5 #define RAYGUI_VERSION_PATCH 0 -#define RAYGUI_VERSION "4.5-dev" +#define RAYGUI_VERSION "5.0-dev" #if !defined(RAYGUI_STANDALONE) #include "raylib.h" @@ -358,17 +365,6 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// Allow custom memory allocators -#ifndef RAYGUI_MALLOC - #define RAYGUI_MALLOC(sz) malloc(sz) -#endif -#ifndef RAYGUI_CALLOC - #define RAYGUI_CALLOC(n,sz) calloc(n,sz) -#endif -#ifndef RAYGUI_FREE - #define RAYGUI_FREE(p) free(p) -#endif - // Simple log system to avoid printf() calls if required // NOTE: Avoiding those calls, also avoids const strings memory usage #define RAYGUI_SUPPORT_LOG_INFO @@ -421,13 +417,16 @@ // TODO: Texture2D type is very coupled to raylib, required by Font type // It should be redesigned to be provided by user - typedef struct Texture2D { + 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) - } Texture2D; + } Texture; + + // Texture2D, same as Texture + typedef Texture Texture2D; // Image, pixel data stored in CPU memory (RAM) typedef struct Image { @@ -527,7 +526,7 @@ typedef enum { DROPDOWNBOX, TEXTBOX, // Used also for: TEXTBOXMULTI VALUEBOX, - SPINNER, // Uses: BUTTON, VALUEBOX + CONTROL11, LISTVIEW, COLORPICKER, SCROLLBAR, @@ -549,12 +548,12 @@ typedef enum { BORDER_COLOR_DISABLED, // Control border color in STATE_DISABLED BASE_COLOR_DISABLED, // Control base color in STATE_DISABLED TEXT_COLOR_DISABLED, // Control text color in STATE_DISABLED - BORDER_WIDTH, // Control border size, 0 for no border + 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, // Control text padding, not considering border - TEXT_ALIGNMENT, // Control text horizontal alignment inside control text bound (after border and padding) + //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; @@ -641,11 +640,14 @@ typedef enum { TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable } GuiTextBoxProperty; -// Spinner +// ValueBox/Spinner typedef enum { - SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width - SPIN_BUTTON_SPACING, // Spinner buttons separation -} GuiSpinnerProperty; + SPINNER_BUTTON_WIDTH = 16, // Spinner left/right buttons width + SPINNER_BUTTON_SPACING, // Spinner buttons separation +} GuiValueBoxProperty; + +// Control11 +//typedef enum { } GuiControl11Property; // ListView typedef enum { @@ -653,6 +655,7 @@ typedef enum { 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; @@ -717,6 +720,9 @@ RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load 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 @@ -999,11 +1005,11 @@ typedef enum { ICON_MLAYERS = 226, ICON_MAPS = 227, ICON_HOT = 228, - ICON_229 = 229, - ICON_230 = 230, - ICON_231 = 231, - ICON_232 = 232, - ICON_233 = 233, + ICON_LABEL = 229, + ICON_NAME_ID = 230, + ICON_SLICING = 231, + ICON_MANUAL_CONTROL = 232, + ICON_COLLISION = 233, ICON_234 = 234, ICON_235 = 235, ICON_236 = 236, @@ -1046,12 +1052,24 @@ typedef enum { #if defined(RAYGUI_IMPLEMENTATION) #include // required for: isspace() [GuiTextBox()] -#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()] -#include // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()] +#include // Required for: 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 @@ -1318,11 +1336,11 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x422a422a, 0x422e422a, 0x40384e28, 0x00007fe0, // ICON_MLAYERS 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x5b2a512a, 0x512e552a, 0x40385128, 0x00007fe0, // ICON_MAPS 0x04200000, 0x1cf00c60, 0x11f019f0, 0x0f3807b8, 0x1e3c0f3c, 0x1c1c1e1c, 0x1e3c1c1c, 0x00000f70, // ICON_HOT - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_229 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_230 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_231 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_232 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_233 + 0x00000000, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236 @@ -1363,7 +1381,7 @@ static unsigned int *guiIconsPtr = guiIcons; #define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties //---------------------------------------------------------------------------------- -// Types and Structures Definition +// Module Types and Structures Definition //---------------------------------------------------------------------------------- // Gui control property style color element typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement; @@ -1387,8 +1405,7 @@ static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() //static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking -static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down -static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement +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) @@ -1484,7 +1501,6 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co //---------------------------------------------------------------------------------- static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only) -static int GetTextWidth(const char *text); // Gui get text width using gui font and style static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor @@ -1589,6 +1605,10 @@ int GuiWindowBox(Rectangle bounds, const char *title) #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; @@ -1597,9 +1617,10 @@ int GuiWindowBox(Rectangle bounds, const char *title) 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) - 20, - statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18 }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; // Update control //-------------------------------------------------------------------- @@ -1653,7 +1674,7 @@ int GuiGroupBox(Rectangle bounds, const char *text) // Line control int GuiLine(Rectangle bounds, const char *text) { - #if !defined(RAYGUI_LINE_ORIGIN_SIZE) + #if !defined(RAYGUI_LINE_MARGIN_TEXT) #define RAYGUI_LINE_MARGIN_TEXT 12 #endif #if !defined(RAYGUI_LINE_TEXT_PADDING) @@ -1671,7 +1692,7 @@ int GuiLine(Rectangle bounds, const char *text) else { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.width = (float)GuiGetTextWidth(text) + 2; textBounds.height = bounds.height; textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT; textBounds.y = bounds.y; @@ -1711,8 +1732,8 @@ int GuiPanel(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar - GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED: (int)LINE_COLOR)), - GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR))); + 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; @@ -2011,7 +2032,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) bool pressed = false; // NOTE: We force bounds.width to be all text - float textWidth = (float)GetTextWidth(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 @@ -2149,7 +2170,9 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + const char **items = NULL; + + if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle slider = { 0, // Calculated later depending on the active toggle @@ -2196,7 +2219,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) if (text != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(text); + 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; @@ -2221,7 +2244,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -2474,7 +2497,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) - #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement + #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 @@ -2487,10 +2510,10 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); - int textLength = (int)strlen(text); // Get current text length + int textLength = (text != NULL)? (int)strlen(text) : 0; // Get current text length int thisCursorIndex = textBoxCursorIndex; if (thisCursorIndex > textLength) thisCursorIndex = textLength; - int textWidth = GetTextWidth(text) - GetTextWidth(text + thisCursorIndex); + int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); int textIndexOffset = 0; // Text index offset to start drawing in the box // Cursor rectangle @@ -2511,15 +2534,6 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) mouseCursor.x = -1; mouseCursor.width = 1; - // Auto-cursor movement logic - // NOTE: Cursor moves automatically when key down after some time - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCooldownCounter++; - else - { - autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter - autoCursorDelayCounter = 0; // GLOBAL: Cursor delay counter - } - // Blink-cursor frame counter //if (!autoCursorMode) blinkCursorFrameCounter++; //else blinkCursorFrameCounter = 0; @@ -2537,6 +2551,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) 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++; + 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; @@ -2550,7 +2571,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textIndexOffset += nextCodepointSize; - textWidth = GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex); + textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); } int codepoint = GetCharPressed(); // Get Unicode codepoint @@ -2560,10 +2581,43 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int codepointSize = 0; const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); - // Add codepoint to text, at current cursor position - // NOTE: Make sure we do not overflow buffer size - if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) + // Handle text paste action + if (IsKeyPressed(KEY_V) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(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]; @@ -2583,113 +2637,185 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Move cursor to end if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; - // Delete codepoint from text, after current cursor position - if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + // Delete related codepoints from text, after current cursor position + if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_DELETE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - autoCursorDelayCounter++; + int offset = textBoxCursorIndex; + int accCodepointSize = 0; + int nextCodepointSize; + int nextCodepoint; - if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + // 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) { - int nextCodepointSize = 0; - GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); - - // Move backward text from cursor position - for (int i = textBoxCursorIndex; i < textLength; i++) text[i] = text[i + nextCodepointSize]; - - textLength -= codepointSize; - if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; - - // Make sure text last character is EOL - text[textLength] = '\0'; + 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) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(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 ((textLength > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - int i = textBoxCursorIndex - 1; + int offset = textBoxCursorIndex; int accCodepointSize = 0; + int prevCodepointSize; + int prevCodepoint; - // Move cursor to the end of word if on space already - while ((i > 0) && isspace(text[i])) + // Check whitespace to delete (ASCII only) + while (offset > 0) { - int prevCodepointSize = 0; - GetCodepointPrevious(text + i, &prevCodepointSize); - i -= prevCodepointSize; + 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 cursor to the start of the word - while ((i > 0) && !isspace(text[i])) - { - int prevCodepointSize = 0; - GetCodepointPrevious(text + i, &prevCodepointSize); - i -= prevCodepointSize; - accCodepointSize += prevCodepointSize; - } + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex; i <= textLength; i++) text[i - accCodepointSize] = text[i]; - // Move forward text from cursor position - for (int j = (textBoxCursorIndex - accCodepointSize); j < textLength; j++) text[j] = text[j + accCodepointSize]; - - // Prevent cursor index from decrementing past 0 - if (textBoxCursorIndex > 0) - { - textBoxCursorIndex -= accCodepointSize; - textLength -= accCodepointSize; - } - - // Make sure text last character is EOL - text[textLength] = '\0'; - } - else if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + textLength -= accCodepointSize; + textBoxCursorIndex -= accCodepointSize; + } + + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) { - autoCursorDelayCounter++; + // Delete single codepoint from text, before current cursor position + + int prevCodepointSize = 0; - if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames - { - int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - // Prevent cursor index from decrementing past 0 - if (textBoxCursorIndex > 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]; - // Move backward text from cursor position - for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize]; - - textBoxCursorIndex -= codepointSize; - textLength -= codepointSize; - } - - // Make sure text last character is EOL - text[textLength] = '\0'; - } + textLength -= prevCodepointSize; + textBoxCursorIndex -= prevCodepointSize; } // Move cursor position with keys - if (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_LEFT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - autoCursorDelayCounter++; + int offset = textBoxCursorIndex; + //int accCodepointSize = 0; + int prevCodepointSize; + int prevCodepoint; - if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + // Check whitespace to skip (ASCII only) + while (offset > 0) { - int prevCodepointSize = 0; - if (textBoxCursorIndex > 0) GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if (!isspace(prevCodepoint & 0xff)) break; - if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize; + 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 (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && autoCursorShouldTrigger))) { - autoCursorDelayCounter++; + int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + textBoxCursorIndex -= prevCodepointSize; + } + else if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_RIGHT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(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) { - int nextCodepointSize = 0; - GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) break; - if ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize; + 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) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger))) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + textBoxCursorIndex += nextCodepointSize; } // Move cursor position with mouse @@ -2701,7 +2827,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) float widthToMouseX = 0; int mouseCursorIndex = 0; - for (int i = textIndexOffset; i < textLength; i++) + for (int i = textIndexOffset; i < textLength; i += codepointSize) { codepoint = GetCodepointNext(&text[i], &codepointSize); codepointIndex = GetGlyphIndex(guiFont, codepoint); @@ -2720,7 +2846,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Check if mouse cursor is at the last position - int textEndWidth = GetTextWidth(text + textIndexOffset); + int textEndWidth = GuiGetTextWidth(text + textIndexOffset); if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; @@ -2737,7 +2863,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) else mouseCursor.x = -1; // Recalculate cursor position.y depending on textBoxCursorIndex - cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING); + 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 @@ -2745,6 +2871,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) { textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes result = 1; } } @@ -2757,6 +2884,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes result = 1; } } @@ -2825,19 +2953,22 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int int tempValue = *value; - Rectangle spinner = { bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING), bounds.y, - bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING)), bounds.height }; - Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; - Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; + Rectangle 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)GetTextWidth(text) + 2; + textBounds.width = (float)GuiGetTextWidth(text) + 2; textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); - textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; - if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING); + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); } // Update control @@ -2871,20 +3002,20 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int // Draw control //-------------------------------------------------------------------- - result = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode); + 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(SPINNER, BORDER_WIDTH)); + 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(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); //-------------------------------------------------------------------- *value = tempValue; @@ -2903,12 +3034,12 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in GuiState state = guiState; char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; - sprintf(textValue, "%i", *value); + snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value); Rectangle textBounds = { 0 }; if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -2929,10 +3060,37 @@ 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 (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 (GetTextWidth(textValue) < bounds.width) + if (GuiGetTextWidth(textValue) < bounds.width) { int key = GetCharPressed(); if ((key >= 48) && (key <= 57)) @@ -2992,11 +3150,14 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in 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 + // Draw cursor rectangle if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = { bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) }; + 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))); } @@ -3019,12 +3180,12 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float GuiState state = guiState; //char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; - //sprintf(textValue, "%2.2f", *value); + //snprintf(textValue, sizeof(textValue), "%2.2f", *value); - Rectangle textBounds = {0}; + Rectangle textBounds = { 0 }; if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -3045,10 +3206,37 @@ 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 (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 (GetTextWidth(textValue) < bounds.width) + if (GuiGetTextWidth(textValue) < bounds.width) { int key = GetCharPressed(); if (((key >= 48) && (key <= 57)) || @@ -3103,7 +3291,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = {bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, + 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))); @@ -3120,7 +3308,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float // Slider control with pro parameters // NOTE: Other GuiSlider*() controls use this one -int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth) +int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) { int result = 0; GuiState state = guiState; @@ -3129,6 +3317,8 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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) }; @@ -3146,7 +3336,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, { 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; + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; } } else @@ -3166,7 +3356,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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; + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; } } else state = STATE_FOCUSED; @@ -3205,44 +3395,45 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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)GetTextWidth(textLeft); + 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(SLIDER, TEXT + (state*3)))); + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } if (textRight != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textRight); + 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(SLIDER, TEXT + (state*3)))); + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } //-------------------------------------------------------------------- return result; } -// Slider control extended, returns selected value and has text -int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) -{ - return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH)); -} - // Slider Bar control extended, returns selected value int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) { - return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0); + 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 @@ -3257,14 +3448,14 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight // Progress bar Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0, - bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) }; + 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 - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f); + if ((state != STATE_DISABLED)) progress.width = ((float)*value/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)); //-------------------------------------------------------------------- // Draw control @@ -3282,15 +3473,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); } - else GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + 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 + 1, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + 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 + 1, bounds.y, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); - GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y + bounds.height - 1, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); - GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + 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) @@ -3301,23 +3492,23 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight if (textLeft != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textLeft); + 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(PROGRESSBAR, TEXT + (state*3)))); + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } if (textRight != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textRight); + 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(PROGRESSBAR, TEXT + (state*3)))); + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } //-------------------------------------------------------------------- @@ -3467,11 +3658,11 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd // Draw visible items for (int i = 0; ((i < visibleItems) && (text != NULL)); i++) { - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), BLANK); + if (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, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_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(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); } @@ -3480,18 +3671,18 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (((startIndex + i) == itemSelected) && (active != NULL)) { // Draw item selected - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); + 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))); } else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! { // Draw item focused - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); + 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))); } else { - // Draw item normal + // Draw item normal (no rectangle) GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); } } @@ -3531,22 +3722,22 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd return result; } -// Color Panel control - Color (RGBA) variant. +// 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. + 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. + // 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); @@ -3570,7 +3761,10 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) 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 }; + 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 //-------------------------------------------------------------------- @@ -3617,7 +3811,6 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) // Draw control //-------------------------------------------------------------------- - // Draw alpha bar: checked background if (state != STATE_DISABLED) { @@ -3755,7 +3948,7 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *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. + // 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); @@ -3768,8 +3961,8 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *color) 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. +// 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) @@ -3917,7 +4110,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; - //int textWidth = GetTextWidth(message) + 2; + //int textWidth = GuiGetTextWidth(message) + 2; Rectangle textBounds = { 0 }; textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -3981,7 +4174,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co Rectangle textBounds = { 0 }; if (message != NULL) { - int textSize = GetTextWidth(message) + 2; + 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; @@ -4221,7 +4414,7 @@ void GuiLoadStyle(const char *fileName) if (fileDataSize > 0) { - unsigned char *fileData = (unsigned char *)RAYGUI_MALLOC(fileDataSize*sizeof(unsigned char)); + unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); GuiLoadStyleFromMemory(fileData, fileDataSize); @@ -4283,8 +4476,6 @@ void GuiLoadStyleDefault(void) GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(VALUEBOX, TEXT_PADDING, 0); GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); - GuiSetStyle(SPINNER, TEXT_PADDING, 0); - GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(STATUSBAR, TEXT_PADDING, 8); GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); @@ -4299,8 +4490,8 @@ void GuiLoadStyleDefault(void) GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2); GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16); GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2); - GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24); - GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2); + GuiSetStyle(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); @@ -4310,6 +4501,7 @@ void GuiLoadStyleDefault(void) 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); @@ -4322,8 +4514,8 @@ void GuiLoadStyleDefault(void) { // Unload previous font texture UnloadTexture(guiFont.texture); - RL_FREE(guiFont.recs); - RL_FREE(guiFont.glyphs); + RAYGUI_FREE(guiFont.recs); + RAYGUI_FREE(guiFont.glyphs); guiFont.recs = NULL; guiFont.glyphs = NULL; @@ -4352,7 +4544,7 @@ const char *GuiIconText(int iconId, const char *text) if (text != NULL) { memset(buffer, 0, 1024); - sprintf(buffer, "#%03i#", iconId); + snprintf(buffer, 1024, "#%03i#", iconId); for (int i = 5; i < 1024; i++) { @@ -4364,7 +4556,7 @@ const char *GuiIconText(int iconId, const char *text) } else { - sprintf(iconBuffer, "#%03i#", iconId); + snprintf(iconBuffer, 16, "#%03i#", iconId); return iconBuffer; } @@ -4430,17 +4622,17 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) { if (loadIconsName) { - guiIconsName = (char **)RAYGUI_MALLOC(iconCount*sizeof(char **)); + guiIconsName = (char **)RAYGUI_CALLOC(iconCount, sizeof(char *)); for (int i = 0; i < iconCount; i++) { - guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH); + 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), iconCount*(iconSize*iconSize/32), rgiFile); + fread(guiIconsPtr, sizeof(unsigned int), (int)iconCount*((int)iconSize*(int)iconSize/32), rgiFile); } fclose(rgiFile); @@ -4449,6 +4641,56 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) 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) { @@ -4476,12 +4718,73 @@ 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) @@ -4567,7 +4870,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) { // Compressed font atlas image data (DEFLATE), it requires DecompressData() int dataUncompSize = 0; - unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize); + unsigned char *compData = (unsigned char *)RAYGUI_CALLOC(fontImageCompSize, sizeof(unsigned char)); memcpy(compData, fileDataPtr, fontImageCompSize); fileDataPtr += fontImageCompSize; @@ -4581,7 +4884,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) else { // Font atlas image data is not compressed - imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize); + imFont.data = (unsigned char *)RAYGUI_CALLOC(fontImageUncompSize, sizeof(unsigned char)); memcpy(imFont.data, fileDataPtr, fontImageUncompSize); fileDataPtr += fontImageUncompSize; } @@ -4609,7 +4912,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) if ((recsDataCompressedSize > 0) && (recsDataCompressedSize != recsDataSize)) { // Recs data is compressed, uncompress it - unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_MALLOC(recsDataCompressedSize); + unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_CALLOC(recsDataCompressedSize, sizeof(unsigned char)); memcpy(recsDataCompressed, fileDataPtr, recsDataCompressedSize); fileDataPtr += recsDataCompressedSize; @@ -4651,7 +4954,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) if ((glyphsDataCompressedSize > 0) && (glyphsDataCompressedSize != glyphsDataSize)) { // Glyphs data is compressed, uncompress it - unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_MALLOC(glyphsDataCompressedSize); + unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_CALLOC(glyphsDataCompressedSize, sizeof(unsigned char)); memcpy(glypsDataCompressed, fileDataPtr, glyphsDataCompressedSize); fileDataPtr += glyphsDataCompressedSize; @@ -4704,68 +5007,6 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) } } -// Gui get text width considering icon -static int GetTextWidth(const char *text) -{ - #if !defined(ICON_TEXT_PADDING) - #define ICON_TEXT_PADDING 4 - #endif - - Vector2 textSize = { 0 }; - int textIconOffset = 0; - - if ((text != NULL) && (text[0] != '\0')) - { - if (text[0] == '#') - { - for (int i = 1; (i < 5) && (text[i] != '\0'); i++) - { - if (text[i] == '#') - { - textIconOffset = i; - break; - } - } - } - - text += textIconOffset; - - // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly - float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); - - // Custom MeasureText() implementation - if ((guiFont.texture.id > 0) && (text != NULL)) - { - // Get size in bytes of text, considering end of line and line break - int size = 0; - for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++) - { - if ((text[i] != '\0') && (text[i] != '\n')) size++; - else break; - } - - float scaleFactor = fontSize/(float)guiFont.baseSize; - textSize.y = (float)guiFont.baseSize*scaleFactor; - float glyphWidth = 0.0f; - - for (int i = 0, codepointSize = 0; i < size; i += codepointSize) - { - int codepoint = GetCodepointNext(&text[i], &codepointSize); - int codepointIndex = GetGlyphIndex(guiFont, codepoint); - - if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); - else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); - - textSize.x += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); - } - } - - if (textIconOffset > 0) textSize.x += (RAYGUI_ICON_SIZE + ICON_TEXT_PADDING); - } - - return (int)textSize.x; -} - // Get text bounds considering control bounds static Rectangle GetTextBounds(int control, Rectangle bounds) { @@ -4786,7 +5027,7 @@ static Rectangle GetTextBounds(int control, Rectangle bounds) case SLIDER: case CHECKBOX: case VALUEBOX: - case SPINNER: + case CONTROL11: // TODO: More special cases (label on side): SLIDER, CHECKBOX, VALUEBOX, SPINNER default: { @@ -4832,7 +5073,8 @@ static const char *GetTextIcon(const char *text, int *iconId) } // Get text divided into lines (by line-breaks '\n') -const char **GetTextLines(const char *text, int *count) +// 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 @@ -4936,8 +5178,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C float textBoundsWidthOffset = 0.0f; // NOTE: We get text size after icon has been processed - // WARNING: GetTextWidth() also processes text icon to get width! -> Really needed? - int textSizeX = GetTextWidth(lines[i]); + // 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) @@ -5000,7 +5242,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C float textOffsetX = 0.0f; float glyphWidth = 0; - int ellipsisWidth = GetTextWidth("..."); + int ellipsisWidth = GuiGetTextWidth("..."); bool textOverflow = false; for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) { @@ -5144,13 +5386,13 @@ 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.f }, NULL); + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, NULL); int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); GuiSetStyle(LABEL, TEXT_PADDING, 0); GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, guiTooltipPtr); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, guiTooltipPtr); GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(LABEL, TEXT_PADDING, textPadding); } @@ -5204,7 +5446,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i buffer[i] = '\0'; // Set an end of string at this point counter++; - if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + if (counter >= RAYGUI_TEXTSPLIT_MAX_ITEMS) break; } } @@ -5526,10 +5768,10 @@ 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; + 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; } @@ -5562,7 +5804,7 @@ static const char *TextFormat(const char *text, ...) va_list args; va_start(args, text); - vsprintf(buffer, text, args); + vsnprintf(buffer, RAYGUI_TEXTFORMAT_MAX_SIZE, text, args); va_end(args); return buffer; @@ -5731,7 +5973,7 @@ static int GetCodepointNext(const char *text, int *codepointSize) } else if (0xe0 == (0xf0 & ptr[0])) { - // 3 byte UTF-8 codepoint */ + // 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; From 6adb1c2704a4e72a14326f78dec34dc6318b6bc3 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:51:40 +0100 Subject: [PATCH 059/189] Update core_viewport_scaling.c --- examples/core/core_viewport_scaling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index e70b89829..59e0bd026 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -92,7 +92,7 @@ int main(void) enum ViewportType viewportType = KEEP_ASPECT_INTEGER; SetConfigFlags(FLAG_WINDOW_RESIZABLE); - InitWindow(screenWidth, screenHeight, "raylib [core] example - Viewport Scaling"); + InitWindow(screenWidth, screenHeight, "raylib [core] example - viewport scaling"); ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); SetTargetFPS(60); // Set our game to run at 60 frames-per-second From c24f5ac4123356d401b85a9904477c7967215319 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:52:14 +0100 Subject: [PATCH 060/189] REXM: Reviewed rebuild to support full categories -WIP- --- tools/rexm/rexm.c | 61 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 4e417e987..450e95819 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -887,11 +887,14 @@ int main(int argc, char *argv[]) case OP_BUILD: { LOG("INFO: Command requested: BUILD\n"); - LOG("INFO: Example to be built: %s\n", exRebuildRequested); + LOG("INFO: Example to be built: %s\n", exName); - if ((strcmp(exRebuildRequested, "others") != 0) && + if ((exRebuildRequested[0] != '\0') && + (strcmp(exRebuildRequested, "others") != 0) && (strcmp(exCategory, "others") != 0)) // Skipping "others" category for rebuild: Special needs { + // TODO: Support building full categories: exRebuildRequested + int exRebuildCount = 0; rlExampleInfo *exRebuildList = LoadExamplesData(exCollectionFilePath, exRebuildRequested, false, &exRebuildCount); @@ -944,7 +947,54 @@ int main(int argc, char *argv[]) UnloadExamplesData(exRebuildList); } - else LOG("WARNING: [others] category examples should be build manually, they could have specific build requirements\n"); + else // Build a single example + { + // Build: raylib.com/examples//_example_name.html + // Build: raylib.com/examples//_example_name.data + // Build: raylib.com/examples//_example_name.wasm + // Build: raylib.com/examples//_example_name.js +#if defined(_WIN32) + // Set required environment variables + //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + //putenv("MAKE=mingw32-make"); + //ChangeDirectory(exBasePath); +#endif + + // Build example for PLATFORM_DESKTOP +#if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); + system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#else + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#endif + + // Build example for PLATFORM_WEB +#if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); + system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); +#else + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); + system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); +#endif + // Update generated .html metadata + LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName)); + UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + + // Copy results to web side + LOG("INFO: [%s] Copy example build to raylib.com\n", exName); + FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName)); + FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName)); + FileCopy(TextFormat("%s/%s/%s.wasm", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName)); + FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName)); + } + //LOG("WARNING: [others] category examples should be build manually, they could have specific build requirements\n"); } break; case OP_VALIDATE: // Validate: report and actions @@ -1909,10 +1959,13 @@ static void UnloadExamplesData(rlExampleInfo *exInfo) // WARNING: Expecting the example to follow raylib_example_template.c static rlExampleInfo *LoadExampleInfo(const char *exFileName) { - rlExampleInfo *exInfo = (rlExampleInfo *)RL_CALLOC(1, sizeof(rlExampleInfo)); + rlExampleInfo *exInfo = NULL; if (FileExists(exFileName) && IsFileExtension(exFileName, ".c")) { + // Example found in collection + exInfo = (rlExampleInfo *)RL_CALLOC(1, sizeof(rlExampleInfo)); + strcpy(exInfo->name, GetFileNameWithoutExt(exFileName)); strncpy(exInfo->category, exInfo->name, TextFindIndex(exInfo->name, "_")); From 4883813bbb640e5350346c546b840f36e561eb97 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:52:18 +0100 Subject: [PATCH 061/189] Update raygui.h --- examples/shapes/raygui.h | 870 +++++++++++++++++++++++++-------------- 1 file changed, 556 insertions(+), 314 deletions(-) diff --git a/examples/shapes/raygui.h b/examples/shapes/raygui.h index a3fc51f0f..17ced6ef5 100644 --- a/examples/shapes/raygui.h +++ b/examples/shapes/raygui.h @@ -4,7 +4,7 @@ * * 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. +* available as a standalone library, as long as input and drawing functions are provided * * FEATURES: * - Immediate-mode gui, minimal retained data @@ -27,7 +27,7 @@ * - 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). +* by default any previously loaded font (texture, recs, glyphs) * - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions * * CONTROLS PROVIDED: @@ -65,7 +65,7 @@ * - 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). +* It also provides a set of functions for styling the controls based on its properties (size, color) * * * RAYGUI STYLE (guiStyle): @@ -81,7 +81,7 @@ * * 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. +* 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) @@ -100,7 +100,7 @@ * 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. +* 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: * @@ -112,20 +112,20 @@ * * 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. +* 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. +* 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 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). +* 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) @@ -141,12 +141,17 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 4.5-dev (Sep-2024) Current dev version... +* 5.0-dev (2025) Current dev version... * ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes * ADDED: GuiValueBoxFloat() * ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP * ADDED: GuiListView() property: LIST_ITEMS_BORDER_WIDTH +* ADDED: GuiLoadIconsFromMemory() * ADDED: Multiple new icons +* 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 @@ -156,6 +161,8 @@ * 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 * @@ -259,16 +266,16 @@ * 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. +* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria +* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria +* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria * * DEPENDENCIES: * raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing * * STANDALONE MODE: * By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled -* with the config flag RAYGUI_STANDALONE. In that case is up to the user to provide another backend to cover library needs. +* 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: * @@ -309,7 +316,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -334,7 +341,7 @@ #define RAYGUI_VERSION_MAJOR 4 #define RAYGUI_VERSION_MINOR 5 #define RAYGUI_VERSION_PATCH 0 -#define RAYGUI_VERSION "4.5-dev" +#define RAYGUI_VERSION "5.0-dev" #if !defined(RAYGUI_STANDALONE) #include "raylib.h" @@ -358,17 +365,6 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// Allow custom memory allocators -#ifndef RAYGUI_MALLOC - #define RAYGUI_MALLOC(sz) malloc(sz) -#endif -#ifndef RAYGUI_CALLOC - #define RAYGUI_CALLOC(n,sz) calloc(n,sz) -#endif -#ifndef RAYGUI_FREE - #define RAYGUI_FREE(p) free(p) -#endif - // Simple log system to avoid printf() calls if required // NOTE: Avoiding those calls, also avoids const strings memory usage #define RAYGUI_SUPPORT_LOG_INFO @@ -421,13 +417,16 @@ // TODO: Texture2D type is very coupled to raylib, required by Font type // It should be redesigned to be provided by user - typedef struct Texture2D { + 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) - } Texture2D; + } Texture; + + // Texture2D, same as Texture + typedef Texture Texture2D; // Image, pixel data stored in CPU memory (RAM) typedef struct Image { @@ -527,7 +526,7 @@ typedef enum { DROPDOWNBOX, TEXTBOX, // Used also for: TEXTBOXMULTI VALUEBOX, - SPINNER, // Uses: BUTTON, VALUEBOX + CONTROL11, LISTVIEW, COLORPICKER, SCROLLBAR, @@ -549,12 +548,12 @@ typedef enum { BORDER_COLOR_DISABLED, // Control border color in STATE_DISABLED BASE_COLOR_DISABLED, // Control base color in STATE_DISABLED TEXT_COLOR_DISABLED, // Control text color in STATE_DISABLED - BORDER_WIDTH, // Control border size, 0 for no border + 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, // Control text padding, not considering border - TEXT_ALIGNMENT, // Control text horizontal alignment inside control text bound (after border and padding) + //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; @@ -641,11 +640,14 @@ typedef enum { TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable } GuiTextBoxProperty; -// Spinner +// ValueBox/Spinner typedef enum { - SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width - SPIN_BUTTON_SPACING, // Spinner buttons separation -} GuiSpinnerProperty; + SPINNER_BUTTON_WIDTH = 16, // Spinner left/right buttons width + SPINNER_BUTTON_SPACING, // Spinner buttons separation +} GuiValueBoxProperty; + +// Control11 +//typedef enum { } GuiControl11Property; // ListView typedef enum { @@ -653,6 +655,7 @@ typedef enum { 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; @@ -717,6 +720,9 @@ RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load 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 @@ -999,11 +1005,11 @@ typedef enum { ICON_MLAYERS = 226, ICON_MAPS = 227, ICON_HOT = 228, - ICON_229 = 229, - ICON_230 = 230, - ICON_231 = 231, - ICON_232 = 232, - ICON_233 = 233, + ICON_LABEL = 229, + ICON_NAME_ID = 230, + ICON_SLICING = 231, + ICON_MANUAL_CONTROL = 232, + ICON_COLLISION = 233, ICON_234 = 234, ICON_235 = 235, ICON_236 = 236, @@ -1046,12 +1052,24 @@ typedef enum { #if defined(RAYGUI_IMPLEMENTATION) #include // required for: isspace() [GuiTextBox()] -#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()] -#include // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()] +#include // Required for: 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 @@ -1318,11 +1336,11 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x422a422a, 0x422e422a, 0x40384e28, 0x00007fe0, // ICON_MLAYERS 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x5b2a512a, 0x512e552a, 0x40385128, 0x00007fe0, // ICON_MAPS 0x04200000, 0x1cf00c60, 0x11f019f0, 0x0f3807b8, 0x1e3c0f3c, 0x1c1c1e1c, 0x1e3c1c1c, 0x00000f70, // ICON_HOT - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_229 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_230 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_231 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_232 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_233 + 0x00000000, 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 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236 @@ -1363,7 +1381,7 @@ static unsigned int *guiIconsPtr = guiIcons; #define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties //---------------------------------------------------------------------------------- -// Types and Structures Definition +// Module Types and Structures Definition //---------------------------------------------------------------------------------- // Gui control property style color element typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement; @@ -1387,8 +1405,7 @@ static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() //static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking -static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down -static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement +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) @@ -1484,7 +1501,6 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co //---------------------------------------------------------------------------------- static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only) -static int GetTextWidth(const char *text); // Gui get text width using gui font and style static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor @@ -1589,6 +1605,10 @@ int GuiWindowBox(Rectangle bounds, const char *title) #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; @@ -1597,9 +1617,10 @@ int GuiWindowBox(Rectangle bounds, const char *title) 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) - 20, - statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18 }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; // Update control //-------------------------------------------------------------------- @@ -1653,7 +1674,7 @@ int GuiGroupBox(Rectangle bounds, const char *text) // Line control int GuiLine(Rectangle bounds, const char *text) { - #if !defined(RAYGUI_LINE_ORIGIN_SIZE) + #if !defined(RAYGUI_LINE_MARGIN_TEXT) #define RAYGUI_LINE_MARGIN_TEXT 12 #endif #if !defined(RAYGUI_LINE_TEXT_PADDING) @@ -1671,7 +1692,7 @@ int GuiLine(Rectangle bounds, const char *text) else { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.width = (float)GuiGetTextWidth(text) + 2; textBounds.height = bounds.height; textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT; textBounds.y = bounds.y; @@ -1711,8 +1732,8 @@ int GuiPanel(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar - GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED: (int)LINE_COLOR)), - GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR))); + 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; @@ -2011,7 +2032,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) bool pressed = false; // NOTE: We force bounds.width to be all text - float textWidth = (float)GetTextWidth(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 @@ -2149,7 +2170,9 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + const char **items = NULL; + + if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle slider = { 0, // Calculated later depending on the active toggle @@ -2196,7 +2219,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) if (text != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(text); + 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; @@ -2221,7 +2244,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -2474,7 +2497,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) - #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement + #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 @@ -2487,10 +2510,10 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); - int textLength = (int)strlen(text); // Get current text length + int textLength = (text != NULL)? (int)strlen(text) : 0; // Get current text length int thisCursorIndex = textBoxCursorIndex; if (thisCursorIndex > textLength) thisCursorIndex = textLength; - int textWidth = GetTextWidth(text) - GetTextWidth(text + thisCursorIndex); + int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); int textIndexOffset = 0; // Text index offset to start drawing in the box // Cursor rectangle @@ -2511,15 +2534,6 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) mouseCursor.x = -1; mouseCursor.width = 1; - // Auto-cursor movement logic - // NOTE: Cursor moves automatically when key down after some time - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCooldownCounter++; - else - { - autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter - autoCursorDelayCounter = 0; // GLOBAL: Cursor delay counter - } - // Blink-cursor frame counter //if (!autoCursorMode) blinkCursorFrameCounter++; //else blinkCursorFrameCounter = 0; @@ -2537,6 +2551,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) 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++; + 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; @@ -2550,7 +2571,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textIndexOffset += nextCodepointSize; - textWidth = GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex); + textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); } int codepoint = GetCharPressed(); // Get Unicode codepoint @@ -2560,10 +2581,43 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int codepointSize = 0; const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); - // Add codepoint to text, at current cursor position - // NOTE: Make sure we do not overflow buffer size - if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) + // Handle text paste action + if (IsKeyPressed(KEY_V) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(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]; @@ -2583,113 +2637,185 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Move cursor to end if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; - // Delete codepoint from text, after current cursor position - if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + // Delete related codepoints from text, after current cursor position + if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_DELETE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - autoCursorDelayCounter++; + int offset = textBoxCursorIndex; + int accCodepointSize = 0; + int nextCodepointSize; + int nextCodepoint; - if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + // 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) { - int nextCodepointSize = 0; - GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); - - // Move backward text from cursor position - for (int i = textBoxCursorIndex; i < textLength; i++) text[i] = text[i + nextCodepointSize]; - - textLength -= codepointSize; - if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; - - // Make sure text last character is EOL - text[textLength] = '\0'; + 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) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(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 ((textLength > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - int i = textBoxCursorIndex - 1; + int offset = textBoxCursorIndex; int accCodepointSize = 0; + int prevCodepointSize; + int prevCodepoint; - // Move cursor to the end of word if on space already - while ((i > 0) && isspace(text[i])) + // Check whitespace to delete (ASCII only) + while (offset > 0) { - int prevCodepointSize = 0; - GetCodepointPrevious(text + i, &prevCodepointSize); - i -= prevCodepointSize; + 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 cursor to the start of the word - while ((i > 0) && !isspace(text[i])) - { - int prevCodepointSize = 0; - GetCodepointPrevious(text + i, &prevCodepointSize); - i -= prevCodepointSize; - accCodepointSize += prevCodepointSize; - } + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex; i <= textLength; i++) text[i - accCodepointSize] = text[i]; - // Move forward text from cursor position - for (int j = (textBoxCursorIndex - accCodepointSize); j < textLength; j++) text[j] = text[j + accCodepointSize]; - - // Prevent cursor index from decrementing past 0 - if (textBoxCursorIndex > 0) - { - textBoxCursorIndex -= accCodepointSize; - textLength -= accCodepointSize; - } - - // Make sure text last character is EOL - text[textLength] = '\0'; - } - else if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + textLength -= accCodepointSize; + textBoxCursorIndex -= accCodepointSize; + } + + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) { - autoCursorDelayCounter++; + // Delete single codepoint from text, before current cursor position + + int prevCodepointSize = 0; - if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames - { - int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - // Prevent cursor index from decrementing past 0 - if (textBoxCursorIndex > 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]; - // Move backward text from cursor position - for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize]; - - textBoxCursorIndex -= codepointSize; - textLength -= codepointSize; - } - - // Make sure text last character is EOL - text[textLength] = '\0'; - } + textLength -= prevCodepointSize; + textBoxCursorIndex -= prevCodepointSize; } // Move cursor position with keys - if (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_LEFT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - autoCursorDelayCounter++; + int offset = textBoxCursorIndex; + //int accCodepointSize = 0; + int prevCodepointSize; + int prevCodepoint; - if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + // Check whitespace to skip (ASCII only) + while (offset > 0) { - int prevCodepointSize = 0; - if (textBoxCursorIndex > 0) GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if (!isspace(prevCodepoint & 0xff)) break; - if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize; + 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 (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && autoCursorShouldTrigger))) { - autoCursorDelayCounter++; + int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + textBoxCursorIndex -= prevCodepointSize; + } + else if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_RIGHT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(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) { - int nextCodepointSize = 0; - GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) break; - if ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize; + 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) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger))) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + textBoxCursorIndex += nextCodepointSize; } // Move cursor position with mouse @@ -2701,7 +2827,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) float widthToMouseX = 0; int mouseCursorIndex = 0; - for (int i = textIndexOffset; i < textLength; i++) + for (int i = textIndexOffset; i < textLength; i += codepointSize) { codepoint = GetCodepointNext(&text[i], &codepointSize); codepointIndex = GetGlyphIndex(guiFont, codepoint); @@ -2720,7 +2846,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Check if mouse cursor is at the last position - int textEndWidth = GetTextWidth(text + textIndexOffset); + int textEndWidth = GuiGetTextWidth(text + textIndexOffset); if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; @@ -2737,7 +2863,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) else mouseCursor.x = -1; // Recalculate cursor position.y depending on textBoxCursorIndex - cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING); + 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 @@ -2745,6 +2871,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) { textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes result = 1; } } @@ -2757,6 +2884,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes result = 1; } } @@ -2825,19 +2953,22 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int int tempValue = *value; - Rectangle spinner = { bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING), bounds.y, - bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING)), bounds.height }; - Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; - Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; + Rectangle 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)GetTextWidth(text) + 2; + textBounds.width = (float)GuiGetTextWidth(text) + 2; textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); - textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; - if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING); + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); } // Update control @@ -2871,20 +3002,20 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int // Draw control //-------------------------------------------------------------------- - result = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode); + 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(SPINNER, BORDER_WIDTH)); + 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(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); //-------------------------------------------------------------------- *value = tempValue; @@ -2903,12 +3034,12 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in GuiState state = guiState; char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; - sprintf(textValue, "%i", *value); + snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value); Rectangle textBounds = { 0 }; if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -2929,10 +3060,37 @@ 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 (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 (GetTextWidth(textValue) < bounds.width) + if (GuiGetTextWidth(textValue) < bounds.width) { int key = GetCharPressed(); if ((key >= 48) && (key <= 57)) @@ -2992,11 +3150,14 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in 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 + // Draw cursor rectangle if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = { bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) }; + 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))); } @@ -3019,12 +3180,12 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float GuiState state = guiState; //char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; - //sprintf(textValue, "%2.2f", *value); + //snprintf(textValue, sizeof(textValue), "%2.2f", *value); - Rectangle textBounds = {0}; + Rectangle textBounds = { 0 }; if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -3045,10 +3206,37 @@ 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 (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 (GetTextWidth(textValue) < bounds.width) + if (GuiGetTextWidth(textValue) < bounds.width) { int key = GetCharPressed(); if (((key >= 48) && (key <= 57)) || @@ -3103,7 +3291,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = {bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, + 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))); @@ -3120,7 +3308,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float // Slider control with pro parameters // NOTE: Other GuiSlider*() controls use this one -int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth) +int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) { int result = 0; GuiState state = guiState; @@ -3129,6 +3317,8 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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) }; @@ -3146,7 +3336,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, { 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; + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; } } else @@ -3166,7 +3356,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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; + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; } } else state = STATE_FOCUSED; @@ -3205,44 +3395,45 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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)GetTextWidth(textLeft); + 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(SLIDER, TEXT + (state*3)))); + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } if (textRight != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textRight); + 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(SLIDER, TEXT + (state*3)))); + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } //-------------------------------------------------------------------- return result; } -// Slider control extended, returns selected value and has text -int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) -{ - return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH)); -} - // Slider Bar control extended, returns selected value int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) { - return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0); + 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 @@ -3257,14 +3448,14 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight // Progress bar Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0, - bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) }; + 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 - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f); + if ((state != STATE_DISABLED)) progress.width = ((float)*value/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)); //-------------------------------------------------------------------- // Draw control @@ -3282,15 +3473,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); } - else GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + 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 + 1, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + 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 + 1, bounds.y, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); - GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y + bounds.height - 1, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); - GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + 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) @@ -3301,23 +3492,23 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight if (textLeft != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textLeft); + 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(PROGRESSBAR, TEXT + (state*3)))); + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } if (textRight != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textRight); + 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(PROGRESSBAR, TEXT + (state*3)))); + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } //-------------------------------------------------------------------- @@ -3467,11 +3658,11 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd // Draw visible items for (int i = 0; ((i < visibleItems) && (text != NULL)); i++) { - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), BLANK); + if (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, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_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(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); } @@ -3480,18 +3671,18 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (((startIndex + i) == itemSelected) && (active != NULL)) { // Draw item selected - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); + 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))); } else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! { // Draw item focused - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); + 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))); } else { - // Draw item normal + // Draw item normal (no rectangle) GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); } } @@ -3531,22 +3722,22 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd return result; } -// Color Panel control - Color (RGBA) variant. +// 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. + 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. + // 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); @@ -3570,7 +3761,10 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) 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 }; + 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 //-------------------------------------------------------------------- @@ -3617,7 +3811,6 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) // Draw control //-------------------------------------------------------------------- - // Draw alpha bar: checked background if (state != STATE_DISABLED) { @@ -3755,7 +3948,7 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *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. + // 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); @@ -3768,8 +3961,8 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *color) 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. +// 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) @@ -3917,7 +4110,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; - //int textWidth = GetTextWidth(message) + 2; + //int textWidth = GuiGetTextWidth(message) + 2; Rectangle textBounds = { 0 }; textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -3981,7 +4174,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co Rectangle textBounds = { 0 }; if (message != NULL) { - int textSize = GetTextWidth(message) + 2; + 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; @@ -4221,7 +4414,7 @@ void GuiLoadStyle(const char *fileName) if (fileDataSize > 0) { - unsigned char *fileData = (unsigned char *)RAYGUI_MALLOC(fileDataSize*sizeof(unsigned char)); + unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); GuiLoadStyleFromMemory(fileData, fileDataSize); @@ -4283,8 +4476,6 @@ void GuiLoadStyleDefault(void) GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(VALUEBOX, TEXT_PADDING, 0); GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); - GuiSetStyle(SPINNER, TEXT_PADDING, 0); - GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(STATUSBAR, TEXT_PADDING, 8); GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); @@ -4299,8 +4490,8 @@ void GuiLoadStyleDefault(void) GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2); GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16); GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2); - GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24); - GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2); + GuiSetStyle(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); @@ -4310,6 +4501,7 @@ void GuiLoadStyleDefault(void) 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); @@ -4322,8 +4514,8 @@ void GuiLoadStyleDefault(void) { // Unload previous font texture UnloadTexture(guiFont.texture); - RL_FREE(guiFont.recs); - RL_FREE(guiFont.glyphs); + RAYGUI_FREE(guiFont.recs); + RAYGUI_FREE(guiFont.glyphs); guiFont.recs = NULL; guiFont.glyphs = NULL; @@ -4352,7 +4544,7 @@ const char *GuiIconText(int iconId, const char *text) if (text != NULL) { memset(buffer, 0, 1024); - sprintf(buffer, "#%03i#", iconId); + snprintf(buffer, 1024, "#%03i#", iconId); for (int i = 5; i < 1024; i++) { @@ -4364,7 +4556,7 @@ const char *GuiIconText(int iconId, const char *text) } else { - sprintf(iconBuffer, "#%03i#", iconId); + snprintf(iconBuffer, 16, "#%03i#", iconId); return iconBuffer; } @@ -4430,17 +4622,17 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) { if (loadIconsName) { - guiIconsName = (char **)RAYGUI_MALLOC(iconCount*sizeof(char **)); + guiIconsName = (char **)RAYGUI_CALLOC(iconCount, sizeof(char *)); for (int i = 0; i < iconCount; i++) { - guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH); + 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), iconCount*(iconSize*iconSize/32), rgiFile); + fread(guiIconsPtr, sizeof(unsigned int), (int)iconCount*((int)iconSize*(int)iconSize/32), rgiFile); } fclose(rgiFile); @@ -4449,6 +4641,56 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) 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) { @@ -4476,12 +4718,73 @@ 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) @@ -4567,7 +4870,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) { // Compressed font atlas image data (DEFLATE), it requires DecompressData() int dataUncompSize = 0; - unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize); + unsigned char *compData = (unsigned char *)RAYGUI_CALLOC(fontImageCompSize, sizeof(unsigned char)); memcpy(compData, fileDataPtr, fontImageCompSize); fileDataPtr += fontImageCompSize; @@ -4581,7 +4884,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) else { // Font atlas image data is not compressed - imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize); + imFont.data = (unsigned char *)RAYGUI_CALLOC(fontImageUncompSize, sizeof(unsigned char)); memcpy(imFont.data, fileDataPtr, fontImageUncompSize); fileDataPtr += fontImageUncompSize; } @@ -4609,7 +4912,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) if ((recsDataCompressedSize > 0) && (recsDataCompressedSize != recsDataSize)) { // Recs data is compressed, uncompress it - unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_MALLOC(recsDataCompressedSize); + unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_CALLOC(recsDataCompressedSize, sizeof(unsigned char)); memcpy(recsDataCompressed, fileDataPtr, recsDataCompressedSize); fileDataPtr += recsDataCompressedSize; @@ -4651,7 +4954,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) if ((glyphsDataCompressedSize > 0) && (glyphsDataCompressedSize != glyphsDataSize)) { // Glyphs data is compressed, uncompress it - unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_MALLOC(glyphsDataCompressedSize); + unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_CALLOC(glyphsDataCompressedSize, sizeof(unsigned char)); memcpy(glypsDataCompressed, fileDataPtr, glyphsDataCompressedSize); fileDataPtr += glyphsDataCompressedSize; @@ -4704,68 +5007,6 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) } } -// Gui get text width considering icon -static int GetTextWidth(const char *text) -{ - #if !defined(ICON_TEXT_PADDING) - #define ICON_TEXT_PADDING 4 - #endif - - Vector2 textSize = { 0 }; - int textIconOffset = 0; - - if ((text != NULL) && (text[0] != '\0')) - { - if (text[0] == '#') - { - for (int i = 1; (i < 5) && (text[i] != '\0'); i++) - { - if (text[i] == '#') - { - textIconOffset = i; - break; - } - } - } - - text += textIconOffset; - - // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly - float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); - - // Custom MeasureText() implementation - if ((guiFont.texture.id > 0) && (text != NULL)) - { - // Get size in bytes of text, considering end of line and line break - int size = 0; - for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++) - { - if ((text[i] != '\0') && (text[i] != '\n')) size++; - else break; - } - - float scaleFactor = fontSize/(float)guiFont.baseSize; - textSize.y = (float)guiFont.baseSize*scaleFactor; - float glyphWidth = 0.0f; - - for (int i = 0, codepointSize = 0; i < size; i += codepointSize) - { - int codepoint = GetCodepointNext(&text[i], &codepointSize); - int codepointIndex = GetGlyphIndex(guiFont, codepoint); - - if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); - else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); - - textSize.x += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); - } - } - - if (textIconOffset > 0) textSize.x += (RAYGUI_ICON_SIZE + ICON_TEXT_PADDING); - } - - return (int)textSize.x; -} - // Get text bounds considering control bounds static Rectangle GetTextBounds(int control, Rectangle bounds) { @@ -4786,7 +5027,7 @@ static Rectangle GetTextBounds(int control, Rectangle bounds) case SLIDER: case CHECKBOX: case VALUEBOX: - case SPINNER: + case CONTROL11: // TODO: More special cases (label on side): SLIDER, CHECKBOX, VALUEBOX, SPINNER default: { @@ -4832,7 +5073,8 @@ static const char *GetTextIcon(const char *text, int *iconId) } // Get text divided into lines (by line-breaks '\n') -const char **GetTextLines(const char *text, int *count) +// 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 @@ -4936,8 +5178,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C float textBoundsWidthOffset = 0.0f; // NOTE: We get text size after icon has been processed - // WARNING: GetTextWidth() also processes text icon to get width! -> Really needed? - int textSizeX = GetTextWidth(lines[i]); + // 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) @@ -5000,7 +5242,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C float textOffsetX = 0.0f; float glyphWidth = 0; - int ellipsisWidth = GetTextWidth("..."); + int ellipsisWidth = GuiGetTextWidth("..."); bool textOverflow = false; for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) { @@ -5144,13 +5386,13 @@ 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.f }, NULL); + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, NULL); int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); GuiSetStyle(LABEL, TEXT_PADDING, 0); GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, guiTooltipPtr); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, guiTooltipPtr); GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(LABEL, TEXT_PADDING, textPadding); } @@ -5204,7 +5446,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i buffer[i] = '\0'; // Set an end of string at this point counter++; - if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + if (counter >= RAYGUI_TEXTSPLIT_MAX_ITEMS) break; } } @@ -5526,10 +5768,10 @@ 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; + 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; } @@ -5562,7 +5804,7 @@ static const char *TextFormat(const char *text, ...) va_list args; va_start(args, text); - vsprintf(buffer, text, args); + vsnprintf(buffer, RAYGUI_TEXTFORMAT_MAX_SIZE, text, args); va_end(args); return buffer; @@ -5731,7 +5973,7 @@ static int GetCodepointNext(const char *text, int *codepointSize) } else if (0xe0 == (0xf0 & ptr[0])) { - // 3 byte UTF-8 codepoint */ + // 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; From a66b6c998a97a9603dd13e428197effae265000a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:52:23 +0100 Subject: [PATCH 062/189] Update README.md --- examples/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/README.md b/examples/README.md index 28a2107e4..f1f6c80b3 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: 192] +## EXAMPLES COLLECTION [TOTAL: 194] -### category: core [45] +### category: core [47] Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality. @@ -71,6 +71,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [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 | [Robin](https://github.com/RobinsAviary) | | [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 [34] From eacbc8bd616169c558bfbcfa918ceaa19dbd4cee Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:52:45 +0100 Subject: [PATCH 063/189] Update examples_report.md --- tools/rexm/examples_report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md index 7734a234c..24977e38e 100644 --- a/tools/rexm/examples_report.md +++ b/tools/rexm/examples_report.md @@ -59,12 +59,14 @@ Example elements validated: | core_high_dpi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_render_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_undo_redo | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_viewport_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_input_actions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_directory_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_screen_recording | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_compute_hash | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_bullet_hell | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From af57c8854f14511a85a4c7c30e877a84f8a174c3 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2025 20:53:14 +0100 Subject: [PATCH 064/189] REXM: ADDED: `core_compute_hash` --- examples/Makefile | 1 + examples/Makefile.Web | 7 + examples/core/core_compute_hash.c | 143 +++++ examples/core/core_compute_hash.png | Bin 0 -> 19367 bytes examples/examples_list.txt | 1 + .../VS2022/examples/core_compute_hash.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 29 +- projects/VS2022/raylib/raylib.vcxproj | 9 +- 8 files changed, 754 insertions(+), 5 deletions(-) create mode 100644 examples/core/core_compute_hash.c create mode 100644 examples/core/core_compute_hash.png create mode 100644 projects/VS2022/examples/core_compute_hash.vcxproj diff --git a/examples/Makefile b/examples/Makefile index 6fcf218ee..729459de4 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -525,6 +525,7 @@ CORE = \ core/core_basic_screen_manager \ core/core_basic_window \ core/core_clipboard_text \ + core/core_compute_hash \ core/core_custom_frame_control \ core/core_custom_logging \ core/core_delta_time \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 3ac776435..d2336e7df 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -513,6 +513,7 @@ CORE = \ core/core_basic_screen_manager \ core/core_basic_window \ core/core_clipboard_text \ + core/core_compute_hash \ core/core_custom_frame_control \ core/core_custom_logging \ core/core_delta_time \ @@ -753,6 +754,9 @@ core/core_basic_window: core/core_basic_window.c core/core_clipboard_text: core/core_clipboard_text.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_compute_hash: core/core_compute_hash.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_custom_frame_control: core/core_custom_frame_control.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -834,6 +838,9 @@ core/core_text_file_loading: core/core_text_file_loading.c core/core_undo_redo: core/core_undo_redo.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_viewport_scaling: core/core_viewport_scaling.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_vr_simulator: core/core_vr_simulator.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file core/resources/shaders/glsl100/distortion.fs@resources/shaders/glsl100/distortion.fs diff --git a/examples/core/core_compute_hash.c b/examples/core/core_compute_hash.c new file mode 100644 index 000000000..376e2d65c --- /dev/null +++ b/examples/core/core_compute_hash.c @@ -0,0 +1,143 @@ +/******************************************************************************************* +* +* raylib [core] example - compute hash +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +static char *GetDataAsHexText(const unsigned int *data, int dataSize); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - compute hash"); + + // UI controls variables + char textInput[96] = "The quick brown fox jumps over the lazy dog."; + bool textBoxEditMode = false; + bool btnComputeHashes = false; + + // Data hash values + unsigned int hashCRC32 = 0; + unsigned int *hashMD5 = NULL; + unsigned int *hashSHA1 = NULL; + unsigned int *hashSHA256 = NULL; + + // Base64 encoded data + char *base64Text = NULL; + int base64TextSize = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (btnComputeHashes) + { + int textInputLen = strlen(textInput); + + // Encode data to Base64 string (includes NULL terminator), memory must be MemFree() + base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize); + + hashCRC32 = ComputeCRC32((unsigned char *)textInput, textInputLen); // Compute CRC32 hash code (4 bytes) + hashMD5 = ComputeMD5((unsigned char *)textInput, textInputLen); // Compute MD5 hash code, returns static int[4] (16 bytes) + hashSHA1 = ComputeSHA1((unsigned char *)textInput, textInputLen); // Compute SHA1 hash code, returns static int[5] (20 bytes) + hashSHA256 = ComputeSHA256((unsigned char *)textInput, textInputLen); // Compute SHA256 hash code, returns static int[8] (32 bytes) + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + GuiSetStyle(DEFAULT, TEXT_SIZE, 20); + GuiSetStyle(DEFAULT, TEXT_SPACING, 2); + GuiLabel((Rectangle){ 40, 26, 720, 32 }, "INPUT DATA (TEXT):"); + GuiSetStyle(DEFAULT, TEXT_SPACING, 1); + GuiSetStyle(DEFAULT, TEXT_SIZE, 10); + + if (GuiTextBox((Rectangle){ 40, 64, 720, 32 }, textInput, 95, textBoxEditMode)) textBoxEditMode = !textBoxEditMode; + + btnComputeHashes = GuiButton((Rectangle){ 40, 64 + 40, 720, 32 }, "COMPUTE INPUT DATA HASHES"); + + GuiSetStyle(DEFAULT, TEXT_SIZE, 20); + GuiSetStyle(DEFAULT, TEXT_SPACING, 2); + GuiLabel((Rectangle){ 40, 160, 720, 32 }, "INPUT DATA HASH VALUES:"); + GuiSetStyle(DEFAULT, TEXT_SPACING, 1); + GuiSetStyle(DEFAULT, TEXT_SIZE, 10); + + GuiSetStyle(TEXTBOX, TEXT_READONLY, 1); + GuiLabel((Rectangle){ 40, 200, 120, 32 }, "CRC32 [32 bit]:"); + GuiTextBox((Rectangle){ 40 + 120, 200, 720 - 120, 32 }, GetDataAsHexText(&hashCRC32, 1), 120, false); + GuiLabel((Rectangle){ 40, 200 + 36, 120, 32 }, "MD5 [128 bit]:"); + GuiTextBox((Rectangle){ 40 + 120, 200 + 36, 720 - 120, 32 }, GetDataAsHexText(hashMD5, 4), 120, false); + GuiLabel((Rectangle){ 40, 200 + 36*2, 120, 32 }, "SHA1 [160 bit]:"); + GuiTextBox((Rectangle){ 40 + 120, 200 + 36*2, 720 - 120, 32 }, GetDataAsHexText(hashSHA1, 5), 120, false); + GuiLabel((Rectangle){ 40, 200 + 36*3, 120, 32 }, "SHA256 [256 bit]:"); + GuiTextBox((Rectangle){ 40 + 120, 200 + 36*3, 720 - 120, 32 }, GetDataAsHexText(hashSHA256, 8), 120, false); + + GuiSetState(STATE_FOCUSED); + GuiLabel((Rectangle){ 40, 200 + 36*5 - 30, 320, 32 }, "BONUS - BAS64 ENCODED STRING:"); + GuiSetState(STATE_NORMAL); + GuiLabel((Rectangle){ 40, 200 + 36*5, 120, 32 }, "BASE64 ENCODING:"); + GuiTextBox((Rectangle){ 40 + 120, 200 + 36*5, 720 - 120, 32 }, base64Text, 120, false); + GuiSetStyle(TEXTBOX, TEXT_READONLY, 0); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + MemFree(base64Text); // Free Base64 text data + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +static char *GetDataAsHexText(const unsigned int *data, int dataSize) +{ + static char text[128] = { 0 }; + memset(text, 0, 128); + + if ((data != NULL) && (dataSize > 0) && (dataSize < ((128/8) - 1))) + { + for (int i = 0; i < dataSize; i++) TextCopy(text + i*8, TextFormat("%08X", data[i])); + } + else TextCopy(text, "00000000"); + + return text; +} diff --git a/examples/core/core_compute_hash.png b/examples/core/core_compute_hash.png new file mode 100644 index 0000000000000000000000000000000000000000..19a5d0b1cff66831f997ce43d809b1256d550f9c GIT binary patch literal 19367 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 + + + + 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 + + + + {6C897101-BE52-4387-8AA2-062123A76BA1} + Win32Proj + core_compute_hash + 10.0 + core_compute_hash + + + + 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 8ace665a9..34c696ffe 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -407,6 +407,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_lines_drawing", "exa 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5053,6 +5055,30 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5220,7 +5246,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} @@ -5258,6 +5284,7 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/projects/VS2022/raylib/raylib.vcxproj b/projects/VS2022/raylib/raylib.vcxproj index 7721a669a..cf254761e 100644 --- a/projects/VS2022/raylib/raylib.vcxproj +++ b/projects/VS2022/raylib/raylib.vcxproj @@ -242,7 +242,7 @@ Level3 Disabled - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;%(PreprocessorDefinitions) CompileAsC $(ProjectDir)..\..\..\src\external\glfw\include @@ -295,7 +295,7 @@ Level3 Disabled - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED;%(PreprocessorDefinitions) CompileAsC $(ProjectDir)..\..\..\src\external\glfw\include MultiThreadedDebug @@ -353,10 +353,11 @@ MaxSpeed true true - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;%(PreprocessorDefinitions) $(ProjectDir)..\..\..\src\external\glfw\include CompileAsC + AdvancedVectorExtensions2 Windows @@ -412,7 +413,7 @@ MaxSpeed true true - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED;%(PreprocessorDefinitions) $(ProjectDir)..\..\..\src\external\glfw\include CompileAsC MultiThreaded From ad17af57e928c61e8e29d2f6c74962c249adf36d Mon Sep 17 00:00:00 2001 From: JohnnyCena123 Date: Fri, 7 Nov 2025 11:13:27 +0200 Subject: [PATCH 065/189] [ignore][parser] properly ignore built rlparser executable (#5337) * [ignore][parser] properly ignore built rlparser executable * remove actual executable --- .gitignore | 3 ++- tools/rlparser/rlparser | Bin 43144 -> 0 bytes 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100755 tools/rlparser/rlparser diff --git a/.gitignore b/.gitignore index fa4c4c49d..ddbc5c11d 100644 --- a/.gitignore +++ b/.gitignore @@ -115,7 +115,8 @@ build-*/ docgen_tmp/ # Tools stuff -tools/parser/raylib_parser +tools/parser/rlparser.exe +tools/parser/rlparser tools/rexm/rexm.exe tools/rexm/rexm diff --git a/tools/rlparser/rlparser b/tools/rlparser/rlparser deleted file mode 100755 index b68032c023debdd4b5e656b794864b81bd2e123c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43144 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 Date: Sat, 8 Nov 2025 11:28:15 +0100 Subject: [PATCH 066/189] fix clipping issue (#5342) --- src/external/rlsw.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 15ab89d4e..db5a8189d 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -2118,12 +2118,12 @@ static inline int sw_clip_##name( // Frustum cliping functions //------------------------------------------------------------------------------------------- #define IS_INSIDE_PLANE_W(h) ((h)[3] >= SW_CLIP_EPSILON) -#define IS_INSIDE_PLANE_X_POS(h) ((h)[0] <= (h)[3]) -#define IS_INSIDE_PLANE_X_NEG(h) (-(h)[0] <= (h)[3]) -#define IS_INSIDE_PLANE_Y_POS(h) ((h)[1] <= (h)[3]) -#define IS_INSIDE_PLANE_Y_NEG(h) (-(h)[1] <= (h)[3]) -#define IS_INSIDE_PLANE_Z_POS(h) ((h)[2] <= (h)[3]) -#define IS_INSIDE_PLANE_Z_NEG(h) (-(h)[2] <= (h)[3]) +#define IS_INSIDE_PLANE_X_POS(h) ( (h)[0] < (h)[3]) // Exclusive for +X +#define IS_INSIDE_PLANE_X_NEG(h) (-(h)[0] < (h)[3]) // Exclusive for -X +#define IS_INSIDE_PLANE_Y_POS(h) ( (h)[1] < (h)[3]) // Exclusive for +Y +#define IS_INSIDE_PLANE_Y_NEG(h) (-(h)[1] < (h)[3]) // Exclusive for -Y +#define IS_INSIDE_PLANE_Z_POS(h) ( (h)[2] <= (h)[3]) // Inclusive for +Z +#define IS_INSIDE_PLANE_Z_NEG(h) (-(h)[2] <= (h)[3]) // Inclusive for -Z #define COMPUTE_T_PLANE_W(hPrev, hCurr) ((SW_CLIP_EPSILON - (hPrev)[3])/((hCurr)[3] - (hPrev)[3])) #define COMPUTE_T_PLANE_X_POS(hPrev, hCurr) (((hPrev)[3] - (hPrev)[0])/(((hPrev)[3] - (hPrev)[0]) - ((hCurr)[3] - (hCurr)[0]))) From d8da443604cfc0cdcd5dde6251549e298f3e3dc3 Mon Sep 17 00:00:00 2001 From: Chakradhar Date: Sat, 8 Nov 2025 15:59:45 +0530 Subject: [PATCH 067/189] Fixed core_text_file_loading example in raylib examples, to account for blank lines in text file and text wrapping properly for the case when the last word goes out the display (#5339) --- examples/core/core_text_file_loading.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/examples/core/core_text_file_loading.c b/examples/core/core_text_file_loading.c index ed48f7d36..852cc32c4 100644 --- a/examples/core/core_text_file_loading.c +++ b/examples/core/core_text_file_loading.c @@ -19,6 +19,8 @@ #include "raymath.h" // Required for: Lerp() +#include + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -59,10 +61,11 @@ int main(void) int lastSpace = 0; // Keeping track of last valid space to insert '\n' int lastWrapStart = 0; // Keeping track of the start of this wrapped line. - while (lines[i][j] != '\0') + while (j <= strlen(lines[i])) { - if (lines[i][j] == ' ') + if (lines[i][j] == ' ' || lines[i][j] == '\0') { + char before = lines[i][j]; // Making a C Style string by adding a '\0' at the required location so that we can use the MeasureText function lines[i][j] = '\0'; @@ -75,7 +78,7 @@ int main(void) lastWrapStart = lastSpace + 1; } - lines[i][j] = ' '; // Resetting the space back + if(before != '\0') lines[i][j] = ' '; // Resetting the space back lastSpace = j; // Since we encountered a new space we update our last encountered space location } @@ -92,7 +95,7 @@ int main(void) textHeight += (int)size.y + 10; } - // A simple scrollbar on the side to show how far we have red into the file + // A simple scrollbar on the side to show how far we have read into the file Rectangle scrollBar = { .x = (float)screenWidth - 5, .y = 0, @@ -132,7 +135,13 @@ int main(void) for (int i = 0, t = textTop; i < lineCount; i++) { // Each time we go through and calculate the height of the text to move the cursor appropriately - Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2); + Vector2 size; + if(strcmp(lines[i], "")){ + // Fix for empty line in the text file + size = MeasureTextEx( GetFontDefault(), lines[i], (float)fontSize, 2); + }else{ + size = MeasureTextEx( GetFontDefault(), " ", (float)fontSize, 2); + } DrawText(lines[i], 10, t, fontSize, RED); From 8b3ea995f91742fffae313e9b22aef6f080bec3f Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 8 Nov 2025 11:32:58 +0100 Subject: [PATCH 068/189] Update parse_api.yml --- .github/workflows/parse_api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/parse_api.yml b/.github/workflows/parse_api.yml index e095e4a55..c6aa59bfe 100644 --- a/.github/workflows/parse_api.yml +++ b/.github/workflows/parse_api.yml @@ -32,6 +32,6 @@ jobs: set -x git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add tools/rlparser + git add tools/rlparser/output git commit -m "rlparser: update raylib_api.* by CI" git push From 2a324ace277ed2b510678457c1d6d837be1c9231 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 8 Nov 2025 11:35:34 +0100 Subject: [PATCH 069/189] Update parse_api.yml --- .github/workflows/parse_api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/parse_api.yml b/.github/workflows/parse_api.yml index c6aa59bfe..e25cde18b 100644 --- a/.github/workflows/parse_api.yml +++ b/.github/workflows/parse_api.yml @@ -22,7 +22,7 @@ jobs: - name: Diff parse files id: diff run: | - git add -N tools/rlparser + git add -N tools/rlparser/output git diff --name-only --exit-code continue-on-error: true From d7a7eda959e6dff41274e06c3b2621f4e40e5963 Mon Sep 17 00:00:00 2001 From: Hugo Date: Sat, 8 Nov 2025 11:36:42 +0100 Subject: [PATCH 070/189] [examples] `core_directory_files` fixes (#5343) * [examples] reset on folder click `continue` after clicking a new folder * [examples] don't make non-directories clickable `IsPathFile` is not enough to check if it's a directory since it also takes in char devices. * rlparser: update raylib_api.* by CI * Delete tools/rlparser/rlparser --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Ray --- examples/core/core_directory_files.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index b7e11b686..83a4239d0 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -69,18 +69,19 @@ int main(void) DrawText(directory, 100, 40, 20, DARKGRAY); btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<"); - + for (int i = 0; i < (int)files.count; i++) { Color color = Fade(LIGHTGRAY, 0.3f); - if (!IsPathFile(files.paths[i])) + if (!IsPathFile(files.paths[i]) && DirectoryExists(files.paths[i])) { if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, "")) { strcpy(directory, files.paths[i]); UnloadDirectoryFiles(files); files = LoadDirectoryFiles(directory); + continue; } } From 0b4815b8fe861f8fbeac35f46f7e1ff78891b7b5 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 9 Nov 2025 13:43:08 +0100 Subject: [PATCH 071/189] WARNING: REMOVED: GIT recording option, added example --- examples/README.md | 2 +- examples/core/core_screen_recording.c | 118 ++++++++++++++++++++-- examples/core/core_screen_recording.png | Bin 17323 -> 17353 bytes {src/external => examples/core}/msf_gif.h | 0 examples/examples_list.txt | 2 +- src/config.h | 2 - src/raylib.h | 1 - src/rcore.c | 102 +------------------ tools/rexm/examples_report.md | 2 +- tools/rexm/examples_report_issues.md | 1 - 10 files changed, 112 insertions(+), 118 deletions(-) rename {src/external => examples/core}/msf_gif.h (100%) diff --git a/examples/README.md b/examples/README.md index f1f6c80b3..9a208f599 100644 --- a/examples/README.md +++ b/examples/README.md @@ -68,7 +68,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [core_input_actions](core/core_input_actions.c) | core_input_actions | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) | | [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_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 | [Robin](https://github.com/RobinsAviary) | | [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) | diff --git a/examples/core/core_screen_recording.c b/examples/core/core_screen_recording.c index 43c90eec5..633ddcf81 100644 --- a/examples/core/core_screen_recording.c +++ b/examples/core/core_screen_recording.c @@ -2,12 +2,10 @@ * * raylib [core] example - screen recording * -* Example complexity rating: [★☆☆☆] 1/4 +* Example complexity rating: [★★☆☆] 2/4 * * Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev * -* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5) -* * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * @@ -17,6 +15,16 @@ #include "raylib.h" +// Using msf_gif library to record frames into GIF +#define MSF_GIF_IMPL +#include "msf_gif.h" // GIF recording functionality + +#include // Required for: sinf() + +#define GIF_RECORD_FRAMERATE 5 // Record framerate, we get a frame every N frames + +#define MAX_SINEWAVE_POINTS 256 + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -29,7 +37,20 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording"); - // TODO: Load resources / Initialize variables at this point + bool gifRecording = false; // GIF recording state + unsigned int gifFrameCounter = 0; // GIF frames counter + MsfGifState gifState = { 0 }; // MSGIF context state + + Vector2 circlePosition = { 0.0f, screenHeight/2.0f }; + float timeCounter = 0.0f; + + // Get sine wave points for line drawing + Vector2 sinePoints[MAX_SINEWAVE_POINTS] = { 0 }; + for (int i = 0; i < MAX_SINEWAVE_POINTS; i++) + { + sinePoints[i].x = i*GetScreenWidth()/180.0f; + sinePoints[i].y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*(1.0f/60.0f)*(float)i); // Calculate for 60 fps + } SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -39,7 +60,59 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // TODO: Update variables / Implement example logic at this point + // Update circle sinusoidal movement + timeCounter += GetFrameTime(); + circlePosition.x += GetScreenWidth()/180.0f; + circlePosition.y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*timeCounter); + if (circlePosition.x > screenWidth) + { + circlePosition.x = 0.0f; + circlePosition.y = screenHeight/2.0f; + timeCounter = 0.0f; + } + + // Start-Stop GIF recording on CTRL+R + if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_R)) + { + if (gifRecording) + { + // Stop current recording and save file + gifRecording = false; + MsfGifResult result = msf_gif_end(&gifState); + SaveFileData(TextFormat("%s/screenrecording.gif", GetApplicationDirectory()), result.data, (unsigned int)result.dataSize); + msf_gif_free(result); + + TraceLog(LOG_INFO, "Finish animated GIF recording"); + } + else + { + // Start a new recording + gifRecording = true; + gifFrameCounter = 0; + msf_gif_begin(&gifState, GetRenderWidth(), GetRenderHeight()); + + TraceLog(LOG_INFO, "Start animated GIF recording"); + } + } + + if (gifRecording) + { + gifFrameCounter++; + + // NOTE: We record one gif frame depending on the desired gif framerate + if (gifFrameCounter > GIF_RECORD_FRAMERATE) + { + // Get image data for the current frame (from backbuffer) + // WARNING: This process is quite slow, it can generate stuttering + Image imScreen = LoadImageFromScreen(); + + // Add the frame to the gif recording, providing and "estimated" time for display in centiseconds + msf_gif_frame(&gifState, imScreen.data, (int)((1.0f/60.0f)*GIF_RECORD_FRAMERATE)/10, 16, imScreen.width*4); + gifFrameCounter = 0; + + UnloadImage(imScreen); // Free image data + } + } //---------------------------------------------------------------------------------- // Draw @@ -48,20 +121,43 @@ int main(void) ClearBackground(RAYWHITE); - // TODO: Draw everything that requires to be drawn at this point + for (int i = 0; i < (MAX_SINEWAVE_POINTS - 1); i++) + { + DrawLineV(sinePoints[i], sinePoints[i + 1], MAROON); + DrawCircleV(sinePoints[i], 3, MAROON); + } - DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED); - DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED); - DrawText("example base code template", 260, 400, 20, LIGHTGRAY); + DrawCircleV(circlePosition, 30, RED); + DrawFPS(10, 10); + + /* + // Draw record indicator + // WARNING: If drawn here, it will appear in the recorded image, + // use a render texture instead for the recording and LoadImageFromTexture(rt.texture) + if (gifRecording) + { + // Display the recording indicator every half-second + if ((int)(GetTime()/0.5)%2 == 1) + { + DrawCircle(30, GetScreenHeight() - 20, 10, MAROON); + DrawText("GIF RECORDING", 50, GetScreenHeight() - 25, 10, RED); + } + } + */ EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - - // TODO: Unload all loaded resources at this point + // If still recording a GIF on close window, just finish + if (gifRecording) + { + MsfGifResult result = msf_gif_end(&gifState); + msf_gif_free(result); + gifRecording = false; + } CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/core/core_screen_recording.png b/examples/core/core_screen_recording.png index da99bbb0d97118eef3ca41c16b62182acced63f9..9b14af24d5f8472e403671d78ac8c629f3612bc2 100644 GIT binary patch literal 17353 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 CaB8Rk literal 17323 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 1000/GIF_RECORD_FRAMERATE) - { - // Get image data for the current frame (from backbuffer) - // NOTE: This process is quite slow... :( - Vector2 scale = GetWindowScaleDPI(); - unsigned char *screenData = rlReadScreenPixels((int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); - - #ifndef GIF_RECORD_BITRATE - #define GIF_RECORD_BITRATE 16 - #endif - - // Add the frame to the gif recording, given how many frames have passed in centiseconds - msf_gif_frame(&gifState, screenData, gifFrameCounter/10, GIF_RECORD_BITRATE, (int)((float)CORE.Window.render.width*scale.x)*4); - gifFrameCounter -= 1000/GIF_RECORD_FRAMERATE; - - RL_FREE(screenData); // Free image data - } - - #if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MODULE_RTEXT) - // Display the recording indicator every half-second - if ((int)(GetTime()/0.5)%2 == 1) - { - DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON); // WARNING: Module required: rshapes - DrawText("GIF RECORDING", 50, CORE.Window.screen.height - 25, 10, RED); // WARNING: Module required: rtext - } - #endif - - rlDrawRenderBatchActive(); // Update and draw internal render batch - } -#endif - #if defined(SUPPORT_AUTOMATION_EVENTS) if (automationEventRecording) RecordAutomationEvent(); // Event recording #endif @@ -1002,38 +934,8 @@ void EndDrawing(void) #if defined(SUPPORT_SCREEN_CAPTURE) if (IsKeyPressed(KEY_F12)) { -#if defined(SUPPORT_GIF_RECORDING) - if (IsKeyDown(KEY_LEFT_CONTROL)) - { - if (gifRecording) - { - gifRecording = false; - - MsfGifResult result = msf_gif_end(&gifState); - - SaveFileData(TextFormat("%s/screenrec%03i.gif", CORE.Storage.basePath, screenshotCounter), result.data, (unsigned int)result.dataSize); - msf_gif_free(result); - - TRACELOG(LOG_INFO, "SYSTEM: Finish animated GIF recording"); - } - else - { - gifRecording = true; - gifFrameCounter = 0; - - Vector2 scale = GetWindowScaleDPI(); - msf_gif_begin(&gifState, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y)); - screenshotCounter++; - - TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter)); - } - } - else -#endif // SUPPORT_GIF_RECORDING - { - TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); - screenshotCounter++; - } + TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); + screenshotCounter++; } #endif // SUPPORT_SCREEN_CAPTURE diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md index 24977e38e..e3d64137b 100644 --- a/tools/rexm/examples_report.md +++ b/tools/rexm/examples_report.md @@ -63,7 +63,7 @@ Example elements validated: | core_input_actions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_directory_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_highdpi_testbed | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_screen_recording | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_screen_recording | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_clipboard_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_text_file_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_compute_hash | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/examples_report_issues.md b/tools/rexm/examples_report_issues.md index 8d24a251d..081170806 100644 --- a/tools/rexm/examples_report_issues.md +++ b/tools/rexm/examples_report_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_screen_recording | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From f76e3714364fdd96756cb2fcaee3be5c48f8b35f Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 9 Nov 2025 19:14:46 +0100 Subject: [PATCH 072/189] REDESIGNED: `core_clipboard_text`, based on #5248 --- examples/README.md | 2 +- examples/core/core_clipboard_text.c | 216 +++++++++++--------------- examples/core/core_clipboard_text.png | Bin 15878 -> 17783 bytes examples/examples_list.txt | 2 +- 4 files changed, 94 insertions(+), 126 deletions(-) diff --git a/examples/README.md b/examples/README.md index 9a208f599..29cea47fb 100644 --- a/examples/README.md +++ b/examples/README.md @@ -69,7 +69,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [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 | [Robin](https://github.com/RobinsAviary) | +| [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) | diff --git a/examples/core/core_clipboard_text.c b/examples/core/core_clipboard_text.c index c9d22c54a..895c235da 100644 --- a/examples/core/core_clipboard_text.c +++ b/examples/core/core_clipboard_text.c @@ -2,22 +2,23 @@ * * raylib [core] example - clipboard text * -* Example complexity rating: [★☆☆☆] 1/4 -* * Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev * -* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5) +* Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2025 Robin (@RobinsAviary) +* Copyright (c) 2025 Ananth S (@Ananth1839) * ********************************************************************************************/ #include "raylib.h" -#include +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" + +#define MAX_TEXT_SAMPLES 5 //------------------------------------------------------------------------------------ // Program main entry point @@ -31,30 +32,32 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text"); - const char *clipboardText = NULL; + // Define some sample texts + const char *sampleTexts[MAX_TEXT_SAMPLES] = { + "Hello from raylib!", + "The quick brown fox jumps over the lazy dog", + "Clipboard operations are useful!", + "raylib is a simple and easy-to-use library", + "Copy and paste me!" + }; - // List of text the user can switch through and copy - const char *copyableText[] = { "raylib is fun", "hello, clipboard!", "potato chips" }; + char *clipboardText = NULL; + char inputBuffer[256] = "Hello from raylib!"; // Random initial string - unsigned int textIndex = 0; + // UI required variables + bool textBoxEditMode = false; - const char *popupText = NULL; + bool btnCutPressed = false; + bool btnCopyPressed = false; + bool btnPastePressed = false; + bool btnClearPressed = false; + bool btnRandomPressed = false; - // Initialize timers - // The amount of time the pop-up text is on screen, before fading - const float maxTime = 3.0f; - float textTimer = 0.0f; - // The length of time text is offset - const float animMaxTime = 0.1f; - float pasteAnim = 0.0f; - float copyAnim = 0.0f; - int copyAnimMult = 1; - float textAnim = 0.0f; - float textAlpha = 0.0f; - // Offset amount for animations - const int offsetAmount = -4; + // Set UI style + GuiSetStyle(DEFAULT, TEXT_SIZE, 20); + GuiSetIconScale(2); - SetTargetFPS(60); + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop @@ -62,83 +65,56 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // Check if the user has pressed the copy/paste key combinations - bool pastePressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V)); - bool copyPressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C)); - - // Update animation timers - if (textTimer > 0) textTimer -= GetFrameTime(); - if (pasteAnim > 0) pasteAnim -= GetFrameTime(); - if (copyAnim > 0) copyAnim -= GetFrameTime(); - if (textAnim > 0) textAnim -= GetFrameTime(); - - if (pastePressed) + // Handle button interactions + if (btnCutPressed) { - // Most operating systems hide this information until the user presses Ctrl-V on the window. + SetClipboardText(inputBuffer); + clipboardText = GetClipboardText(); + inputBuffer[0] = '\0'; // Quick solution to clear text + //memset(inputBuffer, 0, 256); // Clear full buffer properly + } - // Check to see if the clipboard contains an image - // This function does nothing outside of Windows, as it directly calls the Windows API - Image image = GetClipboardImage(); - - if (IsImageValid(image)) + if (btnCopyPressed) + { + SetClipboardText(inputBuffer); // Copy text to clipboard + clipboardText = GetClipboardText(); // Get text from clipboard + } + + if (btnPastePressed) + { + // Paste text from clipboard + clipboardText = GetClipboardText(); + if (clipboardText != NULL) TextCopy(inputBuffer, clipboardText); + } + + if (btnClearPressed) + { + inputBuffer[0] = '\0'; // Quick solution to clear text + //memset(inputBuffer, 0, 256); // Clear full buffer properly + } + + if (btnRandomPressed) + { + // Get random text from sample list + TextCopy(inputBuffer, sampleTexts[GetRandomValue(0, MAX_TEXT_SAMPLES - 1)]); + } + + // Quick cut/copy/paste with keyboard shortcuts + if (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL)) + { + if (IsKeyPressed(KEY_X)) { - UnloadImage(image); - popupText = "clipboard contains image"; + SetClipboardText(inputBuffer); + inputBuffer[0] = '\0'; // Quick solution to clear text } - else + + if (IsKeyPressed(KEY_C)) SetClipboardText(inputBuffer); + + if (IsKeyPressed(KEY_V)) { clipboardText = GetClipboardText(); - - popupText = "text pasted"; - pasteAnim = animMaxTime; + if (clipboardText != NULL) TextCopy(inputBuffer, clipboardText); } - - // Reset animation values - textTimer = maxTime; - textAnim = animMaxTime; - textAlpha = 1; - } - - // React to the user pressing copy - if (copyPressed) - { - // Set the text on the user's clipboard - SetClipboardText(copyableText[textIndex]); - - // Reset values - textTimer = maxTime; - textAnim = animMaxTime; - copyAnim = animMaxTime; - copyAnimMult = 1; - textAlpha = 1; - popupText = "text copied"; - } - - // Switch to the next item in the list when the user presses up - if (IsKeyPressed(KEY_UP)) - { - // Reset animation - copyAnim = animMaxTime; - copyAnimMult = 1; - - textIndex += 1; - - if (textIndex >= sizeof(copyableText) / sizeof(const char*)) // Length of array - { - // Loop back to the other end - textIndex = 0; - } - } - - // Switch to the previous item in the list when the user presses down - if (IsKeyPressed(KEY_DOWN)) - { - // Reset animation - copyAnim = animMaxTime; - copyAnimMult = -1; - - if (textIndex == 0) textIndex = (sizeof(copyableText)/sizeof(const char*)) - 1; - else textIndex -= 1; } //---------------------------------------------------------------------------------- @@ -146,40 +122,32 @@ int main(void) //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(RAYWHITE); + ClearBackground(RAYWHITE); - // Draw the user's pasted text, if there is any yet - if (clipboardText) - { - // Offset animation - int offset = 0; - if (pasteAnim > 0) offset = offsetAmount; + // Draw instructions + GuiLabel((Rectangle){ 50, 20, 700, 36 }, "Use the BUTTONS or KEY SHORTCUTS:"); + DrawText("[CTRL+X] - CUT | [CTRL+C] COPY | [CTRL+V] | PASTE", 50, 60, 20, MAROON); - // Draw the pasted text - DrawText("pasted clipboard:", 10, 10 + offset, 20, DARKGREEN); - DrawText(clipboardText, 10, 30 + offset, 20, DARKGRAY); - } + // Draw text box + if (GuiTextBox((Rectangle){ 50, 120, 652, 40 }, inputBuffer, 256, textBoxEditMode)) textBoxEditMode = !textBoxEditMode; - // Offset animation - int textOffset = 0; - if (copyAnim > 0) textOffset = offsetAmount; + // Random text button + btnRandomPressed = GuiButton((Rectangle){ 50 + 652 + 8, 120, 40, 40 }, "#77#"); - // Draw copyable text and controls - DrawText(copyableText[textIndex], 10, 330 + (textOffset * copyAnimMult), 20, MAROON); - DrawText("up/down to change string, ctrl-c to copy, ctrl-v to paste", 10, 355, 20, DARKGRAY); + // Draw buttons + btnCutPressed = GuiButton((Rectangle){ 50, 180, 158, 40 }, "#17#CUT"); + btnCopyPressed = GuiButton((Rectangle){ 50 + 165, 180, 158, 40 }, "#16#COPY"); + btnPastePressed = GuiButton((Rectangle){ 50 + 165*2, 180, 158, 40 }, "#18#PASTE"); + btnClearPressed = GuiButton((Rectangle){ 50 + 165*3, 180, 158, 40 }, "#143#CLEAR"); - // Alpha / Offset animation - if (textAlpha > 0) - { - // Offset animation - int offset = 0; - if (textAnim > 0) offset = offsetAmount; - // Draw pop up text - DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha)); - - // Fade-out animation - if (textTimer < 0) textAlpha -= GetFrameTime(); - } + // Draw clipboard status + GuiSetState(STATE_DISABLED); + GuiLabel((Rectangle){ 50, 260, 700, 40 }, "Clipboard current text data:"); + GuiSetStyle(TEXTBOX, TEXT_READONLY, 1); + GuiTextBox((Rectangle){ 50, 300, 700, 40 }, clipboardText, 256, false); + GuiSetStyle(TEXTBOX, TEXT_READONLY, 0); + GuiLabel((Rectangle){ 50, 360, 700, 40 }, "Try copying text from other applications and pasting here!"); + GuiSetState(STATE_NORMAL); EndDrawing(); //---------------------------------------------------------------------------------- @@ -191,4 +159,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/examples/core/core_clipboard_text.png b/examples/core/core_clipboard_text.png index caa9b314a694bdb9316f9f8d07161887d53887e6..96a7379c7d956fad97ce1a17eeec7df011d5f422 100644 GIT binary patch literal 17783 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 delta 2729 zcmey~#n@IeL7B<+>_*jTj8=-)%!lqKoMSljrB5j8cK7KTueY)*J}e6V!&CmhS8U&6 zMFS}&6e7kcp@j2VMwHy-LPu%d4LxmNFK{%j=T&!KoHdzIT8y);hNI_PLyy{{$s0AL zO&Bg3D;#;Zy`lHYum7>QbkBnJ z>lrhRCLd%J;k0l{C}B%6QSF=D$S7fWL6^nj9&=N+KGVXP93}D(r5M#q*E4T?)mdtO zX6}+z>LSToZXI^auIHWlL(TMW?=-{7g%)(5IjTIJa=1+d8DlO}h;tl}`-uoA)fb10JbnpQ?ec5D?(=8azzGqzcRgNjiIqQoY@2@4A zS?}j6Ucb6{c|z~BMJPc64j~I?u!B><4)z5(cpjr->00}ZuU76&XQ@@0cV(~Ym3x;R z*8Ocs%gYdz-yq_V{n^v^<&jxbzQ}VQ zu4Q!vOHW<=A)%`}`6Gu2XIm1))wd^a)U=wsUq*%9;fvgaix!fTFY-xp@iKZr9L77j zfl*TGf-Vc2FT0AB)hx!Am2ZoqW?El(C!_UG>g?&s6RpKK8)U#%zDxvJ$$P*^>YB4L z%QU@ME2+}S6RpKLpFm>eBG{8U7j#)V<}oUk)wAWK%nSKyAiwyvv;0f>oM(@^G_!UJ z->v!bLDhWE$X>Q;+zrxdaQF6k?FD8=@GRg>S`rZ&wz5bYockz>VOC`_F27A)M6B1zaLD8(t zaMD;|$-9FKrd1WaXKrj&*|SyFf5t;P&Jyp;f1Zj;)(W? z8>J+W*vQ`k(Ec9B3uZkqQaC z^`OAh2W9UTw`YlZZM_#Jua>*cVSmQP$(UismB8#Y#=A8^e?4=~OnU7<Fc=3own^*n1nz3^7LMc&B8HmZUARkExU(jXAsN+9TaKG4L^Q-CilsX5~7m}RM@tPP}21^c9{w(OQzz87lE{@}#kk)zVn#t+2`h(P)pY!8>N`~)sTrp=^=wE|?r^Xwf@^3wy zy=3{}gHrc-7AKgnv;}~zSGx`_^(JrA6su=A`@KOxs#5VuaFF{JkFEVN-vwXmdHwB| zvpaH5f_KVZgYQDw_KN=>NChq}wc)?^LD}5)!Kw5wr}URh%kcKR^Vl_WpTf1;7PlW4 z?{1uOs`_eM^gs2jdlr=6PS~-;IjjA4f_HmMTFQmL{#kpSvVMBzSo*%{d6+S~!i1$Q znWN_%OGD4H*ONDD$~Y~sW$lj2u5`bA=>cEkK`SPg-13Q5MRv3D*wZ<5WNmBnO)~kK z1SEXhe<(NJ`7}H1>6aHi$1^q>N-@oVq#3QrfeJE?&3SAoCC`#mmepmw-?_j#LQQ&QskMx3JXG)+*U_)^vAg21rR4e01_bDe3x#Cz1j| z*Nuc$&x=wv+EOI1<96Zf^6$6&V!kcx-@vogmS+o}d)9L9B=;>RzKU=B=<|Nlq&o#F zr7ROB*dAF{?&U70sXN`{EBnG9GFm_9-}=dG8{>9aG1F3h8o!3``5mtuXZ&!u?)+q# zaMbk6SM=E3Zl74JXaLViZ3iYdGm3%ImBjwKzrW^-Z41m^l4_#c)5f6doM19HNWJ9Z z;X;!b_s_b9iVkl}jArq*r|**1^>;fxd9tCoy0OmUL|ZAQ!&WeJ|{)bRn~!NG9x(U)G6w=*y>FnGH9xvX Date: Sun, 9 Nov 2025 19:22:12 +0100 Subject: [PATCH 073/189] Update rexm.c --- tools/rexm/rexm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 450e95819..a7cf88ba0 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -2154,11 +2154,12 @@ static char **ScanExampleResources(const char *filePath, int *resPathCount) int functionIndex01 = TextFindIndex(ptr - 40, "ExportImage"); // Check ExportImage() int functionIndex02 = TextFindIndex(ptr - 10, "TraceLog"); // Check TraceLog() int functionIndex03 = TextFindIndex(ptr - 40, "TakeScreenshot"); // Check TakeScreenshot() - + int functionIndex04 = TextFindIndex(ptr - 40, "SaveFileData"); // Check SaveFileData() if (!((functionIndex01 != -1) && (functionIndex01 < 40)) && // Not found ExportImage() before "" !((functionIndex02 != -1) && (functionIndex02 < 10)) && // Not found TraceLog() before "" - !((functionIndex03 != -1) && (functionIndex03 < 40))) // Not found TakeScreenshot() before "" + !((functionIndex03 != -1) && (functionIndex03 < 40)) && // Not found TakeScreenshot() before "" + !((functionIndex04 != -1) && (functionIndex04 < 40))) // Not found SaveFileData() before "" { int len = (int)(end - start); if ((len > 0) && (len < REXM_MAX_RESOURCE_PATH_LEN)) From d8601121da44b993f2893e9afd51b85105c6e698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Sun, 9 Nov 2025 17:08:26 -0500 Subject: [PATCH 074/189] [examples] Added: `textures_sprite_stacking` example (#5345) * Added sprite stacking example * added link * formatting --- examples/textures/resources/booth.png | Bin 0 -> 63521 bytes examples/textures/textures_sprite_stacking.c | 115 ++++++++++++++++++ .../textures/textures_sprite_stacking.png | Bin 0 -> 52440 bytes 3 files changed, 115 insertions(+) create mode 100644 examples/textures/resources/booth.png create mode 100644 examples/textures/textures_sprite_stacking.c create mode 100644 examples/textures/textures_sprite_stacking.png diff --git a/examples/textures/resources/booth.png b/examples/textures/resources/booth.png new file mode 100644 index 0000000000000000000000000000000000000000..b4147f77b9818ad3a70ffc66dce16ef3e0f56e8a GIT binary patch literal 63521 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 0; i--) + { + Rectangle source = { 0.0f, (float)i*frameHeight, frameWidth, frameHeight }; + // Center vertically + Rectangle dest = { screenWidth/2.0f, (screenHeight/2.0f) + (i*stackSpacing) - (stackSpacing*stackCount/2.0f), scaledWidth, scaledHeight }; + Vector2 origin = { scaledWidth/2.0f, scaledHeight/2.0f }; + + DrawTexturePro(booth, source, dest, origin, rotation, WHITE); + } + + DrawText("a/d to spin\nmouse wheel to change separation (aka 'angle')", 10, 10, 20, DARKGRAY); + const char *spacingText = TextFormat("current spacing: %.01f", stackSpacing); + DrawText(spacingText, 10, 50, 20, DARKGRAY); + const char *speedText = TextFormat("current speed: %.02f", rotationSpeed); + DrawText(speedText, 10, 70, 20, DARKGRAY); + DrawText("redbooth model (c) kluchek under cc 4.0", 10, 420, 20, DARKGRAY); + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadTexture(booth); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/textures/textures_sprite_stacking.png b/examples/textures/textures_sprite_stacking.png new file mode 100644 index 0000000000000000000000000000000000000000..53b9868235032b5021138f4a7eb4237c36d98985 GIT binary patch literal 52440 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 literal 0 HcmV?d00001 From 78faf6a12070797bc630457f8b507314b4e833dc Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 10 Nov 2025 11:47:50 +0100 Subject: [PATCH 075/189] Update README.md --- examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 29cea47fb..82a91e60b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -21,7 +21,7 @@ You may find it easier to use than other toolchains, especially when it comes to ### category: core [47] -Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality. +Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality. | example | image | difficulty
    level | version
    created | last version
    updated | original
    developer | |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------| From 4e8b087ffe5d3b35513f90e94f70c224244a3e55 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 11 Nov 2025 17:15:40 +0100 Subject: [PATCH 076/189] REVIEWED: `ComputeSHA256()` --- src/rcore.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 706cb2028..84a948320 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2894,7 +2894,7 @@ unsigned int *ComputeMD5(unsigned char *data, int dataSize) // NOTE: Returns a static int[5] array (20 bytes) unsigned int *ComputeSHA1(unsigned char *data, int dataSize) { - #define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) + #define SHA1_ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) static unsigned int hash[5] = { 0 }; // Hash to be returned @@ -2937,7 +2937,7 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize) } // Message schedule: extend the sixteen 32-bit words into eighty 32-bit words: - for (int i = 16; i < 80; i++) w[i] = ROTATE_LEFT(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1); + for (int i = 16; i < 80; i++) w[i] = SHA1_ROTATE_LEFT(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1); // Initialize hash value for this chunk unsigned int a = hash[0]; @@ -2972,10 +2972,10 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize) k = 0xCA62C1D6; } - unsigned int temp = ROTATE_LEFT(a, 5) + f + e + k + w[i]; + unsigned int temp = SHA1_ROTATE_LEFT(a, 5) + f + e + k + w[i]; e = d; d = c; - c = ROTATE_LEFT(b, 30); + c = SHA1_ROTATE_LEFT(b, 30); b = a; a = temp; } @@ -2997,9 +2997,9 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize) // NOTE: Returns a static int[8] array (32 bytes) unsigned int *ComputeSHA256(unsigned char *data, int dataSize) { - #define ROTATE_RIGHT(x, c) ((x >> c) | (x << ((sizeof(unsigned int) * 8) - c))) - #define SHA256_A0(x) (ROTATE_RIGHT(x, 7) ^ ROTATE_RIGHT(x, 18) ^ (x >> 3)) - #define SHA256_A1(x) (ROTATE_RIGHT(x, 17) ^ ROTATE_RIGHT(x, 19) ^ (x >> 10)) + #define SHA256_ROTATE_RIGHT(x, c) ((x >> c) | (x << ((sizeof(unsigned int)*8) - c))) + #define SHA256_A0(x) (SHA256_ROTATE_RIGHT(x, 7) ^ SHA256_ROTATE_RIGHT(x, 18) ^ (x >> 3)) + #define SHA256_A1(x) (SHA256_ROTATE_RIGHT(x, 17) ^ SHA256_ROTATE_RIGHT(x, 19) ^ (x >> 10)) static const unsigned int k[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, @@ -3020,7 +3020,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize) 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; - static unsigned int hash[8]; + static unsigned int hash[8] = { 0 }; hash[0] = 0x6A09e667; hash[1] = 0xbb67ae85; hash[2] = 0x3c6ef372; @@ -3033,13 +3033,15 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize) const unsigned long long int bitLen = ((unsigned long long int)dataSize)*8; unsigned long long int paddedSize = dataSize + sizeof(dataSize); paddedSize += (64 - (paddedSize%64)); - unsigned char *buffer = RL_CALLOC(paddedSize, sizeof(unsigned char)); + unsigned char *buffer = (unsigned char *)RL_CALLOC(paddedSize, sizeof(unsigned char)); memcpy(buffer, data, dataSize); buffer[dataSize] = 0x80; for (int i = 1; i <= sizeof(bitLen); i++) + { buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF; - + } + for (unsigned long long int blockN = 0; blockN < paddedSize/64; blockN++) { unsigned int a = hash[0]; @@ -3052,23 +3054,22 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize) unsigned int h = hash[7]; unsigned char *block = buffer + (blockN*64); - unsigned int w[64]; + unsigned int w[64] = { 0 }; for (int i = 0; i < 16; i++) { - w[i] = - ((unsigned int)block[i*4 + 0] << 24) | - ((unsigned int)block[i*4 + 1] << 16) | - ((unsigned int)block[i*4 + 2] << 8) | - ((unsigned int)block[i*4 + 3]); + w[i] = ((unsigned int)block[i*4 + 0] << 24) | + ((unsigned int)block[i*4 + 1] << 16) | + ((unsigned int)block[i*4 + 2] << 8) | + ((unsigned int)block[i*4 + 3]); } for (int t = 16; t < 64; t++) w[t] = SHA256_A1(w[t - 2]) + w[t - 7] + SHA256_A0(w[t - 15]) + w[t - 16]; for (unsigned long long int t = 0; t < 64; t++) { - unsigned int e1 = (ROTATE_RIGHT(e, 6) ^ ROTATE_RIGHT(e, 11) ^ ROTATE_RIGHT(e, 25)); + unsigned int e1 = (SHA256_ROTATE_RIGHT(e, 6) ^ SHA256_ROTATE_RIGHT(e, 11) ^ SHA256_ROTATE_RIGHT(e, 25)); unsigned int ch = ((e & f) ^ (~e & g)); unsigned int t1 = (h + e1 + ch + k[t] + w[t]); - unsigned int e0 = (ROTATE_RIGHT(a, 2) ^ ROTATE_RIGHT(a, 13) ^ ROTATE_RIGHT(a, 22)); + unsigned int e0 = (SHA256_ROTATE_RIGHT(a, 2) ^ SHA256_ROTATE_RIGHT(a, 13) ^ SHA256_ROTATE_RIGHT(a, 22)); unsigned int maj = ((a & b) ^ (a & c) ^ (b & c)); unsigned int t2 = e0 + maj; @@ -3091,7 +3092,9 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize) hash[6] += g; hash[7] += h; } + RL_FREE(buffer); + return hash; } From fcaea5b1a11b0cd3e040328db037eb87864cec62 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 11 Nov 2025 17:39:53 +0100 Subject: [PATCH 077/189] Remove trailing spaces --- src/platforms/rcore_desktop_rgfw.c | 2 +- src/rcore.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 47160af54..09712a706 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -1343,7 +1343,7 @@ int InitPlatform(void) // TODO: Is this needed by raylib now? // If so, rcore_desktop_sdl should be updated too //SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); - + if (FLAG_IS_SET(CORE.Window.flags, FLAG_VSYNC_HINT)) RGFW_window_swapInterval(platform.window, 1); RGFW_window_makeCurrent(platform.window); diff --git a/src/rcore.c b/src/rcore.c index 84a948320..be1c7a34b 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -3041,7 +3041,7 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize) { buffer[(paddedSize - sizeof(bitLen)) + (i - 1)] = (bitLen >> (8*(sizeof(bitLen) - i))) & 0xFF; } - + for (unsigned long long int blockN = 0; blockN < paddedSize/64; blockN++) { unsigned int a = hash[0]; @@ -3092,9 +3092,9 @@ unsigned int *ComputeSHA256(unsigned char *data, int dataSize) hash[6] += g; hash[7] += h; } - + RL_FREE(buffer); - + return hash; } From 7f82da0031b1b989f19db403e3071d31019adfbe Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 11 Nov 2025 17:40:21 +0100 Subject: [PATCH 078/189] Update rlsw.h --- src/external/rlsw.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/external/rlsw.h b/src/external/rlsw.h index db5a8189d..318d77334 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -7,7 +7,7 @@ * functionality available on rlgl.h library used by raylib, becoming a direct software * rendering replacement for OpenGL 1.1 backend and allowing to run raylib on GPU-less * devices when required -* +* * FEATURES: * - Rendering to custom internal framebuffer with multiple color modes supported: * - Color buffer: RGB - 8-bit (3:3:2) | RGB - 16-bit (5:6:5) | RGB - 24-bit (8:8:8) @@ -50,7 +50,7 @@ * * rlsw capabilities could be customized just defining some internal * values before library inclusion (default values listed): -* +* * #define SW_GL_FRAMEBUFFER_COPY_BGRA true * #define SW_GL_BINDING_COPY_TEXTURE true * #define SW_COLOR_BUFFER_BITS 24 @@ -60,7 +60,7 @@ * #define SW_MAX_TEXTURE_STACK_SIZE 2 * #define SW_MAX_TEXTURES 128 * -* +* * LICENSE: MIT * * Copyright (c) 2025-2026 Le Juez Victor (@Bigfoot71), reviewed by Ramon Santamaria (@raysan5) @@ -71,10 +71,10 @@ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: -* +* * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. -* +* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -648,7 +648,7 @@ SWAPI void swBindTexture(uint32_t id); // Check for SIMD vector instructions // NOTE: Compiler is responsible to enable required flags for host device, // supported features are detected at compiler init but varies depending on compiler - // TODO: This logic must be reviewed to avoid the inclusion of multiple headers + // TODO: This logic must be reviewed to avoid the inclusion of multiple headers // and enable the higher level of SIMD available #if defined(__FMA__) && defined(__AVX2__) #define SW_HAS_FMA_AVX2 @@ -896,7 +896,7 @@ typedef struct { int vertexCounter; // Number of vertices in 'ctx.vertexBuffer' SWdraw drawMode; // Current primitive mode (e.g., lines, triangles) - SWpoly polyMode; // Current polygon filling mode (e.g., lines, triangles) + SWpoly polyMode; // Current polygon filling mode (e.g., lines, triangles) int reqVertices; // Number of vertices required for the primitive being drawn float pointRadius; // Rasterized point radius float lineWidth; // Rasterized line width @@ -1123,9 +1123,9 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) float32x4_t values = vld1q_f32(src); float32x4_t scaled = vmulq_n_f32(values, 255.0f); int32x4_t clamped_s32 = vcvtq_s32_f32(scaled); // f32 -> s32 (truncated) - int16x4_t narrow16_s = vqmovn_s32(clamped_s32); + int16x4_t narrow16_s = vqmovn_s32(clamped_s32); int16x8_t combined16_s = vcombine_s16(narrow16_s, narrow16_s); - uint8x8_t narrow8_u = vqmovun_s16(combined16_s); + uint8x8_t narrow8_u = vqmovun_s16(combined16_s); vst1_lane_u32((uint32_t*)dst, vreinterpret_u32_u8(narrow8_u), 0); #elif defined(SW_HAS_SSE41) __m128 values = _mm_loadu_ps(src); @@ -2690,9 +2690,9 @@ static inline void sw_quad_sort_cw(const sw_vertex_t* *output) const sw_vertex_t *input = RLSW.vertexBuffer; // Calculate the centroid of the quad - float cx = (input[0].screen[0] + input[1].screen[0] + + float cx = (input[0].screen[0] + input[1].screen[0] + input[2].screen[0] + input[3].screen[0])*0.25f; - float cy = (input[0].screen[1] + input[1].screen[1] + + float cy = (input[0].screen[1] + input[1].screen[1] + input[2].screen[1] + input[3].screen[1])*0.25f; // Calculate the angle of each vertex relative to the center @@ -3615,7 +3615,7 @@ bool swInit(int w, int h) RLSW.loadedTextures[0].ty = 0.5f; RLSW.loadedTextureCount = 1; - + SW_LOG("INFO: RLSW: Software renderer initialized successfully\n"); #if defined(SW_HAS_FMA_AVX) && defined(SW_HAS_FMA_AVX2) SW_LOG("INFO: RLSW: Using SIMD instructions: FMA AVX\n"); @@ -4494,13 +4494,13 @@ void swDrawArrays(SWdraw mode, int offset, int count) const float *texMatrix = RLSW.stackTexture[RLSW.stackTextureCounter - 1]; const float *defaultTexcoord = RLSW.current.texcoord; const float *defaultColor = RLSW.current.color; - + const float *positions = RLSW.array.positions; const float *texcoords = RLSW.array.texcoords; const uint8_t *colors = RLSW.array.colors; int end = offset + count; - + for (int i = offset; i < end; i++) { float u, v; @@ -4589,16 +4589,16 @@ void swDrawElements(SWdraw mode, int count, int type, const void *indices) const float *texMatrix = RLSW.stackTexture[RLSW.stackTextureCounter - 1]; const float *defaultTexcoord = RLSW.current.texcoord; const float *defaultColor = RLSW.current.color; - + const float *positions = RLSW.array.positions; const float *texcoords = RLSW.array.texcoords; const uint8_t *colors = RLSW.array.colors; - + for (int i = 0; i < count; i++) { - int index = indicesUb ? indicesUb[i] : + int index = indicesUb ? indicesUb[i] : (indicesUs ? indicesUs[i] : indicesUi[i]); - + float u, v; if (texcoords) { From 8ae2c9cf5f0f69bfca6ea4d794905a06e061509b Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 12 Nov 2025 10:22:56 +0100 Subject: [PATCH 079/189] FIX: `LoadFontDataBDF()` #5346 --- src/rtext.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index b4cd560ba..1705e5b49 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -147,7 +147,7 @@ static int textLineSpacing = 2; // Text vertical line spacing in static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) #endif #if defined(SUPPORT_FILEFORMAT_BDF) -static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize); +static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, const int *codepoints, int codepointCount, int *outFontSize); #endif #if defined(SUPPORT_DEFAULT_FONT) @@ -647,7 +647,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz { bool genFontChars = false; stbtt_fontinfo fontInfo = { 0 }; - int *requiredCodepoints = (int *)codepoints; + int *requiredCodepoints = (int *)codepoints; // TODO: Should we create a shallow copy to avoid "dealing" with a const user array? if (stbtt_InitFont(&fontInfo, (unsigned char *)fileData, 0)) // Initialize font for data reading { @@ -2517,7 +2517,7 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, c char buffer[MAX_BUFFER_SIZE] = { 0 }; GlyphInfo *glyphs = NULL; - bool genFontChars = false; + bool internalCodepoints = false; int totalReadBytes = 0; // Data bytes read (total) int readBytes = 0; // Data bytes read (line) @@ -2545,21 +2545,23 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, c int charDWidthX = 0; // Character advance X int charDWidthY = 0; // Character advance Y (unused) - GlyphInfo *glyphs = NULL; // Pointer to output glyph info (NULL if not set) - int *requiredCodepoints = codepoints; + int *requiredCodepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); if (fileData == NULL) return glyphs; // In case no chars count provided, default to 95 codepointCount = (codepointCount > 0)? codepointCount : 95; - // Fill fontChars in case not provided externally - // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) - if (requiredCodepoints == NULL) + if (codepoints == NULL) { - requiredCodepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); + // Fill internal codepoints array in case not provided externally + // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) for (int i = 0; i < codepointCount; i++) requiredCodepoints[i] = i + 32; - genFontChars = true; + internalCodepoints = true; + } + else + { + for (int i = 0; i < codepointCount; i++) requiredCodepoints[i] = codepoints[i]; } glyphs = (GlyphInfo *)RL_CALLOC(codepointCount, sizeof(GlyphInfo)); @@ -2634,11 +2636,11 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, c // Search for glyph index in codepoints glyphs = NULL; - for (int codepointIndex = 0; codepointIndex < codepointCount; codepointIndex++) + for (int index = 0; index < codepointCount; index++) { - if (codepoints[codepointIndex] == charEncoding) + if (requiredCodepoints[index] == charEncoding) { - glyphs = &glyphs[codepointIndex]; + glyphs = &glyphs[index]; break; } } @@ -2738,7 +2740,7 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, c } } - if (genFontChars) RL_FREE(codepoints); + RL_FREE(requiredCodepoints); if (fontMalformed) { From 4dbe04b250d1e44c6e7f0f89d4b3763b20d852cb Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2025 11:26:54 +0100 Subject: [PATCH 080/189] Update config.h --- src/config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.h b/src/config.h index 8e6e6a5fa..9152acc8c 100644 --- a/src/config.h +++ b/src/config.h @@ -59,6 +59,7 @@ // Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy #define SUPPORT_PARTIALBUSY_WAIT_LOOP 1 // Allow automatic screen capture of current screen pressing F12, defined in KeyCallback() +// WARNING: It also requires SUPPORT_IMAGE_EXPORT and SUPPORT_FILEFORMAT_PNG flags #define SUPPORT_SCREEN_CAPTURE 1 // Support CompressData() and DecompressData() functions #define SUPPORT_COMPRESSION_API 1 From 9c73b0eb3715d7855c306f49a4543514c2315be7 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2025 20:36:57 +0100 Subject: [PATCH 081/189] Update Makefile --- examples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Makefile b/examples/Makefile index 729459de4..f70e6993d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -77,7 +77,7 @@ RAYLIB_SRC_PATH ?= ../src # Locations of raylib.h and libraylib.a/libraylib.so # NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD -DESTDIR ?= /usr/local +DESTDIR ?= /usr/local RAYLIB_INCLUDE_PATH ?= $(DESTDIR)/include RAYLIB_LIB_PATH ?= $(DESTDIR)/lib From d172a24bb0fdc1f097b6ccfcc763f673eae6d2e7 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2025 20:37:21 +0100 Subject: [PATCH 082/189] REVIEWED: `main(void)` --- examples/core/core_window_should_close.c | 2 +- examples/models/models_point_rendering.c | 2 +- examples/models/models_waving_cubes.c | 2 +- examples/others/web_basic_window.c | 2 +- examples/shaders/shaders_basic_pbr.c | 2 +- examples/textures/textures_textured_curve.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/core/core_window_should_close.c b/examples/core/core_window_should_close.c index bb7daf3ee..f53f9d48d 100644 --- a/examples/core/core_window_should_close.c +++ b/examples/core/core_window_should_close.c @@ -18,7 +18,7 @@ //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- diff --git a/examples/models/models_point_rendering.c b/examples/models/models_point_rendering.c index 3a93fc8d9..ebfad5ac1 100644 --- a/examples/models/models_point_rendering.c +++ b/examples/models/models_point_rendering.c @@ -32,7 +32,7 @@ static Mesh GenMeshPoints(int numPoints); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- diff --git a/examples/models/models_waving_cubes.c b/examples/models/models_waving_cubes.c index 51febf39d..7996c1c8a 100644 --- a/examples/models/models_waving_cubes.c +++ b/examples/models/models_waving_cubes.c @@ -22,7 +22,7 @@ //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- diff --git a/examples/others/web_basic_window.c b/examples/others/web_basic_window.c index f85c6e4f6..217c47fbc 100644 --- a/examples/others/web_basic_window.c +++ b/examples/others/web_basic_window.c @@ -36,7 +36,7 @@ void UpdateDrawFrame(void); // Update and Draw one frame //---------------------------------------------------------------------------------- // Program main entry point //---------------------------------------------------------------------------------- -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- diff --git a/examples/shaders/shaders_basic_pbr.c b/examples/shaders/shaders_basic_pbr.c index 6fb15a607..cc8583830 100644 --- a/examples/shaders/shaders_basic_pbr.c +++ b/examples/shaders/shaders_basic_pbr.c @@ -77,7 +77,7 @@ static void UpdateLight(Shader shader, Light light); //---------------------------------------------------------------------------------- // Program main entry point //---------------------------------------------------------------------------------- -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- diff --git a/examples/textures/textures_textured_curve.c b/examples/textures/textures_textured_curve.c index feeefc7b6..abf78c88a 100644 --- a/examples/textures/textures_textured_curve.c +++ b/examples/textures/textures_textured_curve.c @@ -49,7 +49,7 @@ static void DrawTexturedCurve(void); //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ -int main() +int main(void) { // Initialization //-------------------------------------------------------------------------------------- From 80b6b7fc2a6c49b3778252f2af5b459e6bfb2dc3 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2025 20:37:35 +0100 Subject: [PATCH 083/189] Update core_input_gamepad.c --- examples/core/core_input_gamepad.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index 1da1c4ce0..abfdb11c1 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -196,7 +196,6 @@ int main(void) } else { - // Draw background: generic DrawRectangleRounded((Rectangle){ 175, 110, 460, 220}, 0.3f, 16, DARKGRAY); @@ -269,7 +268,6 @@ int main(void) else { DrawText(TextFormat("GP%d: NOT DETECTED", gamepad), 10, 10, 10, GRAY); - DrawTexture(texXboxPad, 0, 0, LIGHTGRAY); } From 6dcd4cd564ad3ec4811281cc7c397462fb3a6c37 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2025 20:37:59 +0100 Subject: [PATCH 084/189] Update rexm.c --- tools/rexm/rexm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index a7cf88ba0..c3ca04e47 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -404,7 +404,7 @@ int main(int argc, char *argv[]) char *exColInfo = LoadFileText(exCollectionFilePath); if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection { - strcpy(exName, argv[2]); // Register example name for removal + strcpy(exName, argv[2]); // Register example name strncpy(exCategory, exName, TextFindIndex(exName, "_")); opCode = OP_BUILD; } @@ -2155,11 +2155,13 @@ static char **ScanExampleResources(const char *filePath, int *resPathCount) int functionIndex02 = TextFindIndex(ptr - 10, "TraceLog"); // Check TraceLog() int functionIndex03 = TextFindIndex(ptr - 40, "TakeScreenshot"); // Check TakeScreenshot() int functionIndex04 = TextFindIndex(ptr - 40, "SaveFileData"); // Check SaveFileData() + int functionIndex05 = TextFindIndex(ptr - 40, "SaveFileText"); // Check SaveFileText() if (!((functionIndex01 != -1) && (functionIndex01 < 40)) && // Not found ExportImage() before "" !((functionIndex02 != -1) && (functionIndex02 < 10)) && // Not found TraceLog() before "" !((functionIndex03 != -1) && (functionIndex03 < 40)) && // Not found TakeScreenshot() before "" - !((functionIndex04 != -1) && (functionIndex04 < 40))) // Not found SaveFileData() before "" + !((functionIndex04 != -1) && (functionIndex04 < 40)) && // Not found TakeScreenshot() before "" + !((functionIndex05 != -1) && (functionIndex05 < 40))) // Not found SaveFileText() before "" { int len = (int)(end - start); if ((len > 0) && (len < REXM_MAX_RESOURCE_PATH_LEN)) From b5caef1ffb1d006845b2dc38b2d3c2bc18ec338a Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2025 22:48:24 +0100 Subject: [PATCH 085/189] REXM: ADDED: Example automated-testing -WIP- --- tools/rexm/rexm.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index c3ca04e47..1e7865db1 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -121,6 +121,7 @@ typedef enum { OP_VALIDATE = 5, // Validate examples, using [examples_list.txt] as main source by default OP_UPDATE = 6, // Validate and update required examples (as far as possible) OP_BUILD = 7, // Build example for desktop and web, copy web output + OP_TEST = 8, // Test example: check output LOG WARNINGS } rlExampleOperation; static const char *exCategories[REXM_MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio", "others" }; @@ -413,6 +414,36 @@ int main(int argc, char *argv[]) } } } + else if (strcmp(argv[1], "test") == 0) + { + // Build and test example for PLATFORM_DESKTOP + // NOTE: Build outputs to default directory, usually where the .c file is located, + // to avoid issues with copying resources (at least on Desktop) + if (argc == 2) LOG("WARNING: No example name provided to test\n"); + else if (argc > 3) LOG("WARNING: Too many arguments provided\n"); + else + { + // Support building not only individual examples but categories and "ALL" + if ((strcmp(argv[2], "ALL") == 0) || TextInList(argv[2], exCategories, REXM_MAX_EXAMPLE_CATEGORIES)) + { + // Category/ALL rebuilt requested + strcpy(exRebuildRequested, argv[2]); + } + else + { + // Verify example exists in collection to be removed + char *exColInfo = LoadFileText(exCollectionFilePath); + if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection + { + strcpy(exName, argv[2]); // Register example name + strncpy(exCategory, exName, TextFindIndex(exName, "_")); + opCode = OP_TEST; + } + else LOG("WARNING: TEST: Example requested not available in the collection\n"); + UnloadFileText(exColInfo); + } + } + } // Process command line options arguments for (int i = 1; i < argc; i++) @@ -1487,6 +1518,94 @@ int main(int argc, char *argv[]) UnloadExamplesData(exCollection); //------------------------------------------------------------------------------------------------ + } break; + case OP_TEST: + { + LOG("INFO: Command requested: TEST\n"); + LOG("INFO: Example to be built and tested: %s\n", exName); + + // Steps to follow + // STEP 1: Load example.c and replace required code to inject basic testing code: frames to run + // OPTION 1: Code injection required multiple changes for testing but it does not require raylib changes! + // OPTION 2: Support testing on raylib side: Args processing and events injection: SUPPORT_AUTOMATD_TESTING_SYSTEM, EVENTS_TESTING_MODE + // STEP 2: Build example (PLATFORM_DESKTOP) + // STEP 3: Run example with arguments: --frames 2 > .out.log + // STEP 4: Load .out.log and check "WARNING:" messages -> Some could maybe be ignored + // STEP 5: Generate report with results + + // STEP 1: Load example and inject required code + // PROBLEM: As we need to modify the example source code for building, we need to keep a copy or something + // WARNING: If we make a copy and something fails, it could not be restored at the end + // PROBLEM: Trying to build a copy won't work because Makefile is setup to look for specific example on specific path -> No output dir config + // IDEA: Create directory for testing data -> It implies moving files and set working dir... + // SOLUTION: Make a copy of original file -> Modify original -> Build -> Rename to .test.exe + FileCopy(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); + char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + + static const char *mainReplaceText = + "#include \n" + "#include \n" + "int main(int argc, char *argv[])\n{\n" + " int requestedTestFrames = 0;\n" + " int testFramesCount = 0;\n" + " if ((argc > 1) && (argc == 3) && (strcmp(argv[1], \"--frames\") != 0)) requestedTestFrames = atoi(argv[2]);\n"; + + char *srcTextUpdated[3] = { 0 }; + srcTextUpdated[0] = TextReplace(srcText, "int main(void)\n{", mainReplaceText); + srcTextUpdated[1] = TextReplace(srcTextUpdated[0], "WindowShouldClose()", "WindowShouldClose() && (testFramesCount < requestedTestFrames)"); + srcTextUpdated[2] = TextReplace(srcTextUpdated[1], "EndDrawing();", "EndDrawing(); testFramesCount++;"); + UnloadFileText(srcText); + + SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[2]); + for (int i = 0; i < 3; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } + + // STEP 2: Build example for DESKTOP platform +#if defined(_WIN32) + // Set required environment variables + //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + //putenv("MAKE=mingw32-make"); + //ChangeDirectory(exBasePath); +#endif + // Build example for PLATFORM_DESKTOP +#if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); + system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#else + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#endif + // Restore original source code before continue + FileCopy(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); + + // STEP 3: Run example with required arguments + ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); + system(TextFormat("%s --frames 2 > %s.log", exName, exName)); + + // STEP 4: Load and validate log -> WARNINGS + char *exTestLog = LoadFileText(TextFormat("%s/%s/%s.log", exBasePath, exCategory, exName)); + int exTestLogLinesCount = 0; + char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); + UnloadFileText(exTestLog); + + int issueCounter = false; + for (int i = 0; i < exTestLogLinesCount; i++) + { + if (TextFindIndex(exTestLogLines[i], "WARNING") >= 0) + { + LOG("TEST: [%s] %s\n", exName, exTestLogLines[i]); + issueCounter++; + } + } + + UnloadTextLines(exTestLogLines, exTestLogLinesCount); + + // STEP 5: Generate auto-test report + //if (issueCounter > 0) + } break; default: // Help { From c059ece2a4292581d40e17257f8f9f2eec9f3b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Thu, 13 Nov 2025 17:10:13 -0500 Subject: [PATCH 086/189] [examples] Added: directional billboard (#5351) * Added models directional billboard example * add killbot texture * various fixes and formatting tweaks * corrected stdlib --- .../models/models_directional_billboard.c | 116 ++++++++++++++++++ .../models/models_directional_billboard.png | Bin 0 -> 20612 bytes examples/models/resources/skillbot.png | Bin 0 -> 2241 bytes 3 files changed, 116 insertions(+) create mode 100644 examples/models/models_directional_billboard.c create mode 100644 examples/models/models_directional_billboard.png create mode 100644 examples/models/resources/skillbot.png diff --git a/examples/models/models_directional_billboard.c b/examples/models/models_directional_billboard.c new file mode 100644 index 000000000..fe1b33b2d --- /dev/null +++ b/examples/models/models_directional_billboard.c @@ -0,0 +1,116 @@ +/******************************************************************************************* +* +* raylib [models] example - directional billboard +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6 +* +* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025-2025 Robin (@RobinsAviary) +* Killbot art by patvanmackelberg https://opengameart.org/content/killbot-8-directional under CC0 +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" +#include + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - directional billboard"); + + // Set up the camera + Camera camera = { 0 }; + camera.position = (Vector3){ 2.0f, 1.0f, 2.0f }; // Starting position + camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Target position + camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Up vector + camera.fovy = 45.0f; // FOV + camera.projection = CAMERA_PERSPECTIVE; // Projection type (Standard 3D perspective) + + // Load billboard texture + Texture skillbot = LoadTexture("resources/skillbot.png"); + + // Timer to update animation + float anim_timer = 0.0f; + // Animation frame + unsigned int anim = 0; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera, CAMERA_ORBITAL); + + // Update timer with delta time + anim_timer += GetFrameTime(); + + // Update frame index after a certain amount of time (half a second) + if (anim_timer > 0.5f) + { + anim_timer = 0.0f; + anim += 1; + } + + // Reset frame index to zero on overflow + if (anim >= 4) anim = 0; + + // Find the current direction frame based on the camera position to the billboard object + float dir = (float)floor(((Vector2Angle((Vector2){ 2.0f, 0.0f }, (Vector2){ camera.position.x, camera.position.z })/PI)*4.0f) + 0.25f); + + // Correct frame index if angle is negative + if (dir < 0.0f) + { + dir = 8.0f - (float)abs((int)dir); + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginMode3D(camera); + + DrawGrid(10, 1.0f); + + // Draw billboard pointing straight up to the sky, rotated relative to the camera and offset from the bottom + DrawBillboardPro(camera, skillbot, (Rectangle){ 0.0f + (anim*24.0f), 0.0f + (dir*24.0f), 24.0f, 24.0f }, Vector3Zero(), (Vector3){ 0.0f, 1.0f, 0.0f }, Vector2One(), (Vector2){ 0.5f, 0.0f }, 0, WHITE); + + EndMode3D(); + + // Render various variables for reference + DrawText(TextFormat("animation: %d", anim), 10, 10, 20, DARKGRAY); + DrawText(TextFormat("direction frame: %.0f", dir), 10, 40, 20, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + // Unload billboard texture + UnloadTexture(skillbot); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/models/models_directional_billboard.png b/examples/models/models_directional_billboard.png new file mode 100644 index 0000000000000000000000000000000000000000..cbbe11065eef52f7389e697660af68e119443e5d GIT binary patch literal 20612 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 bFfc5V@ztIs_WC{p0|SGntDnm{r-UW|!Md5^ literal 0 HcmV?d00001 diff --git a/examples/models/resources/skillbot.png b/examples/models/resources/skillbot.png new file mode 100644 index 0000000000000000000000000000000000000000..537f1338367ec575c714a6e858200eb07bc7ec1b GIT binary patch literal 2241 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

    Yvo4TgxgU7wKI4Yjj?CM9?c_z- z9hDiy7;1XO7+zUih`A=|u>T-)Q>@@i_5W^pdwWy<@-~#Wu1K8xVIA-Kgr%Z)&)vLV nAAco$JN6v)|MSilHvgH!mtWaqw0@ZpsN(c=^>bP0l+XkK@GOjN literal 0 HcmV?d00001 From 4dca02daa50e390876e64c7fde0d74d8209977b0 Mon Sep 17 00:00:00 2001 From: iann Date: Thu, 13 Nov 2025 16:12:11 -0600 Subject: [PATCH 087/189] first draft of audio fft spectrum visualizer (#5348) --- examples/Makefile | 1 + .../audio/audio_fft_spectrum_visualizer.c | 279 ++++++++++++++++++ .../audio/audio_fft_spectrum_visualizer.png | Bin 0 -> 15580 bytes examples/audio/resources/fft.glsl | 32 ++ 4 files changed, 312 insertions(+) create mode 100644 examples/audio/audio_fft_spectrum_visualizer.c create mode 100644 examples/audio/audio_fft_spectrum_visualizer.png create mode 100644 examples/audio/resources/fft.glsl diff --git a/examples/Makefile b/examples/Makefile index f70e6993d..f36b89bc2 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -703,6 +703,7 @@ SHADERS = \ shaders/shaders_vertex_displacement AUDIO = \ + audio/audio_fft_spectrum_visualizer \ audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ diff --git a/examples/audio/audio_fft_spectrum_visualizer.c b/examples/audio/audio_fft_spectrum_visualizer.c new file mode 100644 index 000000000..ad38020fd --- /dev/null +++ b/examples/audio/audio_fft_spectrum_visualizer.c @@ -0,0 +1,279 @@ +/******************************************************************************************* +* +* raylib [audio] example - fft spectrum visualizer +* +* Example complexity rating: [★★★☆] 3/4 +* +* Example originally created with raylib 6.0 +* +* Inspired by Inigo Quilez's https://www.shadertoy.com/ +* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8 +* +* Example created by created by IANN (@meisei4) reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 IANN (@meisei4) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" +#include +#include +#include + +#define MONO 1 +#define SAMPLE_RATE 44100 +#define SAMPLE_RATE_F 44100.0f +#define FFT_WINDOW_SIZE 1024 +#define BUFFER_SIZE 512 +#define PER_SAMPLE_BIT_DEPTH 16 +#define AUDIO_STREAM_RING_BUFFER_SIZE (FFT_WINDOW_SIZE*2) +#define EFFECTIVE_SAMPLE_RATE (SAMPLE_RATE_F*0.5f) +#define WINDOW_TIME ((double)FFT_WINDOW_SIZE/(double)EFFECTIVE_SAMPLE_RATE) +#define FFT_HISTORICAL_SMOOTHING_DUR 2.0f +#define MIN_DECIBELS (-100.0f) // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/minDecibels +#define MAX_DECIBELS (-30.0f) // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/maxDecibels +#define INVERSE_DECIBEL_RANGE (1.0f/(MAX_DECIBELS - MIN_DECIBELS)) +#define DB_TO_LINEAR_SCALE (20.0f/2.302585092994046f) +#define SMOOTHING_TIME_CONSTANT 0.8f // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/smoothingTimeConstant +#define TEXTURE_HEIGHT 1 +#define FFT_ROW 0 +#define UNUSED_CHANNEL 0.0f + +typedef struct FFTComplex { float real, imaginary; } FFTComplex; + +typedef struct FFTData { + FFTComplex *spectrum; + FFTComplex *workBuffer; + float *prevMagnitudes; + float (*fftHistory)[BUFFER_SIZE]; + int fftHistoryLen; + int historyPos; + double lastFftTime; + float tapbackPos; +} FFTData; + +static void CaptureFrame(FFTData *fftData, const float *audioSamples); +static void RenderFrame(const FFTData *fftData, Image *fftImage); +static void CooleyTukeyFFTSlow(FFTComplex *spectrum, int n); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //----------------------------------------------------------------------------------- --- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [audio] example - fft spectrum visualizer"); + + Image fftImage = GenImageColor(BUFFER_SIZE, TEXTURE_HEIGHT, WHITE); + Texture2D fftTexture = LoadTextureFromImage(fftImage); + RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight); + Vector2 iResolution = { (float)screenWidth, (float)screenHeight }; + + Shader shader = LoadShader(NULL, "resources/fft.glsl"); + int iResolutionLocation = GetShaderLocation(shader, "iResolution"); + int iChannel0Location = GetShaderLocation(shader, "iChannel0"); + SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2); + SetShaderValueTexture(shader, iChannel0Location, fftTexture); + + InitAudioDevice(); + SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE); + + Wave wav = LoadWave("resources/country.mp3"); + WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO); + + AudioStream audioStream = LoadAudioStream(SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO); + PlayAudioStream(audioStream); + + int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1; + + FFTData fft = { + .spectrum = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE), + .workBuffer = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE), + .prevMagnitudes = calloc(BUFFER_SIZE, sizeof(float)), + .fftHistory = calloc(fftHistoryLen, sizeof(float[BUFFER_SIZE])), + .fftHistoryLen = fftHistoryLen, + .historyPos = 0, + .lastFftTime = 0.0, + .tapbackPos = 0.01f + }; + + size_t wavCursor = 0; + const short *wavPCM16 = wav.data; + + short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 }; + float audioSamples[FFT_WINDOW_SIZE] = { 0 }; + + SetTargetFPS(60); + //---------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + while (IsAudioStreamProcessed(audioStream)) + { + for (int i = 0; i < AUDIO_STREAM_RING_BUFFER_SIZE; i++) + { + int left = (wav.channels == 2)? wavPCM16[wavCursor*2 + 0] : wavPCM16[wavCursor]; + int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left; + chunkSamples[i] = (short)((left + right)/2); + + if (++wavCursor >= wav.frameCount) + wavCursor = 0; + + } + + UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE); + + for (int i = 0; i < FFT_WINDOW_SIZE; i++) + audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f; + } + + CaptureFrame(&fft, audioSamples); + RenderFrame(&fft, &fftImage); + UpdateTexture(fftTexture, fftImage.data); + //------------------------------------------------------------------------------ + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(BLACK); + BeginShaderMode(shader); + SetShaderValueTexture(shader, iChannel0Location, fftTexture); + DrawTextureRec(bufferA.texture, + (Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight }, + (Vector2){ 0, 0 }, + WHITE); + EndShaderMode(); + EndDrawing(); + //------------------------------------------------------------------------------ + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shader); + UnloadRenderTexture(bufferA); + UnloadTexture(fftTexture); + UnloadImage(fftImage); + UnloadAudioStream(audioStream); + UnloadWave(wav); + CloseAudioDevice(); + + free(fft.spectrum); + free(fft.workBuffer); + free(fft.prevMagnitudes); + free(fft.fftHistory); + + CloseWindow(); // Close window and OpenGL context + //---------------------------------------------------------------------------------- + + return 0; +} + +// Cooley–Tukey FFT https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms +static void CooleyTukeyFFTSlow(FFTComplex *spectrum, int n) +{ + int j = 0; + for (int i = 1; i < n - 1; i++) + { + int bit = n >> 1; + while (j >= bit) + { + j -= bit; + bit >>= 1; + } + j += bit; + if (i < j) + { + FFTComplex temp = spectrum[i]; + spectrum[i] = spectrum[j]; + spectrum[j] = temp; + } + } + + for (int len = 2; len <= n; len <<= 1) + { + float angle = -2.0f*PI/len; + FFTComplex twiddleUnit = { cosf(angle), sinf(angle) }; + for (int i = 0; i < n; i += len) + { + FFTComplex twiddleCurrent = { 1.0f, 0.0f }; + for (int j = 0; j < len/2; j++) + { + FFTComplex even = spectrum[i + j]; + FFTComplex odd = spectrum[i + j + len/2]; + FFTComplex twiddledOdd = { + odd.real*twiddleCurrent.real - odd.imaginary*twiddleCurrent.imaginary, + odd.real*twiddleCurrent.imaginary + odd.imaginary*twiddleCurrent.real + }; + + spectrum[i + j].real = even.real + twiddledOdd.real; + spectrum[i + j].imaginary = even.imaginary + twiddledOdd.imaginary; + spectrum[i + j + len/2].real = even.real - twiddledOdd.real; + spectrum[i + j + len/2].imaginary = even.imaginary - twiddledOdd.imaginary; + + float twiddleRealNext = twiddleCurrent.real*twiddleUnit.real - twiddleCurrent.imaginary*twiddleUnit.imaginary; + twiddleCurrent.imaginary = twiddleCurrent.real*twiddleUnit.imaginary + twiddleCurrent.imaginary*twiddleUnit.real; + twiddleCurrent.real = twiddleRealNext; + } + } + } +} + +static void CaptureFrame(FFTData *fftData, const float *audioSamples) +{ + for (int i = 0; i < FFT_WINDOW_SIZE; i++) + { + float x = (2.0f*PI*i)/(FFT_WINDOW_SIZE - 1.0f); + float blackmanWeight = 0.42f - 0.5f*cosf(x) + 0.08f*cosf(2.0f*x); // https://en.wikipedia.org/wiki/Window_function#Blackman_window + fftData->workBuffer[i].real = audioSamples[i]*blackmanWeight; + fftData->workBuffer[i].imaginary = 0.0f; + } + + CooleyTukeyFFTSlow(fftData->workBuffer, FFT_WINDOW_SIZE); + memcpy(fftData->spectrum, fftData->workBuffer, sizeof(FFTComplex)*FFT_WINDOW_SIZE); + + float smoothedSpectrum[BUFFER_SIZE]; + + for (int bin = 0; bin < BUFFER_SIZE; bin++) + { + float re = fftData->workBuffer[bin].real; + float im = fftData->workBuffer[bin].imaginary; + float linearMagnitude = sqrtf(re*re + im*im)/FFT_WINDOW_SIZE; + + float smoothedMagnitude = SMOOTHING_TIME_CONSTANT*fftData->prevMagnitudes[bin] + (1.0f - SMOOTHING_TIME_CONSTANT)*linearMagnitude; + fftData->prevMagnitudes[bin] = smoothedMagnitude; + + float db = logf(fmaxf(smoothedMagnitude, 1e-40f))*DB_TO_LINEAR_SCALE; + float normalized = (db - MIN_DECIBELS)*INVERSE_DECIBEL_RANGE; + smoothedSpectrum[bin] = Clamp(normalized, 0.0f, 1.0f); + } + + fftData->lastFftTime = GetTime(); + memcpy(fftData->fftHistory[fftData->historyPos], smoothedSpectrum, sizeof(smoothedSpectrum)); + fftData->historyPos = (fftData->historyPos + 1) % fftData->fftHistoryLen; +} + +static void RenderFrame(const FFTData *fftData, Image *fftImage) +{ + double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME); + framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1); + + int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback) % fftData->fftHistoryLen; + if (historyPosition < 0) + historyPosition += fftData->fftHistoryLen; + + const float *amplitude = fftData->fftHistory[historyPosition]; + for (int bin = 0; bin < BUFFER_SIZE; bin++) { + ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL })); + } +} \ No newline at end of file diff --git a/examples/audio/audio_fft_spectrum_visualizer.png b/examples/audio/audio_fft_spectrum_visualizer.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f1bc8b0acfbc066c241358f06922dcc8133e86 GIT binary patch literal 15580 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 Date: Thu, 13 Nov 2025 23:19:37 +0100 Subject: [PATCH 088/189] REVIEWED: Bunnymark example new `raybunny`! #5344 As the license for previous bunny was not clear, it was replaced by a new custom bunny specifically created for this example with a CC0 license --- examples/textures/resources/LICENSE.md | 2 +- examples/textures/resources/raybunny.png | Bin 0 -> 466 bytes examples/textures/resources/wabbit_alpha.png | Bin 496 -> 0 bytes examples/textures/textures_bunnymark.c | 2 +- examples/textures/textures_bunnymark.png | Bin 436989 -> 433122 bytes 5 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 examples/textures/resources/raybunny.png delete mode 100644 examples/textures/resources/wabbit_alpha.png diff --git a/examples/textures/resources/LICENSE.md b/examples/textures/resources/LICENSE.md index e4ee45304..7d67572c7 100644 --- a/examples/textures/resources/LICENSE.md +++ b/examples/textures/resources/LICENSE.md @@ -8,7 +8,7 @@ | explosion.png | [Unity Labs Paris](https://blogs.unity3d.com/2016/11/28/free-vfx-image-sequences-flipbooks/) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | | parrots.png | [Kodak set](http://r0k.us/graphics/kodak/) | ❔ | Original name: `kodim23.png` | cat.png | ❔ | ❔ | - | -| wabbit_alpha.png | ❔ | ❔ | - | +| raybunny.png | [VoidSrc*](https://x.com/voidsrc) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - | | custom_jupiter_crash.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) | | KAISG.ttf | [Dieter Steffmann](http://www.steffmann.de/wordpress/) | [Freeware](https://www.1001fonts.com/users/steffmann/) | [Kaiserzeit Gotisch](https://www.dafont.com/es/kaiserzeit-gotisch.font) font | | fudesumi.png | [Eiden Marsal](https://www.artstation.com/marshall_z) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/) | - | diff --git a/examples/textures/resources/raybunny.png b/examples/textures/resources/raybunny.png new file mode 100644 index 0000000000000000000000000000000000000000..b608147bcb6b1a3d8413739d52106eea2ecd565a GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANNfGd*1#Ln2z=hMk^z*nmUk zt+#cVdfo}E$!#xKM32ZNJxyF|r{Nc;XRUraLBi93si2`_3ya{&>vf!FJ33Z$%$d~l zX7LaEI3>-cuQp$=n|WZlfosFegJ<+_>kI#2+2^-_JNn{!CzoAw1*%R?Pp#Z{|NZyp zpZC4LS|4Snsk-L%tutTQmu?WaxcRuNOZ1`3pEENLopsK*ZKiX&NkFb!VB)ItyVfx< zgzo3q#qnhEhDK)&1tkWD9>G;rn{Gd@?sV|Vlu$YL!s}A-vEalnTGM83%$=?M@Wgeo zCu>cfB&}pU(HLz#IVejj@t<6>jqa_z%wjVg?%n!S%d(q!>%9;YE!)Fu*ebT@Ubta8 zdCRQL>U_794V#rKO|N^*^>d#TZsoMpdRC>IRYHA^*z#6Qr|Dn#=B{ZuwNnk<^9rc z@$x7Caqc+R*>NSy;l0_JglE}O36sTz*D+a~ZE#=zy0CtSX~HarrNXQ3-}729`GxMk a{c2Z5d6QEZm>C!t7(8A5T-G@yGywoNN7MWO literal 0 HcmV?d00001 diff --git a/examples/textures/resources/wabbit_alpha.png b/examples/textures/resources/wabbit_alpha.png deleted file mode 100644 index db4081fec5a801d4b6f2beeafca4a0dffbe5d333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 496 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4i*LmhMUEk>KPaqw|lxchE&{YnR>SLu>ntu z{gaK;LKUmeZd=HtG+pu6ye$u7E+3E5O#7zLp`=lC_H{o=ZMM#)h?8~#f()HH3;jcK#eXJBAp@O1TaS?83{ F1OUPp>qY-Ta2?;;W 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�o)ru;J4lB-INBuy-c#( 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�iRAL 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 Quc~x=bi73jAc?{pdI#UD0AO0 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≺WvA|C1=gym8|;i#JBT;5NA4r z?)t2MypgZ?Ue`46Fm805E0Drmcv3v}bm|GAW}X?o)uxRH4;^f1l-^d{qY1+8 zipD#{w%xFv-SVW<_w|Nz9{2CuchLPV`Q^g9H7P$g2pc|5c+QgZWOrix%ht8dOrVvV z6EuV_@XuznEcqvLgTH9%f!p2B7tZS|`75B}Wb*co;UCUhC4AyfT&J>?YB+drRNGN% zsN*^RJj1J&1=0*b%%GCiN>;)2g|WtWyF2L*Qe1ROSl@CdHpr|#Ur=?_jBTgOi8k#E zYuZ@gf>uNhzEG+2pl=wn^?G!$BH9zS$szVzPI2&Mf^j8|SdfR9LVyvD!lH}kRfJKTp3 zFua;FBeyff_3=ETzZ?2;ag3#=U+URmEe zpI{Iyz+l9B;1>GUOo>hR;_W}=Ut%h?OOWk<_I1MJWsaNWkLc`dT3Pvl&*<@n1ssKo zU+>v^TGGzb!L0O?PGZsy4bGP{pbK%g?%}$^*?70DPwtvQ;pY2_JPW$t+3&Srz1P4O zRQ~>>^9Q$*659pm+#7o3o0soo@47O(y5HfK-L>-k4780oh#?iD^%ZaLxM75@`wUxL=Rr-AIg%LhJokYTs#-km1B2@UW6Sn|AYJg&p7CAcp);?sWh!(GQG zEI#tTK-*B^J}dN=xC<-87d$R={HEhQ>mc|Lxu!LuJeOK!cozJ&H}Ul|KJX1x#mQXb zJh*KSSBf5ZslTl4j)X@GdS4uAQQdZVW8NIA0}XZjpnCy~`Aw9WlE8<;nbk`cw;ufN z$6sO3zM}b{gQCMc-bTsN4@OILHecVWe!Jwtv*IVa9io;w^&M(0^~&0mZWObtvWc-I zMgNRY&FM7`S)ff3#&V!bDP)eYl^RWu_4bIfm)>OV$`;X{&)aTN1UjG{eZpYfsY@q$ zz}c4R9^)hV+%pA#3{rkBpKkQzi9NWj!u*!m(XOn#PT>eoggeX4`UU5Xw>5btD4r19 zdt-6d{aO#@$?fwS(?I)HAUgzKOglI&3ACxaXu&y-H+=#D$C*{wC;wOe)wIw+ZHnU& zxlKL7_l>kCRBkx??8IEY2^Mem@n3jWEO7sXhGdQ{Xak*4nbWncUXRiafzE7u85U%8 ziYM~qgmZ7V>~w!1%R52h)3K5WiH2{@4c{6R+OPlRU~F4nJE5B$GHCq(J`CQ^KI2De z?E_Kv32J)GFCyYnN?&&gELUl?lAjl~;cxbJiD`2f=H+Oeb_|SSDz#W9+i*sz>4w7L zxcwE!51df&oVXKuZ0eJfS!`bqeC64|&F(l?fK&6tLk9M;FNPY1HqE=6S$`@yU5H_M z!Q?bS2ef={R|5DvrUPb+A>CTP6HIekQWI7l_#m`H(KbY|g86x$s0%w6_%f6~M`W+a zsjX3N-1CL&iX@}_X6`LdZ~Sq7FnQC2ryF(e3q8NiaG!ILKC7n1dfRrB42Rzi4s-hj z%1>0iYd`<)@LfIq)}4aZ8TXvpZY-(TF-t|7AGBMk;6HDQ?%G8iDiJw9Z|zMeU2u-m zta5_H3gITZ!;N-}8H3otC0#-=dl0ucd*1oTLk;$N0ePP6aW)-$e#%^tbbQyMAsT65 z@y*fgq0#kYNk=w%ZM5GY+_dYPsLkbr4V-$JGAW3))v{%defPiqPd$I3l09f5D91sP z{u9t<&7XP#Dc27kVQt9%*4lFPK+uN2^4ilD$Q^CF^YcPU>zc=|`+Nkh>pq7p=kjIR z5E%9N$(aR8>rYHzv6)pQ_r>j_zTtm~DUuuJ|L=np(FwuqpCo+#=oW;ummbV-lc+!O z(tg1?_aN3M6BsY7j3}(z#^WhEA=qq!wY>j*2QJx6LCu2pToy8Ky&*?$>2oBj4OT{L<%;c3!_K4uRd z$UZ#qMLu##DlL-;!5G2;xj7DoPtT&MHrzo!=zTu2QFo|-np zw3_{JsmyYb^|Ki>W165#fgb;5T;bo+sKl_VLLmBhbE6x>wVxaKbXe~fvOI21vn_d} zu>7{btD1&6Y{A7A@1zzZNiiM+b|T|4pp$og_WcTKGgxKsrmAme`AJ#gMzN1ZFJt>zeSiZ^^la z17GI*-8lB(O-mKe(|fhgC49sk9_2p!sKWDe=5MQpTQ?;f%;yX5dMk6~;{h>;^nV`> zUG#6AWSI3=;mS{jm+dQmGRj_kUcvm)9MTWWv0w4IarNWE|7IyOAAMwgF6m$_z2PSB zgt`mQifn5=99dpfEcnf-!uEOw=roWU2UlA1y!dU$B>&R*K$`u9vj>rabSA4X``IR$ z4|eAnZs*8tO|@;_uuJOj%$F;qpE%CtUu}0nM=ImnVKIwyB@fIWZI~~fu6UY3wP)jd zVI>v*BH6^lC5Rst5TZUpHbkG70xF2Blr;zZ31CY5sz$3G}(m+WP> zy!P{6k1!9{&51lGay!|BryHw$R5Q@|6M6Q-_vu>9?KVlm@89S1@F-Mr&aY2+3|cPN zf1CBw8vY}O4OSWoJiC~WG@qTy7=4_1iQsIDoNLTGot=8>Zt!qq{AXVyJn6!|zK7}` zJgk#zkNC)C=(De3X5!`s&Cu9*@cq43{Gm=Df&Iz3!@nQ+ah#d6=lw;VV+SW#vtS?c z3oC!k);61`W3T*zbL>xCblBP~S5IU37{pe>@H(d9h+_`uP9 z-s_EopBXe*$+K~V@hI?2nk*QWRgPiMXNmi)G9=(wCq?AD6hw|QT@NaTo~w)OL0 z|F*fW&l{}Kot$<6G~LE*?lI4K-*e{shI=8-7u$yNm z^NR$f4ML20YB5EbT8DQ&(fTk?@bz11iKLdvf(xh2II|(;Wk}o2^lFK3b0f|dyw`j3 zC?-JN#Z$6K`uCx$msg6d0)+t)wv>*!!G@3J}Jt5EqRHDUoDx5vAAO6JYU zCP!?ZK(2|p#Qv(~z?BBGHHZ7|9TjKWFjH`b)R%MYpA7e~tIbPexZ5$WY}X`3-EBf^ zQm18FGiT(VSn_KzOS9A!&dP63^q5y{ZnAsLc$w!_kHY<{ji52`D3s(@Yp^+3%`tCP z`&;J9T}fOi@7K)WYhI<2VrG5Sa@NCdpR0Ku*eWD=+Z!~1&U>64JZVLL-L{m9PoHI* zZGJ0nF#O%1ZgVoiaoT3nHO+ULKRtO>+-7NewIF*!|1;KHFZcU1_$IOIUia$fNoOdv zNSNEVE%UwPEhfcdDXE-BIoT_Z6tgpDve}CG8`jB~&R9@s!^{!(GX2UT*RG^Z-3ihH^WHwECT#GXoz5 zwx3aJw31XP40z5m{m9W#GR<>%9^J^eagYCokWP)Pz=XORsVy6N zUugdpSgf%i5_FQ<1gi@<94msElG>U3yN_MxOjKZOu##V^$uG$lGvm+$F%HRAt+jjy zvY1vhGffgOuRXMZZ-=JXmOorOn;9oDmpV8YD=3)RRWhzMVGCkh@wssEKdp%9uYGkN zVigq5P2T=p!q49Q%nYS`7k1r?hqmpMnSFNyA4kqL=DGeS_FgVk$TkJd{zXMRe|*gN zL|+82=834X34inoPkh|FfR7`CQ!InO<5_h54$%d?FHaaNEjZWNcuKNuhWt*RYtn~6 zJ9kdJ4OunQ;k|kDR`}{aG3t3;)G~`*hLkbdu&557`8t<~+Y&2HjdY~Gy z!B#<`bU|vk=Hz8fTNA8{#AjPyyn6QJ=`@C1v-Xvsr9!XS@BVG{98CiSGNrD0{rSW3Tk}kKb^INlehN9hZ z!8?qMx(AzbUD)4(7*6jR4m|m<;`EM*IoHK}9@|b0@hgms<$7NfmK)!z=D!)fQia3v zkmMCk#+~YH{WVWQJa#g_Zc!+Am|#BrF<0^hIe`m8Yx*}$INP#7xuP)Ep(Bq?aqBK? zePf0Dj7~2k;wJoD(EDQf|9a+fgM_*KGxjd<MGn?0LW_%s-V3s7~*^-7U3B~L_b3RXDZI<{@AQbTY zvDZVv4MDQeCrk``?$?#e9ee`XS1xMDVksmxB|!QB4y z-|shkZJZV}w|yOZOR1fMkb>D7VW!Ot^KI5NGX_OJ3_5v1kg0vOUh}3ew4MeRMXwVmX=au4?G>)ya4Mi{qakZ4!fAY_Y8DeWNK))U0JZ3m#W& zd|ChRlj7m!YD zEpO&Jf-kF7d=d6#jbH7KjX$iE;nOjx8_vu+z|%5!!q(+#{SS|Ae$TVPkIhH!+E0d$ zjyWZjDgX7N*&{deS}}6RZ?cry&~>oNHcRG-l=HMHhcYJoJDILHTQG6^+{Z?r|1f&Y zIFzQF@G1dz4?XDoPBBnJPHKWokvpr5Uw4_on!QGI7jAgX)^_%U^hMBZRYok3Gs8h0 z<&QEoCl?g5bj2zd#$-7dD=YjAN|$GQa_;z?xgASqf)3Yv&%`)4k98Br&k&t}bmo#2 zeUF;7gK=!2>j0*|pMOL_U{7&FXTW~fFeID=+okH2fOlIKZj(Eh9j zs#oWn6=Hhbrn{1nSkw9{wA=$Q1;qRhM9~>hpiM1>K{&OKU<}sf7QyQ z-l$o212f|#?>9m^6QVBI2|P(I=TznWk{YS+vQr|#{q3ul5k@UK?0k1tb{MhDFf)8` zn?Gq5>mBW{OLW(l<8bna7 z`}bP$g*t)E2Ssac22VR=t++sPqSb@8lDf8V9{0xY$tzeLrpYy1$-Iz0FX;Z+$l$>w z_EMj^J??v%zDr+HlmI94R~ZSrX9!dlTWylMaK__uO2BR>j_eNytmIxyT5x&&rpt=$ zmmB;J@8aB}!E=Q(QBmZ?gW!z~vYHp(up4@>OURlww{ebNfaJ{M3hTReba4Mwaw_=^ zTD^Mqxq@Ahx=Q*zKeoWX=@#jh8%jMAyjM@KR@sr}`QVY*ddYq3(~?h=++;0RTJw0~ z0luAaadSI-Z5ITCPMBolVtjGQ@dn$M$EFif4W{W%5Z?GfcQaEY_w5|Ms4UiEwm19w zRqsyND{r`T0+(1gXzqX88?G%E=P=$n#~ka?Q75U`@&B25+DgXPH4SH&<`%KeVq9nv zQ+CzC?b@9vg~jtu7%LfUR_E|dp0Ov*uq$+TmAT;`8&=DUop*a$53aqzzue~6%ZLT% z*fWkXFJlDXon7q+I*Ups!`@>;vNiKw#*AewX3j>Xl1q%6@@I;ksNDb_@+v6@U13w| zlyLmxqSN<(R!q~1JG%W0*PE~xX`g>hs^yt~E;q$vyKl0?yP6}?mBv4Oopth?N*xmV zocGDfUg2!)Y_?L~VWqgC4}3V`bH};-0mqx?Ffh)oX8A>(Bb##PNPsS(ZcAJtxGEtcnt$bqkGh+gULM`XS=(K%d82p1 z;<8TYm1u9?g=Rcw-p2U%X!C8J6Ppz_^uE}zSK&yT{fiRq2~jup${8`hi^ZWXf7?-dwNegFB zQdWQb?Ih2C+hWOkHjO36Tv8Mk|JlfUfpLAUFla>D_r;AX%JO@;XMJ?IKZ9?kd%v`Mn}LS*YQu<#)rK`MRvzT&&%UnkGtk?6-l{~_S#KF6Id1pd z3y?atV5!Ra56={yxENos6A02_k=+eCj&)n~Imc(<)5{D@7x2CoRNToUZ?`YC;+xFI zda*4}yiSW0bue|Dbzo+AU&C;AUmd&9wOLx9Ch&1yu?u+aa!TS7+kx$8xR%IlyD78x za^u;TkSi05^PSV4-+#hz`B-TPXsJ`tly>iFRpK+7`Sa!F#O( z+Z!w2xx4Nhz1YCGSJ)?g-9P>NH-n8hXzcp%m&QmQ> z)ZFv{Ts3?z$yjQaFtN+cIL!E} zr6H!lU+$Wx&)!SuA4;T$W@&c#=L*tEI(uUo8hIB9|K3HxhD z7+$GEZ#eL4T6yyvL#9hbU5gC=?@zKz3YlM3EU=a}dCe$v_^RTT)+s zyS=fM=hUkSTy^&&FMK?FhUaC34%69=Gd4Vto7iSQ{jm9T>VY!Lhi&Q;CZ=r9&}O@_ zhV_ic4Ig&J{R`&zeNBmyX3hvp{;ulrW9O?xdw;3fHW?>H&)7wzvuqK0&3IUlEkd0| z?f*C1MTa==@THGQ*+EOAbN)52WGr=ZP)~03Kl*Fi zTt<`Mjw?Ph8u7>Wa$UD=+Y;h&*ltI*vggU>k_S8X4Y4_2m zhy9N-&7I(ycdPmBTZeZM4OYq)x}UVEAHfpU`$_T8iRo#!|1EJpIHIJk3umFHGFCp!dZIKFeq<1&yL#F6{sNA|&V2iQf(_Q~ozu z%NuzAp5DM_`16FHGH8^C*|F%w_Ib_Ik~=xw8{bZz6q2&zYSq+(Np>j>9P!7UKebvh z=P+Akbc(J^jZmeu8U3+Hs>h82AGOL z=Mc`)jQuR(;Qs#6XJ*hj8Ehu68DEts-2dNb_n9%6Tllyc_or7!Y&RGga;vg=Fk7^w2u?t@|?N$vE`?Wdv-jTzt8eu!OMfv70(~Pe7!p%->X}z`Dnsi zfg2|yR<H zkBzhKKab|G3FrR2{oZl8$)Va3bQ1S(2U+fzJXX*+#e#F~**Ym#BqOMnO?Oh>}I}lbHS3sjX7eV zbLltA9C3$Ur`0em|KPV~1A{k73sf0O?Ru2vNR}`w@_yD?U$voBVdJSTm$v!q<&7Gy z8#VXrD-{IQ~J{C*Gb_ zD)QfXhwOsSM`L%0PCKrMa?SeIuQ?!Fj!?xzY)CNVLIQTzPr8KPNZ>! zIa{ST^fo5uzKdadcXEQ?h3j|xc@7>ssqrqdx=gP*SnCOcQ~>+prE*3Btha@kf_QF~ zfKJmo!X|s28+1kZIzNtG?T&N%D||hUbHIX@0Ti@i*L0E(T<2sgwJ2aU$>8VMB?CS! zBd4Q9=VJM*Lwf|}mZZf?rs$^~_>|2vg(2X0v&7#G(N_|`S2ujCIM8>)^?H8|PrlWM z7S|`W3Irm$8g_%TJlv?1_(-^UEo{sDBcDDY46O z`{HIR#S^mBj@w^_Bmg+)g&n%{#3e_2ein>Y^HEAkN%4vvDS8ZJ48Xw zsZN}Isb9zX%z@%7T?cPk^fUgPwQjHPWQi@)|FLH8lsd~ZjlD1->)X7!M--T*vcF|F zhc+X)uA?e}2 zpAk=w?obJ|(lcNNH5}zZh0TS-Qd{I%t}rU9A1l|jJqDV1`Qq$%^w$BS2WxJ)|rgYVJ59}84G~J!_?$dwsCvIPUwt>#HWC(Q(WV^uo@|Trwg5m|X zlB8(~ji6KPbLQ^tXS~MPIJ0y0XU0kFCl}tY;=9FvX{!Idm#!1eu`@f@&tz-f#`nZU zb%MkTkGL7tCAohknD%KIiM(EBlv5w=8l=+j<%`_>vk#WeII-cwF`2gVT>{oEdhv-C zay5)c*R-+=d;;HYrp@y4HlMSf(dtcGkGupejgW9ZloxovT&^f(_vD4fF}L@2R~JYr zdM6n{wjcOApU}O(;WWp@UPjRNg9lNYjykw*D8821_E_BC=!mG}G#T^Mt%fJGo!?z_ zd{?ul{>!9;>#e&T1Ne&Wd_DKIUE<87N~85Kp{ILa{lrNR>*&@Efm@-KcZ zm6;IgOz-2yMXL|BkL0%|G9GCl4xozmT(Z~y{6V?lwiF~{N};k{Em7r3br=O zbTHpK&4_+M`-vVewm;i%CBJS-0QDD}b&onh8dAcW)~%g$0D1|IlaETHm5A~5^)7*2 zuTvUW9L0qe>0fU8pr|}?LGVV0SD;IX6XptCSXO+YaJRz8J+l^rS6?ij{@w6^mEwZl z7Ydb4)eb3HdnC@x?`Gc46|bs!u`$hN!uRS0=W7n|G&nT`I=x_C!dZq{4|iPqDy_l4Q|7Jl7K6V(EA*Nt z+_7zo=eowj^=`stLC6Bh!+!gjb_!3o$=Eq<3j30mJ=vUMo9x%;w9jc-@;I~O>TgiP z(BZeEk&$U3oBWHklAKA>jdS_Cm!!0D}Qb443;BMxY& zhyU%p0}Q*ESyJp)EN;BV$=G?&Z2A4Y>Rj(*Z0flsUrrLa#?bw?x9v_Z)2lfRXAY_D zf9#^}94GMT0m}s*4iDW7u_xD_AC-vP!!}3Z(T{(f53g>2{^8uw+21EjE^uLKJ&?4Z zkKIFgO>vVR|EnbpekYpFPH0GT-zJ-ve&PCoed`&w1j?4Z(Obv+g2#p7gWDH{6IV$yC8dgf$!57(x)f(-#e9LEWr35NOo@7ZUw?Vf*)^~O)c>W$cS zA%+!B`N#XOdn86wNM4%BveB{a{$Gy0FDA!NWmK#0`_3H}e<073J=dkZRL)_#fYN(r z$9wM?jaZiP9dQfi7CKy7skrVYf8>LI{5N1n#q2IVWy;ptnZyG<6i2i6;gr7#mMN8A z{wgSJuiH^P_aV~9E@p>iie#9^?A{0 zX?eZm0FUjgQkq=lx0;`}OWt{J%c6hSXtw=C$ElIcpizbwQ?!%%9;%j}=dd{Yj&WVV z%Aagy>}x(VJ^~*RTXf^$B=) z{{d^8OEvR`i3(=Sf(w+aryVTPO0iS`9VL9M34F+aYMMUBrr>+`j@(%c-iP(P*-Gxn z56&`gt2Zn<7nT*@I95EPZo-`}d(9wjoE3*$CzCVkxGTCa)W5ytkTjEWdnVGEG#FucC1U~e9ko$5| zy@UtTf~O%HcH0+}+BvW_U1`jCk{Z6i54=pU-!K z#(e4e#rrJ}?Jwl8ulOvuL&E6o^!&NU9xQ07(iUIwdE%cn?CZ8Wa21tkc<5BR@gM$g zaAl$omA;*qr!vZ#d88YqjYML>Xi+ch|hpD^h=a@US)Lc$))t4Da}FmNAsvepS{s zr^TkN`hf4IIh&su+^J-kQ&rzupt|C7V$jr+39p%UUS4va^OB@zW$C1Y>l&nME-Jjp z>)+6M`r#}G_cu)zCyswSq~bW2f5x76SIY>{vH6AI4x;6pf|JVSb`G!9*EZi-%Mg{- znyb%|!NyYZMej^b#B-)2?BErx)rBV?TWP+2lzSqxHw8K3f8VOrqV(H5(6xL^IY zr;*UMdgf)ETmCa|W0Wm9B?_8_%W|x8IR3s#PuXRg%#n889jlqe=H6cV&KPBNWcoG- zv&U?qA;zFJ9(!u9`>~ZKxI533|N4(R;yH85`&gAq(AJ~f36EC4-bB-_YpG6w z?t0J$%76>4v677?+NA;I2IE(uw-rwW9c=DY1y`E>C+?q4uof)MR{&kp z&~iA>v%TDI!ST0EUk>%%Vcj^7eVURt@eQ1H7M?;vtv$(T~ zWBSqcIVlXKUVL#o4i^;skNp50u3mJ{fh}fQXF}YnYVKX9KuC&(Ttvzc(0`Bh7U*+O&GoP-L!hX)e&ZD9AE$EZ;+q{F{SqE=FD&1A+&%(Bmn76Sb*#8=~jq8sJ-*|Z;$n8xl zIS#Y>!{6!@ zz}qKpu$5lOeGa;V=*wRvh2r=7s*X5t9=Q6GVJ7D!=Y10dRM>9uGui#*I(aF4f~_yl zhI6bQT%hj2gu88e{{<_ucQjc&ipfA5!YO3QOW;?16k_Cch^KZv=<>Z+H3`PTYWITq zXJ#_IW!+hvV%6;E$Q1EY#t^hj&p(1eto`Ht*!|q!d0+g9y}{b7V8&dM$>+iB zAp;(owR*{=!XL&gvf|yn!w$Nj6KK9wfLfw&c5Zm8AG*f*zP{6mfG2$HIfpGh_=}D+ zr@7tyC;5T*#e&Bb6a5c4ZDTL7e7MBPqtzKS;Z%3QPT&Sx*#))|n9~bCDtt(CiUDn9 zI(d(;ExU1rvBQGDit{BEY$NZTP2ySbxKj7DLbY+iT>c5w4mpXusjHSU2OMvXIV@IU zlMt}s2hTOWT>$~AGMidBuE1~HzOq`nTVea=W<70|(g25w=co4ay!g%}Z&4tbqn9Di z!F*U%M7_yMe!*Xbc}52WQyoLu8u?CaTE+h{Tw>i%Rim8xqK1V#7f)p@E9cnC#9ihj z_DP3*nw zDF2I%CHKx`mtzsK&Ub?oo;&NaOe%tP@0{? zF4$QpRq8B}XD|Jpa5E27ys~xhf`hu@*d2=iF4nzvZROwvRGtm2x3`NB$rE!F6XR z!^ZdZ4QEzqaCtNyO^a{lscg2A2i;C4uuR1A!`tVe_48Q{;zCV*k45KJa^BmydQ~W8M}RBI3y3WmHKTs8NYsJtLd5v@0lFK8Fo9fl<0GSW`cjp90A=BdM@JRhZhg5 zex#Lv1{q{Gq=v^`WaaTY@N9!hfu|ye^6mFIc}EPECbKtZPvB#&I?lX|&xUzZ#bNEX z+?v&r({4MJ9dv)ktY)WvVr{2_;RDxJo+k`B)pi%YSMEp;HE!s;$$B=e;SIw_M-$L` zbiOjDu)q#!=A0ll$RO)Z(fe;-C|G`pKJS=z$J@0>C#pJ%QC$5_QiOn2|H9OBE^J3N zPPnB9q(8~5=W3p{TKn*1aqA8)DbRMVY?e}+4nv+Y&xM<2$S_;Z70B5>`|&36C1Ou+ z#IoID0Jn>7tmarL;%F@O!mRPioG%R`cIUpA3%#9iQtz|Goh=IPuOUZOyW3TXPq(Qk zwklwgH+$W<=RR}oGv;RoGk#2AoqWJp;RGLBsa_MG9y5324X0TvcwHt)_}ISLRvfXM zY4-6%_cxEYr)2XhNIPy7xwAp*up0mDj|`a{D?F1nJo}Q&Ft=jsx8vSyGj}kF6wlLP zGMn_|ti*-m&)(a&%@JCp(fxOdfYYZJ(gonP1(uoZHCoq}S|2zi zxGQ5{uB^)W_4BIQ8$}piRUEj|3_hp8M=a&9I?$E=tr1=-M)y+7Wx+?`ZcXSQVH z&irp?ZLe<6mS8jXSmBV<#CkW4uULD<=SCZArdt_&lbE|%XEjXE%6y$-wBWvM)0^-c zJsr%4Gux~dv^+O> zD^tlkoImBv=Q5UwbFBHySoCG**3*)Qex)_s-T(DOZozZrBbxEsdmVL7aO?2BD#&3i zGjfm#c+TQtzneGnjyL0UiN+%ipAP*$m&nT=u)L-BpoA;mm7ffyN^hP!OD+D)Z1CED z!mJ~_6NE1v*uFH`ur};$O`B-7nW4*zP@^0H?_`bb%-cR4^kddDzjP@vqCSKDu({4J z==d%;k;Un+^)ittP6H9E>-D*1Xd@ z600{qKwJv69B6@RSkuV~A8c-QSW55&CCBpb6!+0QICH_?{fAv7wHA~&f?`$5;d{#h z>4utejyFtB7c|3<$Q=G%VO}6Mt+!Dr;9AKn(B>m^myn5_2i4g&g@gR{mXUEKr(f$E z&W(?%4mR9*IKw30^bW_9KK5NZH=JYl0BullnsD{OBzD>D+*Tj8#H~J9M2600tgIAU zQ_N_@4X$C&s;cnM{_1e=J!o>km_JhH%Fi7J>_ryMp-*Gh6gKV?XPK=O@O<%>dgkUO zd!!D}+uGrG@!sT)BGCQtFIh{y%GU2@de@R*eERVIzQ(5?55MM#`?QefwB#nkD-Bl4 zr&~8mPB32p-ADMFhhJhzT=wC!Eu|h@VF`I=$FDzhC=*%nneo#ac=g&=K(4Bv)_@||7*y3_4hqQnHYnvVY z9a|jTPD$sPy~v1ra`q)?1%#Q)V!@zy4b##d7ICcj%y`?lY0dHrn)4rOiGCJ=ook`_ zy}5+N+Wc)2XjA;--5mnYOm1*SD(w2e|18k|dztgJ)tWnRJ^11){9f{htipoebp>-< zT5EXT|74cs;W=RKaDsCY|LOOJU;aHxzVM|h{leCdX%TOECC^^tJmFx-x5b@Bh2eEa z!w&@;!K!kOUqN~)TieM$BPwtWuTX6Q}XJ*AziwtI~oXV?LMcE~L{>%-Csm^`9%QAfCF&lfyBK0*3;;#~d-N-1WW9xj-D{-XI@;|Giz_R7D1 zuJkU2q0}v_Ss{1Zv(jKmha!W@3;+0M6z2Ome3R;kSdn;x;Z;S$6Gw^2dwPcAYqnX5 zZo0!$5+&xrQ1WZ)Jh_ye(knhQg0@10tU2zneSWi*7HB_N^E-yb1x!1tg>Bxm+ce!3 zJ8Tm0oY_Q~Y0`t_&1pZX(uAAUF1=v`Ww45U=^wS)YQi6IwJ3LNdvWBhx@3{G;^{}< zYakw9<(OqAQFq@jVI8x*hPO8a_D;n#?^7-n+iQ zkG<$PbFDpSO}wrAi{;6UX|@+Yha)TK?`8Tp(OOY>_x7gm%?huXOYQi=?zG%tW_s1K z#kZyBO^D@9GUsiOl;>x@&)FW`? z42RFdx2+RS-^sIc-1~s9M4e*|vtjl(rb$Xtdml4i=9$IFxN)uIJ7bjyRl|sL_xR1H zdwpU{{e7M{H}W)qPV7krP0RJP-JQg@o0+9VM*qhl?K|H}(0 zYyxZ>6SERdZ%_EM$9g5t2IUISSyFuuRj>ND28i{4+!cx+~|~wl(J&?h7-$T9PyG?!ga_XWKEqspE&# zVY{Ebuw(NLJ`uF3-~YYQj;s2K52m-B`FB+>=EMaV{+sHI^UoGsaOG6`QY&xZ8Q^|2 z?|doSIaP1TAFfLzxbi%WGG02dIXTF33AmYYlw1<+>G%G3>-TLH_0$VJ>|JUXBsD+Z zmUI$!4rp<7f0txBXX+noNsmIE6`vV{>L*HWvFosMf1*@wcW+;VjLpH*2hKC>x+xQ_ z&UAAxXdA;j_kF6ek+y3-GYT<-hK6R?yvc|Yh<|#Fw@tTL!I<~!Z$NY25gOFtR3cKqYnCF149 zaz}Ay#Qn1hddC@F&PkZeUKSK*=XB-2`aH+BRXR%qnBOkoW8ZZ*VdJN`9Us;`pRnb* zT4!yhj#(vSlhn<)C+FA~sxa+Vm94!gy2km^_IFZ;Keum}Sf}*%yMvkVm7gzScW~*j z+-m4MYZuVY9BFfPpTL=;H(KPRf{$*v!)YkZ^eW?kNt2a)cD z4=$gzMLJH>gJFRmyN6}QNzoks6L}B*@h>lWkml#s;<(_P`vH~~>uZ+IRr?-9^2&Ix zho6y_^UA?Yx%+V6jn=t&tu=W~woOr!OnP+{jqp{n22^R^4-=zt%>=UdVP&dx!i!!HlGGwe2Td}#}jeWpzrYoH% zL>qcug~%PgqrnlxJp1X4KZ%Cd9vs~EoVo1bg1OC-%}b{WI#-G+{k>kY)L_dLN54xC zt;(i3N>rFLuaIfY&9{xSZ*2pb0fnH3&F1v0Rhh+*Ctyw zvlKjIzVlPSB}dME-dTrt6$;UfzPu}vnO?OV@Y~O{k{!AUXFFq_$9$GE>r(R--Zhn=F z_wo<0t+VzQJA6+6vP1{#q1}8&DK5@z)p>WTTNmy_q(+>`lGI?a z?w@-o>(I{PZb^sfoQG7Vx9Ozp_|11|2HVDij}-DeEDBuDMzaN|r!?}Uq-DmMrF8PW zh~uA82U<7=I{MjK_rT-ojk&4pXR9J^s3yfOYJDSkAxP)OIuFnVRQyTVUJJ$MwLB?g zHT;y?d?HI@?|r##^O>jbeX%@Qa>)WYPM+5(4PTn|R9x=yGYK(&bW~4jys?4zzjtPV%Bo`CekU?3ZKOdulN z=mE=y)JRKp#nXYyW_(UqVY>HIgJYg6TXX(IW9Oy-A?9^AdDw&)SA2fBF!)HooM(p` zYJ%BTd_JhIdGx?>g`)=HT$e6h`1CDt$JT1|3V)6hQW5DX_vW1DQD5gEH4k(rsU;`s zAz^P?*0lFd(2N8H5c{iw16HzbFIV!oX-zoAu!L>dyhg4Ek6ElAWQI@Zl7o!bT=`j` z-EiaQ8>aoc!}?InQf}fbSXy zrX?wsL(ZN{E&iOv2HEs0IAJamQxgxNiec-X3?CDc-4L5BU5V4_+Vr7l)j_oaRa_T5#_8#$`5bZ<@S;w~Yn<~$;3um7#@O{3a_xb+Fk zlxEamWqQf%9FKyjFyGx21-1vXo;JK}Ee)#bwvsTb`ngzQC0|S#>+GKlo()!F3woa$ zxGLCHsk6+Nx>2NaVXlIKu|s+Dfg2mnajpoSbo{~D0++es@8oLpugna(c>TaU4uR%0 z`vTderyWv1d=dUI#puD3E~XL#=AEBEzT|vTqT=(wR{*qJ*O5v1zjphrPK#>cOOEDY*Oeu@7ARMA?qzP7kf>CX#G_Et z^Ux;d<#*?NNs%)Gzvntk=WBZR_du%H8s|;l9!IggW1kS24Keh^@sEcv21%9s<0dCzp}$eo_`5xUYYdE>P6^G`8Y zRf#VF4JBM$uvcLL>-9(e8{VI;<=gvv*%Aeg9a}2x4qug5i0ybMaW1*S+;;wH1}hdl z_nw)I*Rto#5I znb+wK?^`^sGG149{_J^rqSA*T%_M!rmYuv?t}~ZBRM-@~+d0qp&0fQ~j?Qs&7rwb= z*=FVE*VZpx^>8lFgs6by&Q9!xU)%0*GM@Ba!Z4lR;r4+Ae9Y_oI3Szm-+0jM1_J1u0tR9B%NMQ|-N>^} zcVLEG4e@hYNy^iXT7?O@{h*;AUT{x(^>I~xYgz6kVp}w2%cR0AK5Ws6nJaJud?3xA z(DH}I@(Pv`seEz(K?&c#7 zbGZcm3VR%Q$Hds#_~pQrLsuHEG@kkM{g*bg2hTFQl52%*7uFo#+&y8bbkMJktruIY zs!KcW-?k&)&G-D!(Zm*o1Y3pjaQPI2ckH}sig}jle}B$@c+x(wEmT-R`Q(Dh z>o!CRoZ*iVTHb%R6JmTsJLK5@hIfA(X13k==&+3uRGzDTUvCJy-RHN%I>zYcLkEIG zx86%$_judX_L#r~ZkhFQc8n!2m0s1bu1IEl<-+3ID&u@dek0f6%?hTi+6t#lCR*#C z;PRK5b-v-wM~CUF{af!{T*|jIL*NSML9tc4*Evmh%6uHb)#@r&#w3;zZ1w9{$%H$9 zHPt2fo-9}wm$CaxqoZ)uAH59lIqy#vR~DX(zrS_f!kfAR*^eCF&H3}|&pgn|J@8Q- zpwqJ04jplH|J3x3m9f-ng1!pNO6IrhjJXc%8y%%DOte<4ZaBT!Byyf%%x>;I>28vx z``EX*y#8O^;cF=>#}nLm{NJx4hi$P)#416Ls zFy%mohP0NMG%=RFRDkw-To?FpL60a;m^mx$!0neFBAO93wV;2<=c5Z?6 z%QG7;@D}A5f=)G%O8j1X;9CRosXDrAcRk%Nu){@Q6A#DE#|*nt1S=j?oMp_rYghcXbC}B?puVU? zD@8ap@JJj_u7YW;w!&$>U7P18nO^gKtlB)gO}_c=r@bzf!dEsjlq#v|HO!eJ_*TAY zA^(!Jm&Z&KKK^Mj+0@Kmt8BH)aRd1J%5^jOZ}gm${$N+-!pilkX2mk6X&xQN(hPF8 zHRrtQ`P`G{p*Qcq0tLCov>kUjQZEK!6v8(tc&J{@EKVT)cV5VS7;f*!yYd$xgy{xcT zp>XX76SgnC&wem@`i4raHhFW%5j69dcI^$0s6lrvht6X;)7>xm zp{e!ZSDppl9FAS**4{YHu#21J$i7W4HJA;{8w>;(9p>`C)Lh21KzO~M`PzgF-VJ9` z_V4H3`86gWQbMOJ^PnW#VxMAz-REnhn78?HWUwt+&wokdc-bY>PJI85 zVI^~^&II#m%|Bku6{yK_m@9B$uHtf`&j*ixXgb4E>U3cHa%RiF-eJZI%AFQncX+43 zq`UW!SjmRH@{rYTCEivZe=i9KOTrH8e>LT5uH=SNCx;}3ovH_N*FEByuv#Sn)Hq>i zc*oW#*?q?_k)g~<&%ck^n>Dq}P@&vH?Vbf^Ip?dn3LNZ7!OTXB#cpuUoY7M?U-(Uk zPJlW~nUPq=;a}6m`wtv{)#Sr^wx=NjGz}{Are#g+^7D&YM8M}b#7=N2Ph?=u@aJF_ zV|Z2bKzP2H^d_DC>4&V??sH|ZFVTNt;vBe7v&}Amokiuxho{kOm4#>S+AlcAz9RY3 zuGdD)nhdw!KHKr7`O2ZbyGOT)Kl!kWmnWZPri7kcS;~)3RmP`c6*j=uv9Ma@iKoP$ zIpYG__Ik~;Qu#|~;?>us5BiSxwzo{@Zm^P9D4y`W9yH=NQ*gqMt!twtK;dIhf5=L= zCCxTr_SwYge2dzJ-$=wshYGW$-eB9l__f5F#|pM-hQ*Sc=5UlT{t?UuWJnJTCE(CNyuw>-?O)NP^Mc@l2 zex^|kN33|?Eyz=wIT>Ey$GT~nnRqyi5;`wK>waH3s z0pCfL7oW5)yy4iDG(oC!l_k$iwlE&aHJ^BHSjj2a-Z)a(uanZT!TptwSEu2c9e=wY zc50>I-NXvM z+7)!a-<|e5A05h!LA}6f47Xzq7Ug^9aB zTX1g*Jc$&%aaZ1;+5uFNB+aj8j^OyaB6fm;$Jv!UC;lq?SxXnRF|4@ExQm-5(((11 zqdeZu0-F^;wI}b3d;9{tyMBXD;T3BHox*GXX4)4Q`3F4g0{U@`I^t6wKa6sm+y66I zS@PRDmbWWSlEGVLU~N0$gHL%L)e9QSD{MzO;{CzRiPKEjo>)6N%;kH+&FT0Ja#r4h z*98jgyemF8-uvjlZ~euO9dtpVly2%9>)3=x3#uI*W?yw&9)Ix5rZ+n+=O6U8?oPaY zHIwJTxf52wY!`yG+sYoO#rS$Kb6w$N%)F3Xar(g$HcJKBC2VSbr#tdqG|kzy`HSk4 zON$Tx?lTm*^@=&a@oLJAa=9HFU+xt=d^++#V2ELhw!_?h)4vlIJ6wM|^TY-fStH;2 z7t9+R@9+nvt3NmpuwgaNI?ZhsY-jRb<)*JNUU}rzQvdVw4G&n!?fApJ z9F5q51YciskP2RKlOKGk?-@G=%k7p|6(x^G<&-y`xv_uF!-LaOdHD8jmPpA}2woH) zzc*rJcIdB^OXjc)+-^Bb_MZi2HJfo4J*s{Ol>yqO7z~CBfT&? zq5iD8mSuyL(gHt@O-Y~)oy-^fkDuDE%TR82N#~NpG?u)E^K}bmHzS=&XT%*TW5Ud2 zEWd@nrFn8=7Q>aF4R0A6b&n?L&)_tZH~F2|o*p8+gyVMZ^A~;K3}NtQS_$Y@x5JFP zzB4bAFH`5(cKh7Lw+*^0l~T;#Oe=Y^Gz_}*_OHQ572PAtVxi;WGN7Z-zi_FQiCg^G zWFcMj=E=lm6>Yz}I=nATd%4PB#hMnG{H$fI5(gMdo%~|0&oa#3+Ax!K_Dh8)`Cl$? zbePMZV!NQ)-lVyp+#zAJ;)%_23(j%8nRMuJtg%Fwuk3-j{1bMz>iZj4tZ#i2>Ktd+ z`tF=``!wSjMt_^i_2l-n+RM~giYY`h-_MxyulGa>zL-rNlts!@hBa1^lyioy)1Xi zv_q^Xl?M!WpDJtPG8^)Kx`MWc6z6K z<1}cy$nnxZ#WQxGK>@+N3WiVo+W*cA+Oe7GnZs%47eA!eJZ1<&Y1aO7tU9mPBBLuK zJ^v8HtCl-8zxp3un3u`3V7HS)g?hoC9jo~sv3aDkJTh5Uoc>Tf2C_h+Rt?l+$xpZl=e>LQOujrUH|LUH$$7My19;iLP16i)^ZtrES-&3iVBHO z&c0soSK&|8b;(b+6@P0y>Svrj!DF+5hllgG>IN%CgT-+%J5M!0#`~(CD_@cc>V)m> zv;{>F?+WFndz_3b8FdeK&1CglW4bJkCw0zy3As1+4DTBb-08me(Sc7W&(M$!e2Kz@ z^9GFGjqeyNpKhL$xc`<2+fpTNHbM0Z$D9&D$8!r$X1jO4{+z;!jvaG2&7_$waYxT; z&7UdiA)B*#=lwH6ZR+al40Xg_CeA2jDpc&dsiWI=fR!=fIcU%QGe4BM>)H*%n=a(L zq%UA<(A{Zu*=#Q3m6r{rHV$sheNTM3`dDr^)tqPlv@+Z~-1*zR3{8h?n-5v>Dflix zx&UyA{F3l&>le4qpXO07E|COXzILp5!yT&!8NvmhEt$V8a*R06sKSoiS^DKz#UIx! za_w8xgfG2zpBcHUW>{p1J-NL1vddA9PcI`Bco&>wTXDJY$urxwnbiu?cO8>X9gs{A zNV6!J^RP~KNm0ixo;`B{PK&IzUBJh=CYULD7Hd!kC;W8JcqzvQLDn;UoU zJdu82t8hY0xcIi^ipP!bZp?nK@buNSgcJW*-e|^sZl3-Ccpf1ou`Fi#pgzUUeM;v2~S=-o#M+W zZ)~_yq7)m%Vf_Bb9iu6H$8Y`>e-Jj)W4FNyw@jls_n9s4mFa!ZTdVn5!CRl>Y}Em? z+0Ru%jZ~cV8QCOlzW;D(vpAY@PtxxU%m$^Q)pS){Y5shnBIW9NX>MFTwISz<+8@jf4@mUUqk_n2d^k znS2uHw%^+)BTk&&lHk30!&_FynM|`750>AyJi`wikrOLTdAh;(g|XlHBnJ7N+*50I zN*7jN^7*-%=NP+Uy8z-4*A&p?&Td}WyDJR}uU8yd#TD?JIaYRsGLuj-pE>LK4$$DB zEZ>E_@&>k`otecORx-{kl&yHspwz6$3|WG)O`%N}wo}g9>DGF=L}-)upm^y9-xoiw z9I#Sb;LV;m`?Mqn!-akPPyEN5byfuDZh$wuiJh zK5!R2EdSukz6n-GK&yn)WL`{iybz?bokNUG)AxjjNXBJLj`xwN_BaH!wmKG`l;83GntBeyX6Cg_ z5(TAB39`I3vV2b-FqPUBl-iV(9F+ha8*Ku;!tis!$^CU-rzPH-6B?1sQF2Oj4Kq`4 zLmj(E$qW0oS9vE21#je8x0gD>c55tLY|W(hZzuaDPKHuDhs}!axknD9?>{gtG;ufV zD9jXo=p<6yj2#l|4Vhouhy`_4_Z_n|EO@(MX;@2|t%LMcN2#di{wWgzC#BD*oZqTw zc91=XEo0}@RZ1y4L*HDnV|x-QI74;zpS==gj^7&>=pS!dSy@vpeKERS(sUpiOKa4@9(unzl1a z@0c8Qbb*nstSeW^BvBuSw$4T^2GB+IHGGeh%bgBoiy5uSxp+KVe8p$RpoB%KM-nR8 zBQ#DXgd-nEY$O;tXJY6?Mw82opuFNX;|FhVG|wuwj>M0PqrV-tR%~Gs*e1fgGa0l+ zKF^c=W$mVI@Ou&N_E|JZXtl54OWGZ) zrcHM_kPbRKcrO2iP1-wD=L=l()qc-d>;OH5{b%Jz^TS)ZZFwT+b_D-$kmU_fXTE6+ z>S*xHw%HW5xuCq~9Q&tZ#R2Zjw~w}fR{=feDl@2g8kAV^^`dBv%r=&i{U3UtW=kZn zKdSxPs97(r@m}|b^gEj`++6l^8&a$;ykXyVjy>bCrN`zDixhvUqT`Hzn;gMsA~&67 ziHmztT5EkH_k{GN#Mx&hzd6p~wfoAY*>KQU;l}S+9>@^y6FyF}QU&dVNALNW#Q!?I zWw`sFagy^sP1zE8jtoyRkG%7bGI>tSpdOgfWlw0Q1%D?OAIm~bTgsSn$QXC(sCdt|t~Ur&pvImTesC9cByD&c_N zb|*Vg?vhucFLuOEkh&172wvExr_A#%_P7IQKySOw0s8U~a!f#`DK|CBEy83Zi6H*j}YH@Eq6OKb7$wXX7p>c8gDsXR*v& zrc%Z!=AjMQxw&qyf#nd- z%5eB}=S@d+(Eqv58O~Q62x+jApY}72r)*spkM?iH#nV6;wZu+f_GL%+cZbeYe0#$; zgY$LEfg_G{`CD^3q9?xpd7zv}-$Ng?8MV0dRT10#$t&g_U@ljz_V;?cNg`phn1S`h z_v{C!dR*{7e(37Y2M>QAX}I&yqVA2%9S=}X+ZMF5&cll{`GDnUT1%0{<-))cGfwwqZ`9#qkX_>`Oj_uQ>Y%8CQf3 z>;6hmPf>jT7rcv!UwHe^jPnA)+&9*_Uic8dH zo_?*E84lWmq79xCIn&X!<`=`+z6IJ$D#irr_SD0p`OD|p6Q5k- zTq`%+_$ayHX{VOO)9p^yiZ`s}UGI4&WKVei)4{H-T>ZnEpc`kOgVGhE0$95Ex1?I% z9zoe82fc_Z!p~MvUohP570yqj+Nf zJ=RjE53z0>msnoaG*}4={hZ+U@!uzw9uvl($2T}FAG|o~az^=uqf~+{?}gTu6Tclp z{_jZ$5M_QlyY0IGRMEr5)G=W8*4<7jNkL^i?fFo~YK|Ax6lL-kw7~a<;Om=_Q z5>g?bw1dg!dSs^NlVuk?t&An>{;|cSEX`}bde`c};&R8$vId?3&zZMY>NE~VWzUznbyn#>&Ja z+-sPbCWE%}oos$`A>Wq$E&IpTGKV_NVnY=%NvwunYEbFY8xMCPFqVr zJIj-4yonS3#w@tWA0vH5@&vGoxkcVgBqc1%=2=|`=)fvrrddA|4lu)<;jxte z$-gPzblW9CGXXDtyCxhvoagMm?VVXS%i+JrCzxq(yL~PZybK3AB7d);Q#s$oJ*;{4 zXT~6A`1Z_AHTzVU-&}G8t@wRh=2)~LHEO}qs0G#zE+MgnZCWo%bS5lW-fQW6Evm!l z!piUsH~GcgncHlCKQ}(mcfVEg$fC(?k}E&P@$c=e)J^IE`J}Gs7g%(DRoaZZjFCbtR$by{yF@)?%3dn0*vx2` zC!QhnW}ZNRda8ZFRNghhha8kQd}mEr*}S<$C^Uzm+(L}Oe?~+h-=&`nvwr<}=gStw z9Pykfg&({w;OW;`uGEC;n~DE^nSH!ESB*;8n{3E2$q=GAF(@ zSjo3>^Eb6lu$G@6?~s;Rp*lsyZ1ZRSqJTaSPU(_*|+9jwbD4srO zHaj|;rLlEt>{rQOb6MDYWdrE@ajUEmUxh;3N%6Q(t zy;=LP2|6C7R=lN zNxR?5+%*B6BPBf{-!pxI(u;SeQUrY3-ozf<%95>~%@qT_Cg5D-U9@WgUSFv3xGhk^ z^Zr?~vE&ws7zu~zd_q=b;wf$=sp`&&)e>GS4y0Leu!{bA8L=R;f3Z4WQU>$f8rEIB zvMPz#Bn6%%S2#*v z{8;Lc@Q(Q{bEE8T?%mgwZG|=+VmPAzw!Or}A?Zj?0DGxj*JHs#p52_b+NElTzbUIr zI#fGcxtb#3Q1R-F7u(zOoe9eu@?6>DU4A^g=G;@jUTT-%{;|nQ@$^M2#RYp6c6{q> z;At-P_#*Cb?p!*h7>AR!)e{xCm+(O@H`B zvQ3`n3TxQ`Ri6`TO+Re5?>EeuEq1J7y)e^k-kD#d3SEp>7;n|t-O3(zSGInb0v@df|mll)gFG2E@-yIsO}iT`!Yfg20_ zI6Broo5=XCMd3E%?3W5D`oCUA+yE^vdhpvJVfsSm)2DXq?d6d=H^Et{Er7Y%uVMO_zC5vaFsbJoh>1P_XY!R`Toe*BNR! z^xuc=F)-2BtGrOOw$w=p)C_?%{~XGiezacLR=?~ZFB`1De|`OWL;ovQ*^}1U-}u@l zeU;_Om)n=HqxzSXO-1lM1wX?%%1kpm6--_;-p-k~uva4S=+^7ZDS|H|;=cT7xy#s8 z!=wMgPT)eFK$*(Xg=-agZkSC!JS72izpL#8Yn2;U8qYLzzGpn=;E?9vu;_xMz?tq@ z2d^c;cGNVT;W%W)vw`o(JIQEC4@QGp1KajK z=V=kmW{ZTg`QA+XQorsLk5*B~>`S1#)0C33G)5ma{~wvut6MO-{e)HdsKFvWAVQZUm z?!_A9>N@-XRcV{GP6RX+v3NK4m5&JuOb7Bj)k~i-&%U_e_GSLLmIoPb9pIa+4oUqR z#EWdc9#y}`vxMnF4#%42q9y!AExM3~|E?cWZQkYjh7~uH?AfHt#5q<7Gg;3okG|~0 zw$I9wEkK>+&9!UgDwdKvAAfv$Pj|+atT4}5EEV7X|mktVv5r*+vho(<2mR(uwG z#uJ&uxl5QOP2h#dn&aCgGq}E;y?5-v6Rwl)ZEfp#c3G`hd**aFpFshGbi8T#{{z-C z3hci73wYkGD`L}b6Zz=Pv%pp%`?ccYGaFPR9-M2pc+^vVW8!Xwvl``13O|LwC)#jS z)Vz<2EuM1w!bN8GGHH)#t~0%=X|Oo8?7+c=m&GOa zIh!x@+EvTEn(=I%z~(1hvAj>NXurA0_Ikz~J?C2ze}C~F7PUU|k0}6jd3M9h50|HK z)`@exNYQEI*5zTp<|K9b2kd}+P+#Ru)7%N68;scN_&pxTT&R_JE^%%7m4>OHY_Uwf z>^^%AKSz$S)tbpl`P0u76sUb^EA_SPap1aitTxA*xs{=kO=Tiu;TJu~lEVuZ_dGcJ zazjStkpmlk@h&L_ZOw{MXSx1K3$)-z+Ul?Z%Yr_RoMSA{Y(Pc(^CWB8)6)&-9yI4I z(r9&E#Cv#l^XwDfwx07p@u^alTa*nlF`m=%M%`7>VOS2!6ng~BGL%}8R3Jk;~P zM0-M11Uu`smk!%SN+cCOZQQL;8KCYGD17N9!^Y?8%D1L|;5#Aw;DwIIMyY0<8)tI5 z<=P@VPy8wmc&>be@shC9zTeEZSz8s(LT-sWJL}n2o@;s+dE&oXNKWwI#B{dofDPlT z2!(2nYla7xv8Aw8fuhgh9%KYJ&BZ^ZV09St{3`GgCGi&=ajLqiYyxp-HnceYHPUBZ zdtm3`-x534$0Rr0ea~q1v};Ckh2uNNcQrOuzc}8wSY}!lw5P;6Ywr+ddQ~7Z&w94w z1jbuG8CF$QN?-aV7#^D1aMHLS@z;ktXKwN==;i=zTl_Fp`GB6}hg}o=e@)P={&LR4 z^9m2!G@dJe1sC{noJqN$+Hyi%AWY_vP0518e4BdMwpjjs{MKBBb$9b7<{v*|FWi+s zA>}xie}c@Wh;#TUPT~YZ|M_<*6HJfQ1u1y&rKs$(Ss@%`vsV7z&x-$y zMpo(?3VdS1clS%%eP+DG|ElJV`K0s<-R&_^w|;&XXx1vY!KkwQ)w;t6EZ(Xf4t!wd zaN%eZmxnlila(0w((EsO9CoG){5Z@%BpvDxI}p9&Ywm_Nz8p6em)-Ska~3e&%Ha!| zW3aHnFNRo=tLC9a9Fg@4Y?a}2L)L|!{d>74jp^T4`IJVgOCK+1e;L*Hs)rrYdB z<=QFdEN{+cuJB;`P}k*b9%!X_LOrqZ4Ex;)eQydT{K;RO(8hYN%p%<-VYB3pH0uk@ z0-$3aY#bgf@aC8+t?--I-nMZGyTJdSN2PfdD3=z3r(|+AD=8FDOt-)Ami=tk8s@lL zJCc}E6fJ)7uraqXlr2B8GUp8Ugo*Fj8t-y5y_>?Iui76ac!Xir)qn#VB`lwU2X}o308a5vC1Dk zT`(mho;&8}QGpzuorig#C)e_@gANLFkQLM`b^DORekLg(on@!+BE8xP5Bd8|nRA4# zww--yuorni-&o+0zGTAetBGmuR~6oMGi{WO7F*OJnzO7qfML=6zEqLPXAZ1ce&oZm zJC$wz(R@Y)`*)p4c$mO&?Cyn|0;^B$bUAu@a%Hq+-Rctt9JL_~dPe_GFwA;*VCzAd zn+`K()lQhaRdS9>-J>o1mCKmRzP#IL{X5{w;xi2^_D)S@$aP>}32J8C?$}qBtaMmA z_{0@)b>^0P+iJ|6nZC4rVLdQ={$3?P=@5r3hfjTbI*$FBbXUFM^g0WP9902Zw}9hJ zmB~mG4f~8IDPEQ>Qj}QnIq(XrPaBcwO^gl6%U_5N|uojl8`Cd@R2jn@l<#_Jh#BaUC?WL(J#zJ6Bx%14GyYf%R4ozwXyi5$OS zC8xl=p;P(%goZ0I)yy|V>MW#!cHWxi@J;T(v;@NooEA%~3`0~D_0~3(+BsZn26cLN z1%q}=zi$#daoRAa=PZ-9w{1-0<)@%A72$`0%pYI(+~JhSa?CPPbN;sGO-7`Dk;VbP z6R&h%HN0-kHT%Ewu_SYbnaU#bsfl0LJmpy);VLO6Qewm++jJ*Y>G`@-7w%Y11Z@M5 zY@ah#TIBMY@gq(C&yB1 zrt;O);1A=Z=DV*MC%2p}5$M{WJNeq7sV*Wc$)S8g?7GL9N+niYRVPW7IcKxw zrlX*Jw9kqKw*Uvqil5_Zd7ckP#VBtD*Ew`L>jtCkrR8is#3#+5fWmx;NltCX>)@W0t>t1i*^&B0G-b5P+SDYFlJpi`%6#5vwb+-q>jXN!3L zNb?IHd**}GB882trxj<%6`pLiQj}gGebKvNv;6bM=&FgajIU}MrYB6@+Suyoz4<~c zXOQt;ej&~m-dhv09F1j9Z!1HLCM$eZjk=~0)?lUV#WaCQzC`4GcEWRJ&>^Ko;!8C7 z-uem5a0E@WeMqY~xZx|O@wEo_QoBROT@vqHB@E{<-4&k15?OXB`ts2WuNgYmY?)@% zcK7IAo-1q<7FP)_Yx?m%R^IrD=Q3lTON}xj47>g_FLMfEG^+hoelwCSUHAmsRa5=- z1};~uAC^dMM-Mqc zD|kQM6L|7hVM*KL@E5MR3bh;jI68P|F&@13k>O;baQoRRg>ny$SL|n-jyO%b-MCBf z8BfPVwt(l4Kb$?A@cz#3uMLWK%z58!-J%fRW|3dcHv5STTL3%D&f)jQ!~wB~c8CjYF76BuU8K1n-W(AvSk^7d&%sYAl4LP*c(NgtO7Pl{VZuYBBX zhuIhU%hn_ZY--Z^9Av?|cu^iJg5kP}eXu3i(i_w4$F7xuMt9tuu+ z^U(P+VhdJ{IZDIwV@Ba2i zY|3`f{KNKn%}*SDJ5JgwczPp8soex?xdk`--%PUQ$-jRmU7%u%)V-ZMesdWeS)rrG zC}_o8}9kovL;FJW}R5@zhlBXYOZ{$YD>-O zjkwIe<}>3y?j@fz4p06%quRk?EhiV)E8P<8GMKHPZRNhZteI@OTb48|gWY$3NSrFhKf@>(a!QFxH#uHZor0Y>d=-G56qwx$_S--1*5cx5)L3;U4}* z?qoT}_isR{GwsoqWjbTZpD7EfMYeHv7O~E*8lxZ@48vN9@izAS=LVTGU%7b%T@Hz)s{`0lnl4czHSkBcb^!2cUcD2lF z{!tjAr*>p1+Z9eh3;xLI8mrfwQ@CwB^Waq`qvkDdSW+@YGKzmmJvbOW@t@#>ry&a> zdyS_nmU}i>DX-I=u-n<;lY#!BC%z@U9F?;lUQ_fqx-_j_BD7iNH1|cW*F6n>r>i(D z4O$heYBikW7H~u`zTgvJYhz$rm@F@;(klA!o9zwj)`uDex*r}^oyaiXrW$5&bc40y zwk>{4+y|``6!=zrZUmLKu=5x0wtic3wsCJZ=y319%bcdMH(JT@lrXG1aFai~*yFLW zBKM^SM?qV7G$B)nNK@^)^Y~-t^IOgE72UL=_VU?Qo(;)miF5g9*k-nF#GY~4GUu`78J-&# z_b5~;eTj%mnx4>jh5<5m{pj&6cBbv;Mau&3mT$Pw?3^w6$I?Y2;d^xhWGn52wB{=J zwu)+bwwSpBPplmeOgrnu!}Vql|4#SAv4O10tf0eW%NtQwn>@2Mt%MwMd+*|*4_ZZ< zf4*o>uz|Y6=)%j01y3WSPrZ?F_-&u?$bVi;`h?;MX&*e=Wt#te5qlz`kZH=g;l`VP zPkC-MJpOo`r*H2BqyI0=PMiw|ok92-wCb&cVMFw#iQg*~vYp@8G(2&b%NL=}vP^7? zJj)$MMy?O5vJa#?Bz)Q+DcHuuHi_ZI6YU#k*z9^CmsL&t-qi3#;r-u+x1Sx%xUaly z_~$S{#q*-6;3EX%Yc4Dp&Xxi@Fu|Ey653C&$ z=1vLet`IRkyX=)wLz<~W(`A33B!*I}3D$Biemh?H`z~_FoW#&dl~pqz9x45mXsrCI z^WuTswgT>#o6-7)C(eY+luML-arB$TGPka^M!cicHsz!WXg9EG_yXl>$9bIEA6m=x z#UtSh!1M^f~ky z-Z}5Mu6eSc{$(QDS2uaK3m129n8`okmiF;)h9_2JH5yuMXgs|UwDK@`i$mH0v-OWJ zRlR3iV$1rfL?PaTBZz+%>&(5I`VSiJ;c&IiS=KxOG?w3Vw}EdrJ4=a>*c-JkPa}6r zKH+z;Qpo)4Ez)|EI~$ED}9 z$ere%_0=Ja<<*Q9hW_V!8=RlNdZ~Rt`s_+c(G#=JJI)n+;>YpAZsO9$)smmqIhf6# zJFj*g{X+sFMC-0z+`rE&P^r&~1~Rgc~YdmLqc z)$+!wxb@MJ&;QFsn2Xw(OP=VR33y`dn2@v~xl%H2uIkCW3n#-joPByEgGKgW^`isq zY)c>Uu*E%Cr5JH<-*xNehhfG~E*WgS<+Q4Oa5eRRX6c#!Q%&-Pm`VHS(d5=BW=UQPOd@9gcrGByynd8EdJRgL=Ac z%)Opa{WYH%C$WIem`Z8wZ**5}`myPN@tyC{r;IlE#+^-2S#*BF>ed~-GS>kAL(^0VDy`qFoN z?)3?^IddmJ5)fm)$*q=~^doONv(2h1^}`SEg|S5}XTDh~{r-LWhlLk*hR4q^eiBmH z;5*ZD{k((sFU?ilx0mmZ;K6I04{MGedoYVDvaG%4Jo~=n3dgo)(An^FH!nBbvsS-( zcgzk!BaI~u`z-$&94ZENc{b_X;NkQ*GnMhu45m(5pFRENE}%KeCLYkK1YZ~26cC7) z+R>j|ZNJ3W3Dk?=yjve>ak%&HifzqS@(cWqn3B<2s%z4;xCYp7?&2%n4d=wCB(C(*m~U^BA|ua4(B6yfy7%+F!8;--5!XI52{j z(|X@lG-f*@ckpxro7e8?Mj`$=$sXU@OE!Q88U6M`Jj$qc1-4yV^SB)RH( zKa>@iQ3sux2VWLCp@QuX=;({L!ikTW^Qw}594|Fu&T~^t=NsW&pa^~_+U=j;>?tF|KW7rsd{hfirduGS@wpM@L8$J)7wru~e!)(o7 zq9q1eXv8afx7VOB$5`#8{XWALg^OP`z*d#NJUHRy*_j7|ePGK-)S9g1-L`e8dMnud zSSPT6DM0HWqs#%^~twp$s(zBHrJNSbL9i|lFc z*AWLqeuq3yG?iE5+oc#A9ohmqBDUx`^Af>h?YdW)O3fVRc6DCZ?R>y{t&8DW(2}0* z3lFC}KdG16kn6w>X*TlkJeRy@bI3&AwxD}R(XGCQsM4mz%T z-}&nbvi@)7rLWm4g?GM=xOpqp=tPR6 zlrrc93t0ub7hBc@UsqV1vY?N3g|OmeR>?q9zV&GroVf)iNIijE-}+?ZEXk#wEsQ42 zmss!A{0npLZv4)X@>vBkjudlxHFWh(UsI<&bDqm}&JzhU>iKVEFg&W#j&6F_f71U@ zKym)96t<;nV%YktC-A<0-5@JiRpRt)zQxIe)jd`B>^th$vlT_Y_%Bh)mii!d17~F& z54V~x<1^(GF9W9kb51+@RYLY*9pn6>r!5g?#XrIkYh7~;lL~H!pHFzma&tnSDf^B;&+cin$*H~(|8{6vQe&FY zfws5xF55oq%=s(%EHCEl0>!?&dN*Xj*AICo$np#Pez)*5Po?KVp2@EjH(!VCvwZWL z=_RMt$CiX0@+FdrZ*Ih1cp0w13OX&~XXu6tDs2}o6|i;Yoj9NcZ$|j-YkJG-xIM-t zY{J6`>lFT^KW%$?7T79vl}%_=7O4Gy!Bs?e!MPJ6!W~sNG$YcV0MgjZ<@xRU$%zLVN z!{Ny}wlknBHE(~?njjUR&a#AUc6Y*~4ZSZEOkWtw8`K&U3aqVUGt8~|EL`xUi?_%` z1iasJZs#27k1WEUbYCtw=U!=&(!;&&57+Fl3(Jab94ne(^WsG;=v1w;x4KJ;E(u*@ zDEFv3&tSgiyFB~mjVFy6p3a=C=)K=TJ+X0Ga_#n(HInZ8R|qVT-|~EM&FRdx>-_Hw z?pT)2Xk?*nK=F-R-JqvUX$eA7KpA}DsU$B;|Xqv)kvbeGC zlqlpz@=a3ULoLCr;N?k;etVf@w{vgW{V774c||kR%OyEUJ2pMmJ>06lUox%QaaIc` z*H#JqfBpOVfpe#F+kU4j%wE6=-g~s&)Y+i)22KB^)c~1FvwoPc9;m5Iy z-DPfI{tMPpmursc&RcpvNxtCZyWe^y>edzKKG%KKj}3PSGx_mPFE`#MJ?kLm=ZKY1DL;k-XpG9^XMM0?VD?w1bW zdzLgHtMxND#a4Vye8XY+O7^Fpzzx>cV6`pAD(+8>8?1yDoMSz~6Y-pRcDrNI20sp; zyHhIP^3*p!B={#_V!&B>8Nd7kX0CM~9_lIMI{d^SF@n}6WLw_nA3+;n!BH8WmebPOxWvrjp2 zSx6Q{Nk#8hv?c*WTh;b#lT7rgEEt9WM^Q7Uwxp?V#a#MPakUuXy|V zGYVRqh1|c+u%D?(DaroxO1ze}+Ns4toFQL5Qb zA!pg;e#N$hlOCS>ZLP??4zhPD3ktg!ZDW_GJBsoCVjo*CSxQ&N-^4LmZQE~@x`bn8i; zM`}DGjPM0CFJwhhydCE9-`Kcoe&biePl3A)3Mbrn!ryUI@x#k-2j_%O4|rcPF=^yI zuPN_z6uS{Tnf08S(B>yx%hHa=oj8$_W%I1$?@w;`17#9Y3HIy0$d$zI-#S_H@Tb~f z$rp?X-WwfGuSxjUXr;VCcvBwZ_ZJOM93)DV#8&1t&CL@{n17IAcZom=WUoskXbr93 zDbu!4k;V~ZouqN-XwCb3Opa=r=P;i z1nNCY_PgFzoV!i)sIY{C``4xqtM(qK6)zN)m|!jTxzT%*gR!E5^|^I9tfv)EFMiM7 zxRbTyJ$nc5E#@ZOhO#;P*zN1YK}EsDt251*-^*_L)Wn@={gO+K6MaSbwCKM=BF`K1 zz0{M$Snm2SuvJ*_G(1anf?(3O$=4+hc`Y+s@qYJ7#Bs?@W{ZS3v$H&5`*M?CWTUFN zq=T`-i9FV~?4BO08o3*%CBK|%VH6e75pp%F6|~uXC6F=KrvBf|M#gRTnL#}*MtD!l zXYJp^?mVqOSIjQ|%`cN?!LetLKuP|DOY_`$qPZr%VtEkZ`TxjEp6dU1QvynyOEjjW zERk@qxORK$LA|3*j9b`SE`4EnRdQ$7KZ&C=_FXgO`DNQKxi8jzj>^wp7AcjRRxGt* ze!a<`C#&bc#PS!mjT`!yPY7I4ZF#UX;=o_|4X{z*?`K3GG|cN0JN(*T|DeSD`w8kP zs%g&Ow#(X=u&t@NcO{kQx9ucJnQ|HMilt|;jgaC(O-CGlJ8om{-_u%ZXJ^yIW5IDk zv)NkZ?9Fb8tmRJYWcOBbZBn^%LDI>7-^UqGRxr*jYhA-RlmFI~zI}$WD*s=+sAY>d z&a^~)%NwpOSGbPY8Rjxa@I}g9N&I=jA&Nbvypp@QZ3)kvO!s+A)8F0-GoJFrDeb`; zZ=nWvwdQwehu){o5f_Y`vt!1>x-`q?ElN+Guv}PH{H6E#3HSGpCb8%G-7jvPc~FP7 z)cnCp%L5nXuZ1UEkNu^~Hm#kNF+)__V_vfSlSMk9SW3IW8Tp`A;nogY?pHMpX0um2 zTgyF&Q-Y?VtA{%iX!>(+*?$)149#nwPJe$exBI=kqOtLuKT-)B zkKUYc%yiA?M!o;@73VezF}%)r@VcPkjDMBPSpf}($ROs|E)7TI<1EfF?7Gc-msi1b z!)|AVPZL-H)I_vF{Nel=RlpMVeDUb)EtYMwowAzzT@9Wa&g ziYMb;#z#v#{)!kpNv`0ZXLTYW{~PPk&WWEDmtRYn)^2F<#_D{+>$Ve@7hGQd?%nN^ z47XeQ_J|*O^;(TB^~J~CNCzhK-;;zRSp)(_^&Z}8(dQ#g74o78~sZ88fOcMG$q zuv@df{=WM=&k~06(j%9QKe&D2I?-BqV_HHZ=&;QL&+aRolw!+~<%icbptJI&6V+2( z%bcd!#N9QY&$vaf)=fmk7TmhIcE0wuq@C0Bc*Hi|CHFaQTx=+{TNm4I@@T8cRYloJ zof8&c{CM)dGuNS`(Sp)}d}n8#FnD@OjxCGvf{>29^@*hc3(m3I71z6eG~AQZa%NML zmGq0Oi|?5l=jOE{4#D30S8%li=<>6;>N35>-eDNAiq3s)d zUrZ}g<5}S6v2>knv)X=*!`&aa*g9)YT)cNg?;uko+bwn`>$2+#LKoA($Ie2RAJ05` z{(*SFk%pQNf0yyr^009(xo^lG6~t;JyjPitn`MU0CaHksELS)uZvMy4uN`o_nUS60 z?SI57u-}c_7oB%`)zIPL{Owu6Ec;Z0(`_;}pPs1|WWIelo973^>Go)TNr&Hd3BMg2 zx*Sh$@QJfcba+>g6W!EOQ zYwz!aCmQZNWVrj9u~@q3IJ4!R4J#StZ~lHGbvSBC>a7Ld91}r1zz;j^M>@LG;rQF8 zH~ruE6G0=QKTI}UJjP)Akn74v2Y(TTjV78WN{lm_Ety#vuKYZqsh6;!ylIZWcD5Ug zH&fYfiZ^9*ik-0ntu_ARRiU)RiTN(;C-07l2PJpyl-c>2@e=c6|7op0w@))2FLm%< zRpSLZyz;MnzqyaY&ISRMwl}sB>dY!_Z#Ox8*rfY{warTEI%G>dN3-9)OTlhyzOt6u zIY^&RENl4jVy?ghiTN+0+j_*VFsgvgo_XMIFUx)Hr^B`On)~c#pC|M`WR=~2dJSKs z2-oYL6RS0i8qAiie-hx7vEFUX7xq%SgleaG*@cD?oetlgF4@EQ?lF^JOFBdTJGPZS z1^O*E94uPP$PC_z1U+hzJ3&3QG0jVC-YjO&##njv`Fe>Ay1T9RytX;F!0~6oy}O6%3p=u4F9r`7?h{!VQhj(uead)bU5Kv#4>tt}y_OEGsG`d%cfM zTwvM&SqOR;bP=7EoI&A}-scKCcR$bSC^OqVS-n|;?@Otl z9o@`td}P@ygFDtOFSayTDPFhV$9AvWDa!xG@^nGw70r!%&Txe{fks-3`sE$X%1$%s z?`P@Ejk<7r!5Igs2Hmwxr6w1w6%`DhEDb-Ad^v}24>OBO-czoayG(N!Ew@PYrWAn-VN%Iph?za1Ui-+L*? z>Tp2MGQMc7_ycq=hq$_m(T6H$ztf;Klye1A*g>6c!<5P=d*xp&Pd@0k-|4%?8e^u{ zB?_kx_dRsA>?^--&33_Xk3uQvQ1F-S=(~Ej_x$17VIX+r=K(Q8gO38W#%vc(h8vhJ zoGHk&K)E7R;)KN^&a;ce-%3mLlpcP#XySq0Y}=--P5E)1_2!EcA!W^q-sX%-{J8~r ze?Rs+MqcJRd~yLF=LVP&SZ5_E>u(XveZWWt4c0$+NcFSxwX;q=CRMh<4vET2UiEcuaQaAVc)rc$|? z+?rFC=ifNmaOWfgbeN9Og z(f)1q`}SH}f)qYmx_-8-D+&)V3*nf~wI1KISTQ=4%@dKvz(=_2u#V+%b-t#`trI_J_Ul z5i+chaTa6Q1=S80rZ!&b$hSV5@Ivs&gokg=7QFr`%y!?-BMP!cKaS(dZVaUgnSZZ|w57hK+S?d@%jJ-3gr)(9#Vsk;6=hJ>-Cz>r1%*-!-#7?N1(H@Xy z+u_ll?yr{|5YSe#$g#X$Lpjz4mNqxW`asUv-XdP{rD~5w^Qv8T&L4PAOme!xX_fsu z-QdoivS!BHPg{6Im~OxPEP0{-!O|-}H_ou0kO3`KH@@h9oT=2n;d|Wyzr9ScZX80+ z@23d74!gj^@kS#qM?Lo78OUlcrrSMvDw=+Q8ydc~H}DvoEKj|`dPjQGnU#|lCMTx!{0g#hRZ-g^nB)SWqkf=%RpK#%0S-$3EXbuqHzXcB;d-H>^F&g>db$pH zv(;|9gz0=u(-Io{9MOwK>HKj+!-+ty)uj9@X3KJ$kku@^WaZkR1>wvwOy zNpbU=1-vhA{9%rYYxR}6!pWE$;C>G@E7@SBt?;p&hhHLLuHfrPSDrSlLZ0_}_gK5X zu64FGeEqff#3}Jm*%J)a`<0#?(FHBhd0bH_cevZ;cjMWO;H8WcpRq}@GV7jo3TF?x zJcDm0)BLU3Ow3yua(;@gQEpm&xiLpRN1h``)IP(Es3`jOlS*pCq@4U{QdJ2GkjhoGn9J0dcCaasjPN`do`1(<*O$K4Nn|@iRZGOjaZmx!(Iy76}#Y0 z&IZxHQ?E+ov8>e0X;SpzdN36 zZd6Y{cCyu%H4+)P2-vlu5HHJsLv``9w)TJr_A(g`;W z{)RVvZQLUDWSJv)YyY2*VON%BgT|Aeh8ciPRdstg;n}O5Gr13n3ms!~HCi*S^9P2INq*)>-3aaFu%((1sop0Qb z=W$##yq@oqQAC%-0*}Mr${*Z%o@gn*$WHCxyoXQpuI$xWFnPU$#7&0_o)P8wGN}x_ z>2oY>`WagsKS}zn5I@!kz75h<`N@()OJ~kd=WM#-;@^H}WyvDB-y6@)&#z75&}%8N zlXLR#n9M#;fL)Ba%qh-5ANvAD)8;fP0!z)Kw(SYO3YJ66l+*=fFP34Lf$sC@( zm}kMw3AX8u%R?LwT{vpd!f2+nqHIqN_M7Zhk6r?redf9JJ(PLh5x$(|Nhx`0ZZ$fXZVJ~WD zDT@+&qbG2~hx3zWRKH!V8|TKilhX_;oZj;l-s0U;BU;7QyF%sB7CV9H-{RcNpJEj{ zixr!foR~W)x%``9!W%|L+0)(oKFWaCp+QeH+L?Fw&sy+S)Jz@ktaq|4I?n?)9j|-H zZ&w-Np7L7t1c&&imEk88S$1=?T;X)w$@%wRB3sUMfpz8usREN7e0pqOM;}xO6=@WD zv0)~kQ>OTB&;lpeHT2I8O^aGXyN)|({rI?NLgGT{C6k$USwA`DcOtd(;ckW9 zH^O&uE|%boDl)yuTeQdE(_Z-qh{vgU@W!Z^7@4GdWCYkef!#4*tf4R*m0O~67x*%*K-z}KCT;eDB%5*BMo)m z*>g0-ijFf~k!*|&+EMaZjSYHXO3c5;yPQn7nVD|)^t~<7nIY-EV6%dtw6w%MC-y}S zITQY@*Z+U;RM-z^sTCV+6%`Kd-mP!ckY~T$Zre=8o!~P=)69yFGv7RW<4VJs84Ryl z8lp~E*l^sc;G5PIXTtHS<-n9CJodY#@!23C)_j+IL@+!JzD+AisjtQ8OB!j0gkWcS@OJpXP;Q{Bf*|okzwY? zh82gdy>z&~-^Q?!vF6d$z4biY%IQW&^xf~CX9G3G*suI#*yuQSl26-l9%*Gk_2ST} zvF?Ua+rBe{&)Yg+rM2MpImev?mEHyoL`0}R zHPcR6IdjKmtAhq5oosTz7MC+E4Oa4? z>tB2o?A8b~2{D(tY_nPzH*0ym{~gu-7vg-ks#*-^+}JIcBf8=nUR5L*2QN$2a$dO4 zyes5??{}W+=Z@ZjbIUu%gCcgy_B+%B$(4S`X6-Yc#2Bs40$S2CK_EpwgN@~O(Hgx67k6J1nz8!Rw`paDZ}xFT z*5BBe%X;G^xD#^L(O7QDFG0|eyx$q_7V#Zga29kk`ci&wBZYE{1McsfbU`}4>|Z1N^t~?>=^C;XH5C3xX1m}SapOyqm6GQLzmD(SqCCQ?N)iXk>lj3n zt&7C(@&qhrUZ(d@Zb?Dw+wTpfG7eS9C%kyrd%TZf^JupGXJHb9B z^JXXKYsnHJg{i;X6LyzOG)|eOwdjpybJSWJx97~2k1ba$ZoJ3I*!eJs`Bh5@^Lv)a z)?~INmV4(gZef&tk^s4j=SG^F!|BZqvSJfvO-r8ecxJ3=h=hYg$~@x_--_TH%q;~R z=kmwjw_#Hgz0&&}w1)kP_LHZfpfO|p7eY=?Y876b-Vk(de_8-@o>>e-Od0Fzh67)q z3!lN~AZFNi%$y;?ykc_Wn=;TmI$M(RY5kcN{Od%neLOI&LhfEuOjP<_*-iHEu4g@( z9-?OiK4%vMVzWI4!+&Y1PnW3E8JbLPs=mL2_fI9JXqnYYkX z#E`cKboNBIqbxt062m9mmpm#=0ne2S{J3MpKLzf7I&*^W&uxxzJi_|-TUT@1@@Kw~ zWt#Vkd)D8EyNpa$ed0gCH%FF;=zA!yXl6v&t(E2Qy#dsh@2O+w0IfEwn%MtpZhegz z^P3m3Umh@&Iw{QU-^~MW=D%MRyISH<%qB^(4QEmcxb#wgEUM}~XmGzZahXaAKl8S| z3I)IAC)JCyo#444q!V+Idp57*yNCwxgj|^KjWf`_0!&8IC7>>Y-h{I&u5STf(tK0k z#w6_=_fJhn`j+~*7b-1`Fvj}am=(`DkCF3yaRNiB z-GRB>3;Ni)ok^>Zx!zdvMUT0{pCcpw#Kycs z+I4;rOO3ajZ_{CBFSVP%%vM=>^>_P(A|4er#@IO4Y3yB#^$$0#yc)ZQ_ukJP-{gwK zCrw+x_#;=mJQ>sbe71z0sR*#y#VY@Pei?8_`m zxw<2l4z)Y*ev_Tx$ob?P`w5v8yVKVkJoF_?-sClieKE3m;o6LT27$<;@A^07m-Nk4 zE_X^`WW2>csdITSFL?M@eCOwdeIht5>PPB@zo>`>(^p^$Cw=)E<;Shi(OXPuQ; z&NAlNcC7BTZPlym4N`JkY(LL?-LKR|7_g6oO1Cm3e^Z78)#c-Am2 zqtQz7#Ir+bRveZ>e@j4@tuAB#yRDc%Sd|U56Vaw9oq3tuHBQI*l7cz24lj7dBN@8; zrtNgcy&{(iRY139*MJVX-njenB5p|!#uwY?9=4KHF!qzRIGFIPp~`@*BmWz7&~6>I zgNriT`3_qv803QHC@R5Q=~UQ^l;x^c$*=e<_>^bo3Xv_Eva^G?op0rdIqOX<8Oq`?WIdcl%i;jEG#q$l$ z6gDksJbgg0{=(Ylhc4`Pc91^5HAk^Be}z1ci#^mKVP zMDkydRWNXN5EoRs&$?-q%qDY2(Dk%$pKq|0Pn_EdYP56AzrCa1(emuHhwg99+xqoc zCHO+-CNi9@d+@qu%gWUT8LSS6gtxquseNqu>EfOppsq>y!nre>-)<}Z(g3=?6}*-o zv?}z&vo2PRT?yVB6TH_sOah(i-Z$ZP@%Ki3ZI^jp71B*GAK54gTfbN@R1g!<0p@X&+1GJF%<<0nc2f#NVA8{3Z;K#A)?~B=& z?%On-;pjS%D5t>;y(aqK$;=a%BA)O*Rj{7$p5fruJzUo~8CSNK>Lq}u7uN20l4vZa zu=R(Pyu!~56N=aZ)LFKOaNo>%a*o~O&)L)Oc@`|Lm>TopzV*>b^LbtxHkt{)pJzMM z(MS9{=#q{OlRn{Y@S4JxJQ)mX>mm%~<3tqY&vHYjjO)cKil%+CJ#k4FlHjs`eT+ZD zyh*O+KKq2mnkRb9f(cjm+VT|coACK2Y@tmA=uA1bEs3$39L0b2eyNqjsK+K2tAQ^S z5uBmJKg~{TtFW`ANAFc5kMnPw-#N2oG2VE?o^q|ZkrBM#N#T6jg8M%iiYo!&9( zPYe6xHYch$vEFRY=Z`;sDYM1-T7vwU&wV#_lOIkG~K4%uw036chd7Z}go zI&k*P>AJazh&d?7V~E^arq(>kR_XA*oy?NFf`JF?r1^LKd6InKal=mq`ju z4~>jp!|LIy5nr#kll3m0;iTf}#qY%(%b39_q2ukPodua+RKrgEN+@qSkY<&&=8fb( z25Y&>Zxfhh*6puh4PVz;GWq@HX<9pWgz%==+Aoac|Kj^%!MXOjRbpOKY+LUMG7GWD z?(JUtm~ql!HNM%3f-c@Hv%94ZZdTl|SK&ySOTh8RPyS}}DCDeL(Hbi4!Kc!w)1TW3 zDmGu$Bp9=()!kR_Y7}9()sd&g6xqiV)#Z9dNN2*&1*#DncwY#os~9(=SuHDHhu93_ zP?cWr(I{hnyNq-f`ng>3iI4JDH^@%N-jUwqaQtJF-yx^>6%A*aWv_DIT2ohb(}(Ty ziW0WF3l!MGGt{5lT7BK3S>npi3q9-80(u+XY>0ZudGind?7IwaUo&(b1TCl!awzX? zIO5oLjq&RF+t*JfylAnIo=#|IKF*`qovR$8^ND` z0$+mHYu${HoM0{US6I-P(zR7ano4+8*uVKm7z^#6=EWX?V{q*m~sm&*a|{6RhPn zbaPC6%(M6NK?f#=QoCj6;}0>sS`czB;=qM_mcnbS)2;@xG2e6LF*L)P6R4`#CO+#$1xh5NGGg~B}>&auC+h!ZS*W4?Cto=X0k2lbRz9DFc~%ZTIm z3ENL^*w0wOGfvfxADwY+{$fWX4s(?0=z9oVvt%swa+sWHqpy%0wZQj9?JH1rg-#fw`?&hb@}{MC@%lxQrk@ELY@;kIt}!j+7r zPUrG(olQ7#;Y7jj``T<%YdmZktmNBe6xEk2p6{6OsQo0*NglCmMd@81OWhpYUp1X+ zeai^F0BdFI+zF;1uO_x_O+2arUupoIZMwH)iUH`xr54Z$az<+`t556?5HMkG(#}Cy z5_jmxdd74|$U)IgVW0UT&Pb$sJ?OEzFpocgop}kvwVw^3GC!sFMxM31xx|%^3Tks} zj$L-Jp7!7{gS8}gNz}BpfbW6dS?&jB_|&w4ZHwP;}!S+lfyhPr5lBjpaZ)xT+kC6+nkJAGT6F zk@j{^<#fi9Pof?^dvA0mYJJfYxRCax+P7Z9&UVMS1IrhjWOx;k(^Te^FqcQbR#dC) zo!x|(Ny1AmGXn(sfuuWYeFA&;F$RIQ}6`%KmVV z#tGJGC+6}8EN7nGI`4p=gwNipM&ag*JD>AhzOLI^?vPM*!CHR7Zu>10K->6rCYaA_ z{vjbQ%w(+rK91X3{ax~ouW!w6ctJa8)504~8X;#e{N)m^U!;7P;r4q*(7;q9cw7gx z;C#y;F3^c82g|Lkzy~W{V!p-CwCgu>v`vHABI5^)>V1xSAGdCB+I!?W-;OlF_LCu-Ex?_5iDb#EtA}|f`01^f%=BtO!-vVa zb9q)Nw(=}$>*HBJJ^7vduT=%?PxU4om77rDHcxQp_U9~zFV17_@O|;1@5IWOw$5V3 z>6xH~e$SMlmY#h9Y660;#Ynm?ld^+-Pm93qqb(<9U-nl7m#nJDh`Tv@0F` z`>G0fT;tn?QmS~&W^%u)@laaVyYfRXQn2-Tu2gH?G9oX1rO!ck6%S>AjBAQzi5qRUPN{TU(nQn!3v3m$Aex zF@p(A_jbuK>-9Iyk>`8WftY3a)?_9BlwCZjlxxLj#!0*FpGzJ7pD!=*>}+Gtng%OL zxpM-#3--!C4eekODA{#&$r3WRrwLbIxIeaACVfS*vD7Q-kC6oE+JViAA0j6%tv+!49iPi_W|@1Nrx_zI zbiDGM)v2$DZ{FPl2?9^g7S#PuVrzCf!6UNb^Tu<0MH&sBTW$Y@=v?58Opj9hUHo9K z0NbO+m91P6h8<#|tsCAe-L0sRcx&V|A?e0Hfg47;pgF}D2K3dU*LIn2mvAV4`a=4= zqk3Ya*^=VVN@-!{qT-EfO}cuL7!oh!96xkHfGuaU@`;7X+j+nKDDs@j*0z4Pgv61B z!aG41Snoaj#hFLn|4mB6$Hb%)X^N*C(*lm@-g)?HsiX$`hI7ZK&z>;3tKv%PL)l5y zdsj<1Y?f1qE-1B2&^yton{-3BrtzTXlAeb$1s5z{25KF)0qrew^4^e;)&QOb*tluG#tIZZ%?n{`Q&rw5{@*~9*~HJpYy|)BIqNtg`?`-vdKK46JVSZ z<_bKyyfL9@!P7|ZxeBt@Imh2T>hcA(e+Bn)y2|ow=sR{d`?H{N*}A(VEOVRy%eL!V~yC|KS|E1F=rz!w}|?w=36IiSiP z)i?F_>JtL11x|v`b*zhUXTF}p$;^5{ON~+pA{=f9TFkDOfa*=g=V=Qm7; z7k;r2c`SD}=E#O0SLJs|WVo?x;rz?r7s3r`iA{L`IXD44epq3DVt!5A=4|z*-W4}Z zni<7E==&txkeJ=7#A{t9u6E-D@7@dk+(uoX*#Nce@1-(YdMAT=2_c}-nzBoxCuCwi zE#Q5b_BvfKRdmJYhlTGsnZMt&2xx8zjNG#RF?&j{1a@p|B7R~@P@sE z_m#tf*Nml34v!Yh6wG>PUX*u4FRx{eor!L{41a?Rooa z_ntRgR~Q*f?KZS(`TY6N7s}&f?|548r-qm5iS08V8*yCu*l_Z0R3-SXqFvva)!OfT zbTH$dEj2-Ma`$^$+4+)p&l!9c zd=$kQaGd$()}8}=>=ov77R}LS&XBzJvU`H2XmIV391b65(DwQAi~h$CU0cXd>b9m> z@%8+Ezr5rFS6?>VWSu4WGn4Bh$9AKX?Y1j~nI^TD+U>j7+OtmSbhDLW+3i^e-9H>M zTW~nd!J(=(FDLm#v)*2&kL&I0k1XJv!`mo(lzTSg!R;*EOZd02aGNkE#dpZ9DMf3`0uF$uYrPOYY&KZd^ z-Mz;f_At%`tpMBYD1Gt#|Az@13>x3)R{Ry)v@SFxLimm(W2pnj*{TM!+09l8TnAJw zHtEG_#MSL#uV6a*C#mhOutK+840n>`yx9H63re2{vaLJb#Ist=`5HI)Xs8Q6x!on? zxN4Fd-W42p_myF#<9=b5W&G2nF072yiGL#5xAu)gp?1!)=0*kwd)e%>udR9d*WFLi z*wmaeuSNIZq3eu{k&Lezz-J09QqFfsxBtv`?`K5;uhFjM3s@z2S)hwyb3Wa$QdF?r zz{inujd`yBiTAIsNgH>RdmA=bNflipws5mi$oaG~qCVi89lxh6V3g z1EaVseNTCEmul6&eHzVkqP#)Cs!cpaJVW`{|Me3}kARl$mV>V5{W$SzgO%cO7rP`E zY0yn*o&nDv=X&c^JY!z=q~ z!c0cOS1fndy=QIi>E!fcXE9;^^zWi_n|iv!=Hn+m?FJowUG3oDz2V&XvXlwEHisr8 zuvjkJ>U6)eQG(%h!+|v03qN0^W$48mZm8KMs%Pym`+{S&L)>SlX_p$U6c(sP%;tNO zTw$)<$GDT3$%y$1W2Hf^GV^)S6DM?DtP{9kq#fYStit~)2Xx%sM#s4#5$vob>?dq@ z@;~r>aeIrxT=B&|#R=>#t&CeZWp4}V+*re|xBYOMbHb+^X|@SP3wmEHuy%U4(?P0X z!)Xr56$}n@`;WO!n9TnAu|nNp&@nAq7koH6c)>H?e6N9TVQhSh?A9<3WS3UvlSoIZo$kniiQDT#)-TjqQma+lu7I zJsV}VT$I@>?Bv1gv9GXH;EvUW9*z~vP5IXrKY0+$_T}ueC2EWpo|Wt_{i-3`-`%bl zZMjDo)PCZA)PSH(FzAu7wF4QV0d_1=JvqT1?55I!m`dPR4wD!4?EbJj(N@6sN=htp29mKHzS5WkB3 z_G!jf76-mGTM3+~wz)7p@nJBx5%ZFAt0ldM7M$52el&8!IrmwtDV?k@I_@4|o$vv4 znbDP-Gb$vCRODXl69`~uZ87e5NIR7W3~eH}H91}o z47yq5?Pc6xrSi9PFOSu)6~_fX+X^QCVBYg4`{lCbJpJ}ijO*?Rv)AIK-rRF_a zj~+RK&QyGC+0p+t$tfnwL3U<)IiJB3{pw>Mo_#EB`~AG^ur*|5=vnJuU6LtJ6*s%C z{!}b^NX;*;W0hXognK`yCMtJIGL>9Z@Hu@u+CQ-5u$8!iqk!}^&PGiomHu}k@J`PO z?=2U;9`HM1HG#pW{J_b+=}XT`ocZsd6$d(Vl>JCssZ&DQgGudkn_6q~Io2gK=em5~ zd&WVG;cShB)GnhJuN=}EQ&UVN9b~yv4m%jjpZIh9zQS^Y#MdYeu(Y==yU(20Vcq(%0L0LYxb7723 zbAxHhU8{xQ!PdX+2Gc(_Sjo4RO-QwQF;|#Pt6|&q1AaeMQrj%K%?u;<2&a17-9JaM zN>ruC;qCoLw8%GFldgJ|5buOG0*$N2eG?1_;Ku#zW1h8 zW~2V29*akzw>1UV<^0~2$+N+){rc7_w)J8sB#PIE*)o6nq;r8YLcv$TR6**BV4%NC zEEmhI3O+N5s*4IM9y4s_xYFow?{VWk@QzE#6IFK`uB)j!y#LxTlYjP01(CBamM71h zWjFQVxwYv$?hWdVXCD$S8+A_}dMX_7oY`dZ zM)~7`yA^5`OqXACV!JCFTsZ&o^>}8#zZoj< zO}ntY^^Je?*@lKMhpog7%+?4q8PA?zvu#7N;uMpFkBs*FJ=N-ul%`I;Wv1=+4W z_a;2G0^iIDI@8_hUCM&htUCoG-+#@|_Vl_4+EsUXL&9c-4Z@q!{#Ko1nEf?jf%1g9M1FXpZx!L0jn=#hU8T}wj(Bb zYd$kZO*+b8b4>6UyY9_XsSR`DmOXmNzu%hWrbWPW=X(s78Xce~3jGDm`JX-fxBcMU z3G2_#H)^m_yzysoI+u*(l=hUQNCngAQ*5_uROn zvPSJ}!#&Q#1xnDJ25Xs1?HpwJ*rXT(+*@Y&aqPV2f4=!m_K7)DnBF%uoMD>VqpHC$ zGcab0MA2v49QhMw4|-ozeVlOl%!KzWjk1S#heb9rmMB}DkhyR&{Kg%&S2YLBR(^jU zaf;z}$&u)t#s~6Dzt4&|uwikkZA|sGOLc5H?jM`1;x^0gSc#1Pshg2Of0=B({^E-NZS+^`vP^ACD-Ck zcR9KSbw0dxCzfX!o2$md+Fwrc%+;HunO7|SD6BDm`X|27Iz1OTHI7#`DpJk<#}gUA zhe4%AJuy6>C(ClS0#xb0j1=40$9Tn&@!`+(^uy*0ep^}?+RUqHOI+M;!EDDci*e)K z2`3M%Zj%VuW&PS9f;;1KrDu`R4Bpoz2hK39WISoS!1vnL|G&;M+-l$pYKP3Z)K-d~ ziMip!Zf1Ts&oi8H-n!CHe@fW`jx#Phrz33C0lq6%H)r$DO|!Dv4o}xNR;hBBwtba{ zx1r3v!kLNM)8(2=5)>umxt;eaNSIwd=)h25xWQ-wlS8#V$I5ol-kOsW)9qjb?p5k6 zk!P=M|1XhJ5Ye{QnJH>ntFI+|{atRr{_-kQ@F^R&U0WBNYtQ3&B4YnUx$L6!fBCFi(lUj!uUe#2*YyM*8xIC${%GvL5 zL25(KrzR^!182wS0!`l<8@|10RRC*?Hulepxo|b8ejc;aF8+IlheA&tKZyg&C z&sR2{Zuz*>7dKjO{F!X@lKJo~&%HchvhR36YhL@<*732QkOQ3u$1Vq2Xf>(n?xa4O z%Z!)XeR-e7BCS&zV*DCpo`c(Qw2e?LeAiLR!PLxPv#Erl&}x zJQY;GlM}h_g0%VxaX zP-oAf$G&KOpXjb1cFu1ed-HVPfBo>w<=cNJOm=9IUAu9Wq6&X>9qT0?t3L7DMmj}I zAqTJYF8usMYe!gwJF|&2(=67X8cdOK472_^*hzAifGTq`IKitA6LiT4>$Y@+F3z4 zJ)UI=Um2I!n-I`(4{F=0l4PB0BW0LZ++w?1)0fN7QT5|cnytg51-wtp-``DIAlC5q zBg0H~t7+ml@06#1l3aJU(dTQ`4Naqrl^q6mcBCEIkZ~}mjV1a7j~H}Nb|yDy%0P#s zdCgt6Qk#yC+;66pT-e9|q>p`5+!I?x(7F1a<^h3^OiS64ANbUYe=z&7NmGyKeqOP` zpC2cV1SCYBy-@nmV$bJ~-(*uV7i^dy7V+jw%n93w4d*z`em+iD5Le2IQs~R zRnxTKy=gm63T$NxTGw<$r&dwhWYMZ-3BOe3WkQZwpe5Dw9lSUGDc_SYqkF0Co;@-} zC-qhcH{SaxQ0%bxKBw7dMsD?h=gdo|dTJDnH! zUo|w`xm+w<^w=chTQf+D+_JR8;twwBceMojUOr^SCaId)rV@QZC^KiX+=*q#IVSGH zBwahdI+5cI-zo(rFLRvBAJBe8xayKJFgNw$^GTL1G(bHX6k7c!RW ze7IZ2XUuWsqr$Pf8=|i`E{{2ArC?BdL}n-VtB3|GL8W3v*^~=CY`gX63!=GkGWT^Cy|j&mTPEFjpYu`@u9Ti2{ZT$BHM2K&}`NVt)JE0k#%t#>`(l z6HZlK%{N`6*Kqec-7MTo#37emW$2&Sy;@wd zWsBkTl`^{bnBJ!}d}*|jcT3CrP;hI5fKe3ptiKNT=JbJ9!W?LwTX58Y;Xqy>JLGiW zD9{0`(0fzTT3joezBe>naWOk?uthX4Ng{*cmBoQO8?3~FiiKuH zY`*pbP&ODBM&YyDBNd#WFu*m+*qS^?VWVFgjJb*g2Fc; zrx~YPo|-hyRuFWTzRi8YC?X@u=#14Kp&I2~?o})inxEz>ESP<9`TZLQC#-zPIPLH@ z7VewR7xZzg5N^_8oAt9H$L+YB8)y)1)# z)C8!rq?u*hXZMj&VT)=zT3KT6?4j~R<6Qf9#nXIO7GII@F;+O9yKJd)U#EQ)OHt?i zt-RmdRLm-G@NleAW_nek@LTlCONLUXr0`8fM>=ZR^>zoPF+f5q3wjLJm+143X$$lZ zS9O$}G0FJP{wuXb!7k_H^VaDrtXDYB<-c%`e@68LYpn-JE;p(;(?6OC-4=*^{aF5f_s(^QoJj*in5-YI`%dnfyf^Dy6pPn%HI0Gnuscfi~ zTX0j5&4l4Ks8?2GAzQTR?%g99ZL>csdN15Kw}jQ03v}^Huw{<1)w*-+9`bKm*0AzU zXl{0x%m2T`BeofOY~VA{P0*&c#^nZ6R#YFTeX;oSv_z?rXUZD74T&EWAAH=_E+OHt zS^h|g-GukB{puO#*V;p>IsHM0c`j7 z)gDyP;aRy{Xzd{hiGTOfX6$F!^kow3mY*^yHY=2y?4+5j1hvodPMYW-eWBC#E7ul& zmY+9bOP(KwcO$O;WO&&=cf!&c@4AZFSfULYt>hIxR$o^P-s?5X=>ebTllua57IMx0 z+n~u%YWI!ld_UXAiRLSsj~w!fl}M|tJ17u-`FKHzqxHQRPIhhE-xsJm3szfpRe`#Z z97(60{XcZ9Tftf$;E=?6ZbGsuXgu>vx%2n>1n`Z!2e<9vS|Wahv+-_Q-#f(_78%!A zZWr!W_zJyJb0=s|+ha!I%M%;V#K_$I)N$|_d!dcdnqOB+cv7P2mtzGJW<|%Wm;BSXS#g0Rf57s? z=hfxbeEm3iH;=TOgWJr+YRd#!_6bZERGZ<0DVO*!aUXKrIl-;WWTN*5hbqwdmg@1k zv9}LzDAY~y=UcIn=~WG=5teJD{!HTD-PU%=nBTpUD|q$pHI;ZcLht3S{2*(wdhtPr za)wtmGt!*y@Nix1J2~NE?A#4p3C|DDVl3Owo-x_d@c0L%c#j_szUZ|Ty(rR|a2&K> z(n`UgzsXA8z-)yuQ_|r)kK^JJ3;Z}TR*JniR&qmD@x|=R^85cV7&7hhV&3_rwN5AsKu+x4{$}p+3mmqGq;_s*{4Bgim}$1;%(+zp_ZS;j zP7D`Gy|F>qD0o-y-TYNccq81GRGB`xbmv;Y5zd+g=i2v}Z)mQllD)Bx-@X69_d0O# zEC@+QIeehILbfkleERSad+w743-q@$mD(j7|9otHT=Sx@-~MfVaE{&M!`Zp+36_GQ zmK!3z*IYQW#mF_0Xs+#Pre&-95~BRYR9$bjN~@2BI6IXPtzUjvc#`lWYAsRweC%d1N)C}jSW{8-7h=W zz}jFX$HT(#DTl*H^UaOe9bsl{ZT{s7xt@rX9^lP0+m|l3W>?d*Hg7(-uTKB)^L42e zu{^hI{4$uWRy;oFz|wGc(!8hhPhFTWoBJALQh4<;qb+k+Cod4|FlmiR;8^Ua$+72w z=$3~vC0t^gTo>$ioVKo*5p=Tlk2D7duEgyNo73&C$t>yG?KqeJ_u{oFGg)uVnWy=e z$yI-aFw-p7nU@Q>bogG!EQo$^hxg`wrdgUVZ){`I>9xyddR6m7-NDbhbCZLQcWb%` zxXXCAj?en*s^XVoprazB#eLERb{%1y&*=EBp+Sea)WPBO28W!b%^epto#yt(&hOl< z&w7oq@od$C&z!6lIh(C~WPg3!v*XL*G`ECLC+6}`i1;mb!XxGKtG^miojqX%)N3tzZsS#NH zr?vhY=vbxtA*rhA0_HH&`=7WZ5$%^`G4~d#@xP77iGt+gw*%^)I zi<+$z#3U_wjBlA4Ygnr`Y;CfVcmJhuyhAD8r=#Z8RNsq1Y!U2F-|b`l;Mei3nh`V_ z&7;C};n^48s0pdTCm{C=rLp?(W*pwNPil#9LG9&`A3Pp~0tNZ~QmMQe7oL5ItzPKu zujXWCd)P|;Mcm)-?^Hqi@uW{F{LY)8uf|epmasgIwL~_lp)^1*cgBGS(GLz5R6I;- z6EHL0aB=rfF{29cs09(5xBh2o&gMyZQt*9J*qTo@aZ@dl9XDk1#hmlx{;e9m;c57b z?Q@my7lDR~P9y}Vv)s;opC$O_@`6!cCe(;thkBs;{Lk0b{hn`yA$bG?RtYB=Wou-ri zVfCt{hO<=%zE#`oal7-$=t5fQ1z81!-{*AWk1@O|k+HsUc)^q&tBQhry$>C~>$@JD zJ9e$LHsYzP-;Rdq(T!;q?`)fNxPvBrPGC3-nu2P0!=QVR>16Srh$8}Tn|3`(emUU)jIzM(F`wX`yfr=^X6*8QyK0R$&(AT+T zt-&cdfs*RP&58zvPkdh}7zR9Nc4@X&aA;dJLFf+0bjuZ|eG-jjc~}^7(pZ-9fcB^9 zE?;!dL;fn$%Et-b8$OgeIQ&YSE_ldnQS-N^gkr8UF&F;IJvi6St>Sy9if?9Pz~q)5 zn+7XIg}*NYD$g#;OnAKRyJO!!wv(H!oKD3&5nh+DJg#)Q(<_l1fqQOTnR8?JL`AJT z{OKKy?|wM!ZxEQC6qD6@Q{S+~wY2g5Ux$0#pI-eCW=mpN!^|}MtHX0)qvp-`WbQCB z&TVMj!=hbzQE*O_<8+=!yBY*yg%!7I|FcW<_|%hnV^^9X^RKjGHX+80;$PXit`CIP zF!T7PtvG&d^AmMtCXo_O#W!*S7gmNVSkCx!xc;R|YV%l{c<5_?@1`XX7foSD5M2Juw!P6> zh2=6g>dKNky4u#fWbK@Lrv7BX_p_xNB=+rg@_T=e&+OV2(Ty@JSAJ@kHLiK@3L2W! zeI9mNfz=3f&HTGI`1u#P*I1UZ@4OtieM|R3O{uSb0#2LdHk^I-VlLl|p9{{ld#7+U z^W3**Gk&>W!?A{6<68X(p=P@R%WKhPW^El69_q~3?nc%AV>(>=U;+1<&mX_BEm2lj zvykK61erNJnGK5NcJJcbWwe*C&}4g8pfj7}rO9C{^%tLb9Dd%`TQOJqf@eg2zJneE zXuBaF`^Ln%0s{6AZsfH^XrJH_%P?ap`Jz{KocUQ|&Z7;H{7?8e75^UpE@sS<>20`2 zapQ##{AF#g88*t#zuBI|wBqx{O@&g2U!GkqVUxrpVI-@d9KT?3S?urh=Bs{Jd(s$U zV>;Fd?u7(2+h0F{8Fo2Y4zd#av!_cW%oUgbx^rg+s4uzTufnhH&k}ZaZameC%Iy-| z-!+|?;Jo`Y^D~f!<*AKg&J9+I3vOR_EN^_HqQvJgw_n%sg01)d|3*I?td(8W?06O& zPMKqTNx~sZX!>F^o1DkVlGhll75^w*e>k^W{klR{$`+S{NzuO*dxayOvjp#(%NPy1 zitj{0+nhP=HR>FnSX-<0V-g+SR~*>W?JENwV^UlqZ^F$qo6(W)l#8k*oBVT?4FVaR zqU#daWKVNXvbN>lWO&bnbI1Ir@~_lh^smopTpsIq?N76n%nRxB6Z@YXRjp6H@5{#f zfWh)t;GPA46=q8r@CWQH`>xkK&FH7>J@)PIj5Ss`vROMEe{~4F$YHVmZYMtZ8=R3F zB>6x~Ap7t9{81x)>B5sxQMPgmhq(ez&av@AbrD8cGA)V zpQN@dm;Py19MjfhC3hr(!-#vyyD8zU&6n>kwb)v-?<<$y_g4pe*`9zm#U*4pK2q4K zC#>*xp33Bq4}TR-Ogmtuu3#9E-g03Ld(LLd6_-DL`&Hcbd-pm6pJ^>?e0~bPIDFt! zKW9$s+I4!&YnU1DT|VewbK=YQWQLdS*BEb2;d|tNe@ExRHHz~cpWSqBEA{K;i8?To zXM)9=&y2~3trQK69X?5WE4Ifr+<5WHpmf7I_KyAk9Fk8_4CE<0>0V}Z`X>Jb2vKww+ki5X)^JlNg664N$KO1Cs za$jQG|C#wLPfpeW*%{g2FRo3FsH+lw=GwC1ahaqB%c-PKJjYiHwysUpej?#ob9#+K z*depo%I7N@K({rVcC6{?W^WW1egxXdxJ75zxd%EwCLX*L%6K@v_EmeO_Vurv>-9 zoivQ*iaG0t-7c7>=y0%`u}o4CRAi+ceD}KnzS#R^^V|un)_&q8i$s|@8MeLQx+cgd zdvf-ZZ*vwd;xO7I7bDQ0G|Sadp}9$U$q|;hMXXkDxk~=L3-Rr!68L?3Q#TJ6(iMnj zx;dX4JOG7T$9F%rdHu&uIlNgJ4(bl@zFDwWVZ*uhDGRxs54{fMDaz^)l!8v$>bF0A zePTUt)+SnP2j!PYZ@ll zY`XPN_O(QUtiTM5UvFQWW3%FUwR8gS1n@CNh;+C5Gvg(8YsKuxSMOQ`7X(^9DOqjz zqHy;Okweqc7wTNL>Y96i!xOBw_6vM7lJlepJsEs*7WXA!^XsOJL=?%4lsiD z=CW^eoGXyBTxgQ|v1riw0=gZ4KRstCVgt!fL z4^~E0fA;O*DveNQscg3Ll3=jbQ7~073~+BLHRNYLe3(DttepazA=}= zwy2@+mg<&0TxtBEE4rU(Uyz#+x@i`V*rpq?jcc8mUKKQiD3^O|Sjk*!SHh%N%J8W( z{KWAOhw|Ln@AmYq7G`=4Iy_Qgx7?MVCyG8L?66uWa_6VPN$Uw;r?ucO^*eXYC#-3VP-J=)0Xm2A<3;GPRYB(i-^XkWFiA;Z)ZN_lQ)mkh z_s!!cig^A!QQbMoe}eM@$IbFBR`Lqc30eQv{NUO)LA6PG&vWK0ofa9qk_XKqr?fwm z2zdV3M`p>UZQW}U3iz1jWi&(_JMrPa@P~i|#}gWPwHq0lQw5d?++ehP&~{KSsMFE6 zPX6#+?lzv^ClD6oW8MIl25MOmAK|tigbCdE>o%9BJ1x)fA-yA-haCJ$^rwU#*jY?`Z$Wz zS+*$d{UlznlcnHMN#0ktwgXo`@))O`OEK_kUvrkd)Gq9YdBa-fQm=&R{PX7S>~)+g z{#7C=;5gHj&JRKc46Emt<(Re^J7#TK<8<)RZM&ESUOlf`rWrI?$((3wG+VlO{&5b_ zIGSMl0@jTm)y@P5Ib@yt<*22zTiU&F7k`P2{*Sx~mv2}r8a=b)S*sl-Vdn3uQ+n(B z3$Et#Rwq8`dOT-NtWmoZ`Q6}Rx%zwK57oi;7k}%|JGMZM`(;dn*@DMWO{JTqi#Bns zP;P>!uip$;ejd2~(c!yphCN4)8H*bGyq5E$PUV>YCQFR)e6?{oTQ*l4A2;@R8%zZlMxUI{yp#j97T zto(^f>jv8wg9m@Z4wX)jj0LSumtlslPQNasdqFdN10Tm3o|y861}i1dD*NM!#}yL186#_!E8;jyTiG6 zZu3MLOWho#FFC$?fBw!{hDpp1{|DPKTZ>is^E!@2Na}^wY93QNM=et{N%CSR3n=nmeLL9 z40indX>h=7c5{Y=^fLA`A+a7iai3dp5_9Jmv}p&28Jf&#m+`%kz#(~60es6j->VYP zahEr_BiLD%v7pRBN*Gof+C=S{=D26ql*U;P9=>~=@c2orZlP3ljrfxAyq9f%BP?S+ zJ>MlI=`j1!$VMDynF&DM%1o`JeIHyi7$#7?Y{KTx~yOhE5# zF`1_Oj7+y4JDxGzlm0FK*bZivXMMNj<&9T-I&Gwq{loYSFKgT{mYZtF4p==FbdJq3 zbiO;4X~*RBv+q)87;K#RF!2*-+rR(Ok|OgIw6s|5Slc4M?&Ucl%N>xevQKQ&or1*A zA{%5j*(|Mgci>|#wX<8BlVEVot*34kQ~xuU{bj;sFBQN?%rM@a#Ao!}@xKrFkQwu7 zdzH6&KR4QQcKrdV-uw5R+&o#HluE2p&XV}{asi)Dil0~dj>=bJAA-Dn-fr)6u(HWA zyCJ!}o*eb5NG$D1v4YTFVSLN^aUv&lVn@LP&-5HVhFzJkU zq+`~jWJTVU%Evoym$Pr?F=B4YG|lpvy%S|9(~Ua1Or0SM4mUmj7){JLo)|+wU2TCI=jU{3Fz(YTK1|+Arn{U>w`%w%g|z3nsW1D?7{m`*fX;*13TR*) z#GG$mo_zV3r_B46B&5Zf^c{38jCPi| z!3qy;!!x)0Dm|5QY2rB{%Xg!# zctTY~d-Ek9{m-%zcMtfTIJzWnL*N4F84WV08+yE=&vK+zSm#R}{!?+}Uc;GWTOMKY zWrihZ?wn(Y>JrT^ovA4ADVOr_NNcrZS^bRGN4yv81fC?9FJ)0!e)vrm>#o3HF4wo6 z$`kxrT6w?uu_#uuNijw|XTI**(y}JCYGc#GgYJqOj4tqSbTGcMXn5gnUT!$&9Y+3T-{Y<-aQmnXXLRI`<0UT?=z&jo$#h8Npvysb1Z_T2ed@tbkew%7=U zP47f+=RSXt20B{mMthC-E`t(fs~1PK*%FpNK73f4$KTH>Zyj4_A(yvd!-mT{Vh!O;hUwn=bQuQhfmvD?k}oaQ>=OTu9I(D-8)_$>Ez843FXZK$#yU130w%=dp~84 zMB2H=5)H`lXVa|}(`NNOb#jZF|4J?ad{lMyrC*UepgT!+Y|IvHmS7jY<2kc(!sow> zvlP9f9XHGGu#yMKN?+LclO1;6*MYtlb4@o-XH;p|>E9R6lCtiDy?I-3{C(pS(w2rY zwu~>2=m5T^+xYDm2uvUAo zP;KY9JWf#?I*@a(N6#n9iz(Me+|0pb8R&YT*%PV|cAStk1=|rbDsLL>u z^Hu;~(qV89|M9DuhAT~e$C)mA9Zlp>;#nas47xKT*X8)LYRF8$mOoy1FU)-S-1*F3 zy9KrihaOEhsFyT7q45qQ_$ZO zcQXET`?6>0R380zcF7Y0rX>}4FwB$SeADt~*2bBPS1J=E6cVgOjdsO7esti$IzGqm0pE#Lsi{0#rzY`u3g-zty_~IW-h8z&%^uS6d~AHA zB3dPy@0F!-gO${WFT8JRZnUTvYDh;JbezyI`f|+KYVJ|)a$}2KZU#3Te;RzU{WabvuvYOIM!FWxfr&SH{a1E!F_t=_3W20XzP#X>n?JPS;fxs(mh#db(iE6S?N?dP^?D=4h{h=V+si!;E}pbG@vI+0UIR zlEGxGx#)1?i<*QJ%+{JO=1w?ixR>X=osIj)v(LD1OT?H2OSDNb+$-j^XXM`Uat?p) zN{KfmIurIg6dgM7SAKz{fF-BT{CWGCEIT&w>`9dHAyw#IdjPx zy))NdJP_hxZ@98%wvA}Eh)vxOnbkk~(;mFgNbzQ3Uh|nThy${~ui)fiE8!QXH%zdW zT)@qFQD2+o2)ZX0fE- z+9sWqOz+<|oGV+w_`Uprl_Gaa+pd{X1!5`Uhxg82!*lA`4fh3-D_9b~x4fCLv+3cx z?&Cb!P5K5Wj5G{RR5|3ix8JSv>nVM2$CzHZK9?=t%Hzx=?HRMg?G->+%-QTlr8 zOrHLrZ$?{mo99eW7JqT3!N&N}lQh=yb6-5YCHVH&olX#7ojDU!jQ?yp^xj)6`3`Fn z=s=}<&=}Vb*)s26tFKRB+dpFkPxIDRbLao}RC(@voWL9_^XyGR#g0SI+Sx{)EiUY`iYND^tT)+E70?b^{d?^qXxrL0 zk(6mSxADz+2O7^;aonu1p!bzQD=6X1O{mK`lkj@>*$)+7+BM8pFHCfvOx}W9^350R2~{zlwy(RBa>K#x z)Glk$qA91g%>B!=Em*Mm(r;tMkfy zOZ83^ChYZ?eNogkMNk%02pCAco87;TCo^wCAKNE6!3!VvESS8`;gy(N>z6O-G7WR0 zd3IZ~sK`&^%G~0o{!vCQ=eJG5T!9O90y!%|3#w1vwPe02ur8^oc0a3G<;q1IA6Q$D z%&TJE%zfo2!`ZeO{w+N#8qAg~-YvK!P5!V=j$bvw{&v&0JT5YXzv8 z0vZ6n(|_k7NA8?g!tcwa8CmEG`HR>5vtLEB39x8EJ!mo$92m)tN%U~!etw8mKs*FR|msI!zw zTkWbf_-H-v0Grf@9f3~AKQx)G{(rYb=BUI~$=i~CD?T?K-Eg;z?{!PTV~bg^r4V*A zcC;^1IBdB<<%Nm1x}~g0>Vk6}w@OazGrO^@IE6LoQxcEDntze3`);R#-BPgS@O?TMdil+X>U_^6h5!OE-R|13VYVIKZR}l*3ZV71(S0YTD{9;>9Hv1i}DoB!N zE&`wPXWu2hO`fIfjb7D~B9?#20YyzRTe)sQPUOmnn_=_oWcY@q5tW)9laD#f74)7g zwW0K6-zpxjs0okD9o6F-4K`UPxPNZS0CigA%q}}>7%rOM$2#llf#vMiUTQ=eH6Bdl zOi|dX&9-UDlnX}MH`Gc3o-3bXFcM~eRkLKBH%oM9jn=h~?#CsT+^LZCU_3p?O44Dj zK%%cFn?PM)>n@iw0yjSHDUjVLB5>uWL);|Mr~H{)nvXDLDY(yQJ~A!NJ;vtyj#_i( z>=|ZZ=_@^%t>q_mWE$R>xLe^UXuBEc1WzlquLsf|{@OnwHFiPpx(WV=oUZX(GjeZ< zv`s7)YnGg?)x3F~wM6rkw|n|1dhYlw=hFrow&>ja z)xITL8om`Buu?Ga1+B(|9inxQ{}HF9Q>-h`7O5v}&JA);LiX=|u9(Mswqb!amkPVk z^vM0qjWcZJ4E}!LJ5_b!OVN2s%0Kf|#?xJWQ} zv*nq%89SyJZ?LVCnpAeM+JOUfP&SK+G1G2gmL+o6ell##4N>e>lQ`?Z++g#Y(OB-< z!vj|p6^~1r#=1-XlbPYODeOj&&V`d<24@$X<9HKs@8$7Z5(kRrZ;wZ-@BoIH5MIga^yofH4EieHR7 z`W;0IHLo@@PguM}R%XL;NvBVcNkPy}Y`F%7#clFD8_vEuAuikmx&JRHzc$C1c|~(m zjoI1e<=-Xi%+n1YMCCTEbq3AvzMGH`%)UujjZf>*+wj=LhEh9+#nVOY;Y(V*wdDS9vN@kdBB^gT%ZV>}(yjRtMq?T7k*g5&}}kDV>r6>Ka^ zuBnM^+8MJlRhv17+3JNw+?UB45}q|ZaR4ox5}08DT5cz&(q8x4GR6LcA6tMr^Oc_k zhEB0;~A?i4lA>q0u`W<<0xY?#Hzc4LzkVjavIr+wTl zjJyZl2_*jL+`EwTRZYQZ4Fe4Z>sqd?3DzwRvYY|O4ERyA8gA<_C^AX1PejfX^3|(>s2C zi@_PqSjdGVzZrwu>(n_sYU1xFvdx&a^R~j`Ly#?hAJ0}O?B>1lvq1YxT1CNAk!WG~Xv#)Uj@P{!o~Cjd9V6cN&M++0XFa zBJqLY!pZQNe%nB+nlDUk`qpT3@7M`}wVaj`Y&$|B>hPio2ck0-y ziIf_E4zA?c#k^#@=%tBGXFF1MiW`~4u1M_YXq>z!?(O5yjGCxtCi@aGD1((MmgsVq3> zzR+$-F1z(dt`s)V@tB`rb;!Eq@)hsfEebA4MIUEg!amy~2XtklQ-FPm7)u?G{;@Ue z%vub&A@0IS9W!H(On4}8)PaZLY>z-SJBQ&j#Dv&2&%_0a40Eem_q~+4YZY*udAjg~ zeCy*&*{*zKIN4|=54wEg-A{*iQyM@S<0f|yzg3$!Xz$8B<6wzH>P~Jv=DIuFf;v)m z=q3w14o~}W^a8{6?XNkG@R&>Mu1OP|#GbjU_OV#=sy3;vx`5}*I}bBj6^Son*!j3| z4JT;d`U1n{wHLbEK^rdK{R?o}RUvQ%a#UpU?im8pr2^ECIDODy{-n#a;2ir3=S>H> zgsy#1E}tm#$LzoiMKdv@&y2goSxUk=R!rV>jjPD;+P^-{gsY${i!|BZGB?WZ=6>`) zvbLSk>~y1? z{Nmx*<+|V;yV+^Sxm*G2OxxaM9h)X8ampdfsK)5PqZ?`N1(jOW_rls9?-u+X55BSY z{h>5FhqMNLS(jUob3GlF$8{PoSO*jdL_5wEnDG~Ki%`R~#Kw339NyP7n9V!yBwVQhyjdUwvnuRg)Rp26>N`&mEF25Se0*=Gvpwy;k6{Ic;)Wb<3rLI zG+P7Hlg#UtGjB0QMz!t{;f_>=tdK=blnk;jU@GeibCrUA(RQCq73jn;g zyAL{Tt8HY}?>N!1nXzQ68TZ0->>kRyX4zLKN&0a*R2^$cv+cWMci4fCL3U+#uB6xr zod|d4y@wZmw`y=S;n<|l3~tzhds&h@p3Gw~I!Iq!&eVV9=vB@}$em5He6MO|RNi3DuVtUNq~wKa z4A+&P9NJ!K6$Nkk4hy!O=c&E0xXdw&TT4q)tz=7c|NW!eWVll}R(xiRs=J!Nd2^pc zNOHGO95`W4)ZwwLSoF~#O<8)$vU_EW5%=$G|KUI1yPThS)ogse4{o#HOqn;&s8!LHb<-Oz6*lW>+jIYFO}cdK^U2#1YVV>>GDH_$-CCqqA;z-v zG2^VS4(4B;@p{Oy>mFu0DSMMGGU~&lFQIG^&mW()Jz>Nxs2aK9#+swt5`E{IWVSSd zPBW3+@Y^n-+Tp|5SqHux@HEAaifqP-=D+3G8oiS(w+0!CGNTeX-Dcl{O&miSlh=*R8+F6V&A zAuGiVs*&;Y7fLa{s%fxN*^n9rI#m~B(2d>~u&HCV6~av6#R>AvpLky=R9@&|@3>ZQ zMNz^Y)E@6uuzb?T^`flgLhnn{@6QY~?zM)@6I#>pi_hdY;^M@nH;i)^v08oQy18+I zA4d=Wt0^;5)0%hQ&=WuM)bqm9<_*c^j?x$MW%f0h+azpO1kV*MVW{$a*pjO*=}>gy z(+xePH(a$RHoUho`0K-$aD&CR@7CWJfo;{@3cbI4jjbgg39A_#c*nPqsk7d#^wylx zQl3+pPe1UnfLhYaz$bQW$dA8tXu&$2!vZEREkH|8H*~X4^grrk_m%4kCU*y_!VyT-=KTo|f*QB1+kdz6=z~O=jvLHO)?c}74PN-5}YkTA*Vwk6%~R`{DeqLgDq%Wo#+O zw9^yTe`fvGH@W#EciS`5=?9J_>^{wWjq{+HanPczZH?d8Gcji{Tb*Eda*pjx>;^xM zUxj-E*qN6sFoS2OHOm&3*Gr~wH@}@ZorjtA z+`5)G;uk*MILlzwC*HDmueveIqllZJJD;os<-#WXbvG6}f2_dD!`Dq`$>R-=Z^*5Q zJ6*#h_`g$)_xA6`I~y5F-6m-%96xpTwZ#F3NzT*U@9R6|Lj$O~$p=d)Nn+NZT z!;IE{xt6J0Yqck?ikImU1P!qXHq}{$m8}vzoas?L{bBSBzUC;&l=<#%;jD*ui+9XE z<2YAPku$KZ_;&I+Ec2QK*_l|ICFwf88b2 zcD6QKE6UCm7vd^wlkOK>oA%^!MWU?03`WqRH-6CItirbWtHqn!_Zl;=I1EZ_v(Fwd zz1{fEV?tymCoj+T_i;xG{$E$;e~^^lV4Tl&;PB}Q`NqeeCI%dDZscGv;+}3a`{aU8 zBAfVT%y(>fSn^+t?J;*2&wSx05_z!^#~$3A(6;F77pVt5G9L~oe*b*4pfDia#gzS0 z=YHF#EX)~MNbLeYYA967>PIVZ1v+#bX;Y1c%JTl3{3&s~t? zx#<$U^Bdc;KdBRJQZ@)|kw3CVz-Tq&?Hs<_h6@{y{#?Mv;xXffYJ|ep1+@z8%nIL2 zp2TORTG&2kXkOZ9c&B7yi6h&Em#Fv9t=Pr2MDb**c}ON6eKJXjeqQ{VoPsnC^=3dj6z=)Ou_{Z!IH zmT!Wb1n;Yw4kv46g{nlEB{pp*t94eT&Cn1!%W&&I<1PM8UNfgVDw^^4?7zc2FQzob z)bpR-NsePHLH+-^eMb*`Xi3cCJff?xuT(ANrLYH2nWZAL=z+Q6Go&9l$_fUkv)rt> z@G?Tdt|zVHL!-*=iPmx_q?YHlERnw8uvLH#*){TX6%iAM`xY;$o3Sz{Snkb*v@UFTz1wG z8Y&a{G;Pkka?r}pIlX4bw&KJRJJ4~QR#M1iASrO;4g0S7 z8%sSBj8!hbU1#(`OUt04?_TTKx&^O~gZ89OXs}XQ@K^DKvD%I=vzfvf{-)hH`XIV7 z!tCpxf68r}>`aUvIo;uTvB|%aZccM=k~GOP+r$X%mV(@sDZs2d)QipRQQG??9Rr$4_B1W2RvC zS2Z_0r4DXwv{KYN`xD$_-Yajw3L2c+yxQ zcCo!_6WH&0HrYJ?UU0OiEw;3lNA!P~;hfq(JR1GC1XxaXGw{~`cww|dSczqhB;(nR zhBv|A^E+|0=fvC|+vk183*NIcem?&vc}M*-zUHJJF6JDw7Ln@g zB5#R=&0+?%pu+Cig86-+!CZyrzm64O@Qhe5XOn2LUg6*bo?BL#O*49(-&xFIm^Z0o z4?hd!)XeQoU-nrs?yM018?t8mbp`ce&g_#0GsJ#1SS#{~=QZ9`*n8v2PbZbYCWb2? z8#wo@j6KINTk&A|CDAv20=f?rG+t~2-2(O^k>_8aL`*HZxkXV&Sii|1FkmWVy}lloQ3I zySqrMBW1>laBv=ts$+fB{H6H^zeL=DUZzqzhtsPnrp%P+ndB^)Gga~F(OtWbOD?Lf zOa4*xU7p$F?Ct3t(MxtNX_eqvy77Kl|61om4r~l}|1w@?dsWkLV}T#%itMK~j7FC^ zcBKeZ_Ot&o(uq)KULqc=>%p@`d`47qJT8_THA{6LWU+bew&8V{QO@XDj1X;c8CBGp!r?jy;UNE^*;K zQ{x9kZDG6Gh8z5|c`JWCv}4Z66g&0o3%j+)r$4d}e1Em;$);|&?0iR=HL9&O=R}bP z`xVJZzPCLBpa~bV^_=h9q`!W7tIU>}cqNc)f&}+QJy72}*NI(rH}|WU22k(lz*D=u zjnRy+Yb4@lvc&!08o|El3e%DFhIhZ&R%-6~!L{!B-4u_fth4?ql=ZWNk2Wc3bK;t^ z4#F!fM-EhVEqRmt1LrZ~O!<$O(Ks zV!@W`dg8>#b^G5-ZrkZtbq+Lh{j&Wo_ztMqUk_aKY<#KNpm&t%Y{h{i4#z(<-T1D@ zU@h-nZwT6CIJe04jNu;f{&^`EdYnYgEU30kNLzgWC!_H3Wo%arch-G3V1BV>wPx%D zC;5_BqAyf*X4rx9kGl+P;~3wq3cfJDy%_>KA2YyXt|rSdP3g)Kgaf z$loCC0Nqu|c=yW&Q47aid{uE~8DY#jg`3_OK9S^~Ayu&a$;<4vjQ0|4vghR;r#P?I z0$ob=3p9q~x0mT-Vzs5iT!9%jpdu4INl~yemLtdfw7Y|qc)YxWRMnjWid7RLj&TK) zE;-oXEq8^}@Lx}rIBP~*%a!Jf%kS45GVtUoV$uH;q#Xd-+;Cu;ZNj5^kp^d-$$kc3 z7_Id{XZxr|7}%Eg&to^9S{Sp2Z5A)1=7q}_k}_uUSoZcqO2ajm8{gR7xGS#!**s*W z+IGP2L<}1zTkeaCfuJK@>p;Wo;0dH9Y|#}5j{IGr~AGXydZ7`k7)Xs61W zV#Z7CpjOg}cgI!vUxU_5SjoQFKCk(EGef$L?4?-AxI0zn3f?O)yE1J1&YZ?!WWRJl z52M-cz~Jo@9{#)jnCD>R1l}uuZ%;e$mbG*3+-(yScUd$umX&k3{8M&bDE?%M?w6+# zJRuCAB>>Ng1>|=M8;S0)(Vi_nX?3D3ch2e64t|WKP6^u=F1F?cof{hXm&J4P_VjZs z=Q|FhSv!Ev$yPADaE6_EszaE~t2%Lk`!|nGNIV_*py$h6O&+TQGx?m(4R?8+dKDT2~cj0?IY@%lQ4cea-<9jtwA%dIK*BI5I;g-R}S4sJ4?@j^9X zroD?q(ig$qT3fD#8`SLo+w<^oqc)F%*@-#<`D1J!6U*BhtYnJ{C#V{paDTICe%06c zjHW_~-W$OixjSN2o|rvyK5Z=l>YBay?dtGu#%^;S8Jm;mv>(jvn|U#mM}cQjN7SnW z;KnL1nOFC2Z%ll@=`c^!w2rOI6zojGyCC}3c3*6LR-3oy+e)}da{kZ%7P;avu3wU>ha^glb&($ zAwxH7{+|8`>}3rz8;u`?_3W2img>ChOKC}<|GbI@liA?XLZ0K75omMqwB|4WSov1W z-^C^Q^HAAs%QZ+>+t{u@aK!ZruY`}pI>R}M7n2<3{cTv;4nCm$!qvt!ue9S%X}>3! zFK7n$-R|wJZrskS@Rr%J{Pkzu38jl*OTlt1>LhYP8fG&ez7<<7nE*N+j{!W?a^X^A zh??}ZWI0vdAYlQHo107Ca(&ZG{_?mYad}dsm7>AUse2Ffbz}%I?_{|0li~f(hI0iC z)6x!}VJfwIa!E1xEwpzI-f_N?bJord#*jB!87mFI{Z)q|18eY!k8AH9xal2k%XaVf zgzA|a@0QhNXi78h=UDQ%6*B#G`;*p$y^te(z7&AAcs+vbYG|8alVK_5u~+T3KHCkp zk_(#QM`R9HfBF~67XF}TLBEQ0MP=y4S9^J+el6I+mZ$WrQARIdOO>p1yvC!TkSCH8 zPQ;;)`{|5=u7k#h7+lRgn>^pUv6dC<Y z^Q7Oc{x^fs z>Y0t4-sVp{w4wNJR-143bc2RzskRZ{XE3U<7b$quy?b_*=j5#!iI8Rwnc zEM>byih9$VOgsZnK;q!R# zy_=`8TT$?ieL3UBI<~pfN;Tw*Cu*z^KJAw|L^S2{*3e3`J;fiNv89-I>W5D;R&bDIHVz|Iox=uV@asvFgkQZ09PZaLv;kmqs8?g_# zyEfhPtrFV~Sj+S9$lrHPYx%+Y^nk3;6F-hOEo+o6)GDZKag@3FRC381MdLj|k0w3n zbC0P}vtWT8b!E6hm?@a~)&{;;pryZ?#T=#`Oqwkld2{FF#Q%vejO2CHV-GH3ER*NR zfz29$4?ww^S}m#f#hzL3{gkAL@6W_+(%!$_b6~-fyav-{jztQbC6xi~$<`YlGfrwQ zwVP+xFo#)Vtpdx-2@KYni!SuO>Tl3Cm^Y_wjTpmQ*1`}rQ@O$^M{iw|$ZI@1VL`cv zolWDM2z7<#y`SAYk}v@GqI4QqaC>zHOsS z7V~8Ga;GT@#z!He!3nc3f)2O&*FJXwYgAI|Rt`h2zB?x?c<)T$yUowUZ7i_Am2p%5 zs%L6h&yPL(@6LAPuiS#*bsd&%;#&l555=+N*sK5@vF-&DqHjEy(D*M4rCm*F_K zzgYeE!9#A(T6s43xlfzSe%NG1(gdmFSB~=haCpLVLX7>!ChZBgl(U~1g4SZ}-EfZm z_>-4BpcW$7^z!H5e0df;E>BE5dwbsuM}bp}rFITJ(8W-E;IrAE^l_cxSykfT&~~?~ zW`3g-!u%6J7-Yv78_&D5t%VV-ai7QV(w6Ja^Ql*6 zA1p}nwQrmLT;4tQddyYB$qUyq6&=?76(?}vY4iN|_6ZH8HWPT6OPw5QZfw#KmEsheOHCeee%a&;+neRsXE#^BSe@YE z^f)7VV?M)M(Map76Ax}wV$Yj2ZMEK<+T8D{2GU!mGhbtD^n}iWy$}~@I>Yh3G?`&; z1#3|8i=UQkVwt9Fpq|oi?kgV?6qpq5PwMlv1WkWG(Y_D|>bOm?3Qw5G=?$6R z&DbK?S=2z&cd#>2HvCms;KyEcoVnJX<4n!b11xL-?TKuCejJcv@MSU-HW%&D4mfmi zlU0YJ2aAz0Uy|_z4hLD@0Cna_Y0!0Y&eQ&HIn~kl{h&JAg&pg3K3sCV;r8Wk`Bcei z>zdE>C4f4}X1{9XH=KRJW5Obo@!NhwBNurfon^ zL#fk-vpsL>dtNlmxyij#_ui44Y^(D(o^1X$A?HrR4nyfHKRv!Q$k_6|N;u%R9dzO` zs587Hc7p1Hd!vN|#v4ML*pH6I+JmMm};&WqeKD&)gqp>V# z!g+JTqXkc+;v85P2ybwBWzsPF{6u*1zG5?@)h6*Jb-(_of^YC!&oFKMSI>?jz7p$Q zlPsTnIgrETz2TbA#v}uy_Lvo%LENt@8qVnN=+W5hfA-#)4KZsu-poCj(=YMOzi9>g zN=r@=)|1cwHSt^mHSc6W3v$dC9e3{g;U3q7x)p5g00C$cW{ts7gLkw^2d z;_I$$^>Qor-uJdPV{)%DdhqSAmEw(Q;f*5DJ0O@j)a1?{IdWjZl5VBiM{-LNpUZ_F zeenA2fr8RkjBVd%%NaGK*-x+rU1qG%o5b@h0d%J9nFZnMeoXnRTRTqQtv~2+Mvi|* z+!wx6?be(;<$iw2GopF-{AJp8H}&;JU!G}OR|FqhAlbKk`};;~c^(&r3s0MOy!(}~ zK#1XNgTx8PJDqQrXwNW3DfNFP$nsw>+_O3+ND}2VpwkMQ9c2609pU6r=+R*Z9YO5! zVtI0@&pqyIK@+)Wu61}<)1Y$Ur-I>y&dA@5$G0`zIGW+T!OreVN`Ofb>*I_UJRG2j zvS*Fo8V~f{Wqr%a_?DTmv)OMi)4Y{z-{p#qGnSlG_yoIsjfdss->v_pZ{(P{pSjDt z!S}_6bL~wtrJW!C$>j-ZoA9#eLT1DX(6u!4nt7Vveg}D&Lkjl1_G(+}AuAWw*cHC15D@Lh8!t2d08XE0|tQF^GwAH~4VT zT7JRg^`AB?@Unwf#S|8ORNGN`===UA|9wrIpuN(y@(MZ0tTQ(<j|t78RxDZQJ&kf0l6gZIxgw!(+m<;9UDk z#w8nDYt%VjNW|S(`$F@s6Zl}#r;#U4ZzVKcnt~k*>h(8%v{F{_xHE+OWE^Jz^QltD1(stF0$pU7f#OXgu<%!F*oxwD86& z3A>j}nDOD**8R+}`oCUA=&@epxj#V!)R*{Pz2JP!fho%KCw%?B--Nke=$T~Nf^+Sk z6Hhd%EtoScQ=9i1pHOjM^O+OPN4Ckk*j5UZ@Z>)-^pFXOHC8)>y*% zu3!#hnbD40k`LzcmsGYr7M8HMYatmSTW?VCbf!Up&W_^?o-^L``TbAx$q^OD%*YKl zmagkf`2S$i{td}&JA|8Telv12fNpAQXPIp^p=yT3it<}eYv(Skf9A)wGkn74L%IpF zlYUQcoXgMF#u9wurR$0EriQ+UZ+9*`De#@M=-9p)t(IPh2?U=;H4Q=cXoJx?Hdiuk+f4ps?niJX#KqHxIUpCw* zY76ZaT)c17Cn=r0=L6vIX9~ntbf*L zwo8H*$)$m=5WB_+y72T0D3zNfd^=>NxFg-IZn8*8VyCx6!e;pwQjW*p9y&6i z{~_yL_NG1ZEKAsqwDYdFneZ%0!0=+j`LY9N9PH+aA6d8Eb?uG|@7WJN6?}4eHeKuGzs_;*8n704#7Y674YU$<& zwl9KAUU=P~a88cx33vqdN$+#{ck+%KnXi0gINO$T)!|gqh0cftwF*mGSTmS+w``G& z;Vx2VE|JmC@Vxd@dbuQzPeUpTzkPGpK3R!)3uc*8mN?;{+4GKVc>E~1!{)@4c!9+Z zpH7&hF*L)QL)2C?Qec=;-CH#y!s-4dmUpL&dv$Ek~!2uPv3xDN#Dh^z_ zD}7*7@ph*^Ro`!Ha(;^yPdIQU2tP^t(A~nb$LSqQVUj_!-f5@(0Rm;m*<0YQgDGJgp-f~wCHq0#$T`>K~0(I7zQ+IxO z!*aOIdqV2l7qV02ch2Ndy3ohA<}>4F?h^kKcRwFEcdFLKmhDwXhmU8QwYs;JXq}MQ zFCGqNR)(@CdM7xZ^s#T6_<)b&O^LSl35Y|CWgGq5!_#Op6%d$V2K3R<-3Mfid~0-c=9F}J&+ZcQ46x;d)09#=sYpYKe{J_Ze-v>lu4npspjEQsr;lVs|JlR|KQ=Wo zZs|BagE2^8{ks{56>PWn9@MsEduMZD-UMqNFP`sd4pK*NSV`}&QshZ#(2Ny+u*+e2 z(!n(6gr*HM`JCJyTgiIgyDH?W-N8SL*HKKx-BNN4P>pOpcFf9)RU0Gtb+21J^hkbx&8F`Ouws=&@EC(@nEB%W8q%HQ%4cz-FiYLEDUNyL@?1 z^c;S0dbhp+&*Y}dt0mNCIK3+HUZNWDLMm~yqQXbd;sviRerx)2|IfjOI}a=BDlP9w ze6e;+5V~=t;Y>rR(}ezqYvVUfIXI)S_u*~n6B%3WKj^hG?bc&syKq7|gGp@1vGhY1 zGYhOOe_oZ~TC@4VA1_ONwh4bYt54L1Y`7`#rB=>>cf(BqiN81Fx)`_JlyOncw_$(T zIJb{A>G34?T$lDzhlFnm=c^X9TYusVH`w`VnkUZ&J~n2~2GA-75udY5%RHE)RQ#|lMOtD8*kMK`^=wNDx$+*EVSbD#^f?=4w8J16JxSX|@y07amTta$s9rZkI4k@q88NMvvIDxgRy! zK=)nj*YP~Ka6pIq)x`GutV}}M6VIl+ zSaT-X;`awL&!1QB^Ip8lu<^Zp^{E9Ma~Kph%NZI{JzA!2rZ+UN*2iw0pn}z?=*g%W|;NyK$+3C z)6x@ut2;oaU>)DpG~D@6z`AH5=%zP5ZqTuFliLr3COf77PvA8RSk8QnGjRdagX?VX zOnw|c&~WGHjymDbOJr^Ytyy$;~x+C9c3zYN+=Re3o)$7cD9PFT@(D!SYF|?qb&E6-lqz7 zRq8DBr2^ES%$x(%G5<}`xo~m! ziMc$`Bd_`k4HY*uH+l1}5H2z%@J@QjYf@gpj{MFIzJM^Bi1X~I)~p9YwaB3<$ls6vWne^*#=RwJ;KYAG_ zMLCQE7#w8zKsT_ltoi)$gXI$i=1R}Xg7y~HE&YuT%@;Yal)7Db%hLJveCr$`2CIu* zjf|IWu$J066lMC=@ofC;e|W2H)ehk^(BKC#csurIr(Q`VnsU#!$@#_v zYNYdA^gmuzoU8>JH}jXzkoWi%pSo({yY-BvPTSVCuDQwvxtzt7_d`nfxmy}-+sy^qRXMU1-c|pw zT-vIrB_DJFx;r$00W`mEdRk2{dB=f-^9h184lAr#aj-x)Rc;S66SvNjbH`s#pTHFz z5+io!p~XglNA?lVS)BhR@Eu-gn=N5erf{ut-B*X43Cx}Kbp_KCbK8`eKkb{qdiS)X zNwB~xC;h30G4qR?7M?rS`|#h-aGvh{aS0cg=Dl$8QfhwtyP?!2WvPn9yV(rauQ^Sh z(QF0oKlici<73|x?U0uEx9;!iz_AY}I*kq9)gDQZ=3i+s;XO;^-5$POf_HZd2>pjnx2F7PJ${Pk)3pv8rhOp- znU5_y`tNZbT+Vid^JZ<5WwZ8b&T~uHZn1xAbd;#tqsPpg5p4PCSkVNx6Bl<2C>NZZ z&pxlG^z~gcHvR1A4Ne!B9$LFAF1J;@U&dF=k@48FgEy*(brEP=$DO6p*Ci4j@uVMsk`c*Gm8 z=xl91^Q`GxPeQTL8y1}l%SyiVzErTZeQ+{jxsHm&wsUWj1riGmzRV7Iu6&Di(!7c9 zSsdq7weEV)d}Sj;snR)}7M=$gzZ2!|as?Ha3a3c+d)j<^e8H(WNg}K|)Ii}ruhMEQ zew#A!7an~WN z?)M5%XHoh8TK3S=?s7+~zy*CA+x$4**LptS44?3c39%`?bH@{ZM*m}74|g>h_c_i5 z-y*=}_}fvbQC1+po%za1hig2qYZ{JhIC)&_dBRriZTu`dlNn$2957pPf9}h3LmN{8q z!9D5VeTMHT(uQ{FKe)g0cJNM0Phbe$abTj4Fnin4^y!D6O0HlLxi6obvEKdNlbVDX zrBB(J-(L)4yYMp7&FQ+trAdL-j+>voOZl;+<%S0T?Hs;WB@N#y6|8fg*S$z9c8^`7 z$2Pa7Rp+Bzm5;31QRw9k?7J2S%+zPU!+*%&07Hq9*qYCbx3;`vu~{U(SD5KljY7GF zpL72mR!dpXxvk}(b(R-v9~(IzurFf^L3C6N5 zlZ>`q-Wc}nTw+746$fOB_r#pc<6*`PeUDimN-dCj;>WSccK7$Vl!C9T*tuukRxy&8 z?QXQ>>n=mkp~pP0S`=2dpD$Tp`K@)b9eC5h<+T(1k21}zVztT>UvjnLvJ$ufwVmlb z!^ZR6s}7vq zkbG9Ff}JIeVa;d8N6nC+s{|EiHXeLC7c*T3?ftmYdE-5&ruErn=MQvvO_&utb3*C! zzT4$S6S#gnm64cWEn_~xY>sld&4jby?FH^^7a}d@OU`3Tzxe*PgO*LIsfW7g70$+) zjJsL{wurnwEOg=@f6iRq2z8b%|CzTj%9flGH3XdkuxS5|^0|y#_*(*wKfd^Pbwc_{ z&8%czD^RTn+A=47!_oa+(-Vi1XVO=WN#$sY6&+`~BH36P(zktGGU!f;#qY%%Z|+|H zjIVjU+$&Gt+4{1H1(|_~45eOY{PrZ=uzbo=@LuR0AIFPj#S!c*X?pu^Uxckj;&?Hw zWJ2AAGi)Awk#e>BIXvbroGZ!95w7Xpyp~n=D0fnWm11Q3E6F0sMG_}iPlp#7SR7+w ze`}}cQ{b(gxIskZaJI^dWX9dsnU@IsbaI;EHbLqJYs&&Y_KkTgr7j7Z6%A|`sD_`A z?VCGWkk=11j35i@Y(+51d_Q=dlW`^^_?#W{B4@3W2f1%aZ*pEQ>MH-@S#ix=jtNNt z$D1WiPsk6nzf{Y7>F0y_M;mIyJt9KHZ)iLT-smv8+7PyACT>|c0*JK~sa`@IrAo3+``Pv!D7WySGuuf8nt z=Ml5Sox^(r-Y}iakJ{15xP_hNiX-F0%-Pe88~Q%6zGXB#+3@BntL{;uKfh(|J~JAz zT=`jW-SN$5#!{p^L0(+ZzA$mG!r$Hl%=Mt7q3%^Z*6>niv2}>Jk|O$WF8_oli^V5& z1^GE~-g(GS>g4cf!8y*3d%SOJ8g6{Q=j1kXYK!PW*-1y!PfI#z|4^9A&&HPXiKl2v zZc$66!-G>^70(}ClRYs>!&FprgT#u-i8J1|yVo)85oU^>CVGWKYU#D44O4dRiU6#HRG@4deN?1K*kglzAJi`_4fIt2*)Pn{>Vy7}d8#+%os& zGm7GhZetCey+rh=!TVcA2I9Bl1fJ~lht`(zwj$ zb9eHF-Hp}u%%6HVGV(t@o;@KlJ+joZpq=>+C*v&US2YbXt-f*BugqC^P{`;~e=cVj z^M^|(QW86CHhOQ^uvGuXJ^m+stSgL}ZZD|If5-$rk?&WXV9m>KzZU;KFq8j?j@SzD z9kxf@-?uynW`5P;b8Bax;*Ed?$B!qH+iZI#q^`J;XFc8ebDyIh^Y2eV5$!Bjemd*} zuVebOGGf6wwl_QOwsvm^omZp4vyZvuE%)Jz+$&BWaQI$3BdWsq0@nd6xfjopcfXa1 zYcJubM>r9`>Xtu#ocG6kX4!@52J(`DCuioLy_Li|wtLe?(1KU`* zmk5JSCsPBR0<=TE%)2U7;z< zz4$?KwhcE0Cd|5OJX;dn;yI1H!~N-Of5Vcf&kuXs=44;xSrFO#n_b~_gQ)C=`<%_b zahiI42a^L$nIa^WfEp%S;|}Dv7IDS3VBxd)QiP=fDNdEjL9{DkGjVsepGkoyaOY*=)9SalQ|` z>|O3#bN)rW5oq4Gm76(dvt@_d{R%$ozg-Wxo``TpJZDZZ@8EsaqOhBJy3Gp}of|77 zKuZ@>)*ODVW+Y-Hz`rC#&|CbTv5m?K!5S^G4>dIx-mq_*ywPLBEXSBjGatVCyq6~} z$6rE&m4BWSmj`PmXB&sVdYfqPTaCFB?iz11kYIY8b~^ORZ+{0_?f~_qMLmW$I4@R* zC0Vd8Nn7b{5n=QHWaJvZt>ukxOc^f9g-zgN0!^E;fllh^yQ?Z9w!rU1iKO_X<}=n; z=O(^>Gxx!{cGn`yuDT0BIx%eb_A*9tuUgYstE*vF`C8IDu!mW9XA|chyTTccR}M{k zqrqNkcjubZG~R#g=O%@`aO4WUu!fCe{hdACj7!p9-jdrPyI^Vf3$eQWe3}B5rb{KA z_P=iG4`qRL@0O*7|BYgsFi$?<@OjyJ=M$dw?2MG#vj1=>Ls6mBr%l>UjSY7s8CTkB ziXUK@^>xRw0)8Lu2R9bv6@C^z%=IExVL@v2g3Ft>oo_nhW%1k9;KojNqdhg>IPz>) z7#s1fk}DI@-*nqyd2-_q?{{B~4_JvS*nuKK<8K1vyUon=9()yCv@lni)4soBl zM>-cC@TM@Rr#-7&6PMp`FNQy=&((|RVA*ZUU3H);(RgCMr@EW%iqDL%T-MCwzPW_M zs!u#t-s9}MQV;hpj|?PCm=~Q<=nfUTqR4pk#-fT7b*>jY!&~mKzpiO8Ticvw{wUqa zY-RJ8LtmP&$XJ%K=UrKS-iGIdvBCyl(8`PL^OgN}-G0FQl0)0j;S=|o#|)d~{xUgz zNsah%rRhua_X!NQqZe3)uC+T-Bo^TA!j?Pb|JBfP(9JIk9#^!s8d%pY@Z zgN2i;8H_kMZl7j+ZP6gopeN}9zxTIpLR`w<1(Ez&uBY4C^CehBTn@B8{c&y1v zKB3&cp`b9=lA@_ab5tp-yy=ANS2(T@^X)fUu{3*~W>+76O9;KBN4(>6( z@r2(eCF0$NS&fv0tT9H)Wd^+pg;@(^FOMG9PkKE%<2j=!x=; zy^0I`PR6%Ah751Z8E8M0Gurz!zO!UHf&qtJ-Ko2Dy1EZ*H)?<#IT$ycJ(-P)InT? z>z(yMhT9E%khZ*}#5Us(_Za7$D12|>+Q{^}rh$hMbmF;y^cMLeXLML{wiz7`ZS!|; zv`u5YGE?+MkPf6mo2AK^X>-kTD(n!*CGQ@{9jS`Hv2o9ms#Pk=%@40$@qsjt3y;~a{A7?nc)F#w|N7K@%oEPB2R#0IdxG2CWvfgg zc&>2%-0@Yd&4yX@z?skmUlyKGV7hD8a;K0X)~KU~5qevfAM?xB(uq8UIUenmjN3%G zYreCG2wah5ls(D)D9&=TOiiTXCYxV%f)jRiZ*Q!&Z>TuT=wZcpm$^yKM@oFAYlUCS)fTvf;Dz;Yj8ab`p?-cy>$+f4EzlrL5iKm~k#!&EYui?4#htt+5UrHCos9 zx?4*)xPNQ<(^JFpK80Pk?S|@v-jg@-tlLYSHt4Qrn#uaA0m9gSTUAN)kF zEbcAOpL65@YpiCeW6#usq7^-s8SGjd-C3f>4No{zts~S~BJZ+iJZDx(`zF6@x~Np| z30d|FNVl;W{l0GP$L7qfzTxVE#}%ofS09{XD7BLjQrLWO!R@mX@3PP4b$l1mV5Pi3 zxzh2K+1l7c(5=*m9FjL&zBTLNyDR2Afi~ij8%k{)t|bdY_9bw(o5?0|K)#RxoFjgbH@+go^X({GSqj&jaN5?54s()QkVF2!0(joS9cyQ z^QSAsRxOa^pOF~;kKwg@f_%vI_?ZuFOMaVYxHZr4eZDq&n!wX#od>u}9II^-W?v}G zJoKVr&dxfXHP>7we^8sXm|tOb%39G4_osCG%3b;CaBmLZqh>3`=kZSrUP%5pe3$c8 zjRNSP%)(M9KADy`R|_^A-xuCI!6rkVBj>SIhCas`!4uU^4s-b@SnLQE;>+P%dnI*7 z>y@7s|GA8^lr@&IzAH$PZOy59D-c=`May8dY5svA0UBPzvXzJ^R=)IK^8mt>4`JbHQP&Jlc;QMkxYUBn! zu1&uk)Ke5cJI>{qA(8Q){a37l!oG`n9_j0A9;sBYv!t;h4xY-e_gKBzrnzU9QgeQl z$PQs8cAJCzN7!Cg7IAO7Bdq4XLb&OTc!2tm($n^B9$ORGuJa!Jz{lakyHB|sJa95W z?t*9Jyb2|8v)hcpOuIk+xvTBM{^U>Gi7(q18Yl6C#tfjlrmiWRHV$B1(tbBJL$~RT zIQl-AyOstYJt`mcFg{^$Y+LO9OVWi^LAvz*o&6^ga+|HL^Gp&CbeUtt23qXz`y~33 zW_VRp!n)9S3e(P`jn)zlKb@cpD6fso}X>^vX?yV6Lc6(zBY6^ce-8n zGWRXvrn9^Yq%TiA>L}a)`T9A-h7G&cX*Wx3v0$Cs_4V6xbG9dZ>_6`DuSf%RzCl+n zol#gO%w$z1ZuYzJT^Z8a^$C#%g(rA8m=FIvKB2E~;ToxPE1E!UPC4Uyi57f&dGG4v zvNq4W$knk={r7`kj>ZZ%tmG6}L8leTosboB`X%qMJZ8T0dyh#|uCjpc&*||?SXIz^ zZ()nxe1@m+^Na4V z2C?pCXDQRVwoY=kWP+@~1iPH=GZ$M+f|uvoRDYV#7y;coUG_`#1W(MT1y7^48c&v- z_VY|?z_~V=tKIvKaNXoZnJueIR8QIY;2yOhnGCzV(4 zt@)%hV|8}l-xRl;Pl3`!k~v!^NuHYK+?UJ0z2QsE{^GxB8jQSp+zL6MwRtudR9jB` zc5s+3sI;4P*|$IWZa+TmTENH7p}gAJu1b8i%?{>6+8^gRI{jA^FgBjC(|KB%PTa;$ zM?WT`u6~{R$(s(Au?0L&zMECOL3;A#_=i2|pkr#JHz^2j3OuuaS##qwhMkWYH?d#& zS>S%FhVPMbxl>seqj{WN^PEB+#0raOkjq(1?e>&8_RXl~pVCn3mXKwX{w9r~b8Y=M zMrDhzc&9as-QQIxXdhX|cEymf)ajhTzO)S&oP8!Yn=RS=e?n5moSkzY7HXutY+t0E zQpvpLF@upb^1{V0&0q2o8s-SF+?v4mx~JynkIp9=_FqMI9r2#ut#Zre>k`Qed=w=rUkQ&Y$Y3%-yN`h`TE-V^a;E^DGa$b^*kxnwT#!Q;`5AWoN{>g z&0(5*na+!nHP@rR8NHdo6zRTl8pF*u-k#5!0}>LVlUQH1%-P-aw?%ly55ZhLwzsvV zJW*B?CiUDH4IHiNZ!S50*=;Yu zCdhEMp(8>gxl|BkPs@xSd2LsDeu;0DJkr2yynv5=$K->{dEVFTY2v%1aC$QrhtUH4 z!%pu~8uV0L_OB5*(w_S}zT&??^BmbHPN&xED;j&01RS7Q(xZy+S4C;C5s;Me7Y;IP`aRx_0zFp(D}(t{=6%MgQU$n7gh$! zF@G}L6a8H`?L%7Q91YP8M`tN+;l6a?K-neHGka0e{I3M{6kVS+M=hB@iBxb+^ZsPr z_RQzRzrI^95Au9x)sb`wc_MKwWo_~W&X-9Kgbvy6;+_TS{%>*KFt>!Y*#6Bv{u^=v zH_}Q#gO}6-#UVbef@sBa!8RKDjw$e5S zwv@^oL(W^bKR#o4H~FB%3yzp{=Wn-n7&-Lqw%eU+<-FrZ^#<;+nEhuMZZ+^dQYbe| zIM-b2RB*OOr}{?+34)ye4V*sXfPO)8vJ@I!#vcWpxuub6(69&bs~Q-pMA$GI5SIpBXnZmz3zg zI98(mIbz3F&<3=>%UDiyf{tZEPBlfZgg!7Z*@oP2OmlEhT3{=)AvF}zP%Ajw(_p2z z;r4}#hxyg)bggGImhk9%$X(%Vls(S<=zI+09s@(x())+ES++}FQdW4q(|(hE!Unce ztJ59dr7*6%W0r1tIQqdfy)TnDI6P~d7JtwTy0J6vf?LT29*&%EkG~n7=wK;&{#dXi zc$rLrt;q^!rdKHqZ<dFz91H1cGH~>tGD~kJDyrM%FX|nG z?rNuZ2@@7cUwO$ex9aNE-F$0!xA?P^uyg!aHz70n;aq_UOWv*P*)k5Bhi;8CMm6Q zSrdBK8*e+40A4t)ou*)=xcaoh=?hM8=Rog}0Nr|K?KrnzAlaQQi7`Xi$|JW}ZABvc zo!6yO)peIy&($4x$G|9ioZE^sJ6>MpZiAK54l70I-OSOT4TQ%&i@u%GyQs-Z{>1Fd zjx|sGI)a|ZwXL?Wl3XA;;qA-`fAv6tu~Qr=Fxo>`82-7}&$j+6kNAA0X(s3Ub{*RA z_Ek=svJV^2pY-&`wGR8w%BXO>Zg~(D#|pZJb&Y`9yft5DKNKsFmj;cv7w%RlHlNmJ z+|c)!^*-~a=Q=<51SVLlSloDzld)4V-_Jda`Bh7Vh=qZLs+vK?%iE39Q#6lvFHmv6 z;lsYrglm>0=gOX@ayz;B_AeGGrcVzh%@l5Y{id;ykT*v!_X=Sl=xM5C2 z=vju_Ied#Qn$J^~-`nl|PwYd@^T$0M$y}}`n{qO9?JfD_2h8m0$Dt zkORw#c+>ueeFElwQz0IF!pCV=s^FaX=zjfzbC`E_ALYJf={TLe)M?r7H^~gK0UXw%-Rb9prht1Oiu1czU*$CPyonDxG>WFIp9!uF0LB%5VC+}u`<CKi^Nh~K7Ii#aze=`w&pUfI>CzJi*%$aeRp7bIe(SO0nra6~_sV?U zVZWnHu`V4o;v8$58*8-0UVJMCO&3{9^Q#*)SZSO*B#E?O>vSpeRm z;Sk0RSrStsbZzq7^%8YE_9tH0+;FC-;l=aak&W9Iw;P_A;kF=x9eif~q)W2=)7s~D znJzC;WcJ}%CJ0)%i%E_(Cw zb=Hw*@0+e~xWBzsTIE%ziztuca0{`#ka?Jo}Xu2?_ywb_?17b z&EYb=q3(hd&xN$ozm-pU#17o#3t&GSzk2G!D)~eGr4-(hzoemtj2F;${j9a z{e4j9Czi~r z3|o4P)$6e`v)w4%^TK=0gu8sZ zg;}=!XWk+>x3N+1X!U|V)(kV11uU1^*xoWaez*7VtU-9zdM9+hFgD z^11^@K*|~4wB#f?lo6dY%|wv(Z=@!c=b-j1Nn&n+KCSYF7CXxlZ5 z=eB-8`m9pBl9i#6pOw}a@p3j)e-AV%Ll%$y_GW^}56Oir_Ci#-5{>7P&9Ldz|szOW9pxxQB15ZE| zmPh9M$hN(+8_Gp%@1hxKK%?C#SJYz(D#T19^(_4XvBCscfHWIV!NYLeh~ z&`N&8UAv(filO=gZ}E5#G%8bDXPNd0;l!RKdMpu2rx zZ*r*Vo9UO5Cbz>cR9*dduD1WjbC*n=ouBWNHl^k2#{O@KlRSGCDLvrhTrpXZ z<;5h7{HupT#mX^Lzd1rr};gO{a?s+mzcDI-1HaX4sdGeM9 zEoP499}CX82Uw)UFWGRxux*jfiFwkXgJZuOMnA6jYDuna^Brb+wr6wGB~1RvO73I$ zZNqt5O48xDUCgbDj)SX?w<<1YFJyWulJK0xWHqA^bIEPX6_*?Dd~~?4&lIG-iR02s z=2E9R*(d21itJX6@AyDxyaYUFUUOf{O!(uBMI{WNlPKpm^Duo(oGZY_)%d479+q#E zFTVfNa9sLBofa`^mXpU?;+Y|j%7L=mmb3o11CcZKt`C0s+sHqp~$` zczk&pX<*(mwIaC$bl{)&+{)7r=J3q)WCpju=FRV!k;;5hmvLU7Y9`0W@1H+U=xtqa z_GRqqJi`VnF`fgQhf)$x7*0*FyP&vXx3i7Yp#Y_qpI%PpS#7p1okN(9rF;JVI##{> z6)Tz3guw@p*%#(2#^k%6%k2_khHRP6VFXR#RhXQccaGr@m)<`U|DFZ43c8aOkB21B z{<-5H%O*?dZTFd>`}kqU?#MB}yvwrB+`UcF)w(nBT&RaF%dEFQX5T!^uxO&Stb%Rr zn&5+pOptS{eR$t2xO>*RFJW(mK;>u46~;|>I2lXhSe_hxSjhOQhU0|ux05x@Wd;tv z9rR9H7#{dmeZWdy!E%Dyg}90Q{O1id82dB!?-rhz-WgfM8f?6k`O>nDn|}39QOnp~ zCw=WFLnLI=bf=&i|Ern@Z9oIY)knu`gNF5TcefXC9Zu#}V{5%(!**?{@PSV! zo;5tFcNbqE!D}tbeJ7Cd-Twy9dG|}%&X|-KAABW}^J&4k_Pb^$4EHWju1J)c&i>i3 zWtG#n2MuO(7w6l6Zi<=xXL&lEN9>#s+4Y*P;?v0d0JcVb@qnUV)xl5T7_a-Z!8Q7E^I+t*O?>!|9I1G1A& z?pE|>JPA6V{wG7JQqFS6s!803)01{EE>WvXwTh4_OSamzDBFC!VaCej{UTf{>_PqB zaw_cL3=rjZGhwl#_vQ<48CG&~G@Hn+pF6wDbdAIDk4+ywe(U663;)MpEk5Dpq1*C` z+0R3MUOkvpyh`zMxMox&&(}ZaCBB3zs>eW@CZMtWO#;*Z{N8+B;+{cF3d7u%*0YK8 z-`g{AH^1Y)S^P+)dEW$`=C`UZcIsZ}W=oW1pWpz= z^{oEPSj3-W23gVCkY?)eX~E($@PXUET^(Lcm>ze~O8JDb+=9JwOnDt=ofPa=2s2sr ziI?qXe=$Wnsqdk!L9I3OiyyIHdY^B&yx!p*~Cdv?vVYup)vHbqH^1U$o|I% zu5c|1w35Hj!Tk1rLoVnTvewrsI!}@-9KSadoOb^9oSR&vGZ=hAL`lbgg3+lJBkszoMdzo(4JX^%*Dmg{!>GwL_Y?NilN zJ7=(Z7vq{GZ=Y0FrTDi6^cT$emT_u@;Ts#Co9r!!ldKj(h96426CQn<_J`-<{z(Te z$#5m{XzEQkCh%#l!m3HLcos-s^yRKS@CxN5n&MfB+|10kj)2Ou*-stf=dl(SJC(~G zUX;06Vw-H$L4{Na1~Il$gLP{f-_$bdo@6RDaS%FxE<1v@NrJ6X!x<<96M+O z$b0rPTwkmm6CSl(X|NJo;ODX}Tq?r*>y|2>@a8L9(oCCZ>K5N6uVD|`37L7}#MaZdv03D3kAYoiZ8NMn9!&}5}J>(qqZJ}PS! zzI#L3sqAMf7DO-5(mT{}hm-Lx>nHV?c@OW-ea^FmDSWeH@Y7qtt`g5u6uAm(oliWS zr10zM_va7Jv7g{ozaM6(^TPgE!s~U1J}_BKQeUCrD7yThmDB>r1$>{kH<(RHlHcmQ z@2$-AWKe5IrmLpg%Exw(@gz1&#V7C9B(Q;Q`TO}m((?oZ^9vE3FYti~=wjtJys!Jg zcT?JASLq)XR`Ynxw)1i0o3sme6%6crc$Wkh&1byES^52ihVy5ZE8Tkh@8%uV7bTuS1l9?&o~CWo z`cnzDZw;Nhcwg1ETDpfBWLPL$-K+DPFmsykZ!@EYzI(1^1{rKDprd-&phxvMdHkZ&Vw@-s}mB1vsLGOy7T78^qocm3=8%uZkW9BnxFGq z&>300w-q+e3jEk{6BOlTBJaC*cidYN-KNj{Vn*DAsgMqjqp{oxSspeahBe8Jxs{?P zB%a*9G_kj}RL>y^ltG-jY&Jz*uoH+(WLwqbG*S4&O#TT6VKXzgkG8zXx**FM-PH;{ z#ob~1g61oEp!LL%+fiF0`e)_lq%gb}Vv4iq$W`8@_`06$#wTsaa_~JWuelPVBNM=t zb8|uX)yg*i|ILzm4BuN`In6n=;q`SNwi~(6V~=k)-tltT;u(8h8>O(Nh+SgU`?1Dt zpX%HzA`PI68jV4T{7mcJN%thVGCic%&OLLWfc5{(YwoTV5?_uAY&Kia*D7-fX(B1< zO~m1ZgGWyon93SW-dyxFu+2GU!evp1q!ZFt4jLbbl13I^MaT=XwdR_CNh+)O&jlbCBnb&+? zX!}#IS?0@+SjZK2pxXD@!%6jDeh3~uwmyGj6z6W$*n1*{vo1X=pI|y=!(N#avg}W| z*&Nvxf#;2u$fZ1sYdfE?{eT~MtDt&vE=!q`Skjc20)}*5H z$1zFK=j4NGJ0_Dg66<0eWmI`@*YLf{SWxcdkaS}9W$-zW&%f&@|0w8gK6p>mNb1ig z%O_!3g`T1tZXE3VEMezg&RTBgP~Ldu-ut$8(-of?cO8{cV~7r76=FVHc3@g$qn>KZ z%Ep!MkO{$i{7gaIkL73oZa=6c`9FexMe@a}7k16DMo*UL`GqR8U9h;eaA&sUG?m*8 zYwgY+ILsi_zLWV#pW~$T1q?SVtqgoV@~41SW4l4OdAtCh)q2IzN@0O=dEzrrhaYqf z@U_f?*Ek*Hr-|lpM9Tg8a@D&{H|G$jTl-@LY&}bYN~W&-Qr7 zw1uHZMGnYLvaAj_`0#SUyqs-S>;(xN9kRL156u_suP&OMXkWs{0y>?`9P?J8TOD<8 zuBozJ;GBJNH=nV@4o9o`FT6MCeX&nA5NJFhxSNGL1#}zNr;WQmex5A}N~e=<3ctu~ zD9^u_6c84k{9)7Ngc(=4UtXvToo$@4^L_G*jm>kqTJK0U&g2!czQPx{{@v^Y1!;;Y zTUj%htu`)?gB-T=m2dTd7vPmKr6w0ZcgV(MIn14KH)*%zsh@8*u(Rv4H`{Ds7K&k$ zWQ?@_%hB8^_l)7-#pVgj7Hi&alt19;A-6^T$!xon${)YFg(V$+J0?^+eKTH?PLCB{!&Q1y%5d7FMpKr`bOu5+im z5??)g%CliOY<`j#*M6sZ>AID@k5Veu za_sv4_@`=Q#q&out4~OUX*!y2xFJ=b{+P|La>7c*td2Na&;cHbioa4@73?aGvu?Qi z)$5P)lNYfoE<4P=bkTfSbKkSpT)*~G8HZDj(|MHMe{_g%YxURlu=mjS*?%JY!PCN< zw|IiLO*h)XZ2a!v@@mOCjl1a`pT8vjIP#%M@l4?ChcCRYeEq)Q9Qz7k!}Y91&ngpc z3HF#U25qhrTOv3yx+l?>5}P)hYtPhMapHyLXFgw?D&wn`icPZ;rq&CbKh*Hr$Z10225+v_4s){-Vms?V2UT`(Ivcn(G^Uv) zY?gj8>4w>w=Dzz^FEyCRIligjJ&`D|;kUztvkawntNtp8YQ8Zmi7{jY9gqfY?Z)PA zPSX6NC-B)_S|ab6!?fB4E1nZ`1t-`A9A{E76FnZs4?4?R+G>}rLE&^C%eLbl;h&rJ z6ho36-cA7ZQ17+zG#)oiV@z>n=jPQ-JT**0q?JNbCc+gU8?+?Qt86?7rTW7$sm z!zKPFJejQGF;Z z_vZ0}AIjDR&zKFZ8KLSgS}Xnl^{DIG(+s|7Ie&Z5V5PLckE3Y8(P@s;ev7_vnwDf) zBx(FZzd=WLmmJ$3V>O;l&)teERp68SjXCNoJ_`m(9DOibkVR}-AoDcI1KOL`<=;G+ z5XyG*&ws{>2W-)67@0o>MES(=I(H_CRalBKb1pDtFuK9f0-^kSXYLB%|hZhwp6yvN;FNxfiG{*;ij7 zT$HtV&n^jO51uQWi43QV|0FHoXwXw;nOnnZ%yQ+ULdt>@->>t8icJXaxR!G|EyCox za`SHeB?mj9iMb5C&v*gv>kWP!yZ)Y-+dtc1;djiHRFQ+SeJi~k%C!`&$Xc;CmB;NghS>761 zz9$<%&0Oho+uz$9DtP}$c1l9k|39)Hnw+HBZUn7f8M%_@=GY(8t=tD{uz71xt_75Opq}%RWP<`JpMiJyJ^CU8++LA zao*hd-;CM#zCT+|!e6Nqy8jpal`CJrw@LqS(@NI6e;H^0WaxyA|9i*0Pe6GoRJ%+cANv9PJGPQ<8+vFtn8(SGx#)*B+L~qsSHqms#M^_^ixGA<^SO$ z;s$rpJSx~ETbUr4I4bY!-(SIP{JZrG72Y#5b}EC$BOWha-P);Kt~TN3f^!}oiAE7O zXZ_pBqhOg*`Q@(yk4w{P>q8PTPZeHYaFperVD@R&^lFcEb1S z6~Y((OWe?(y7i#VVLs5o!RJ^{ID%vSjYZ6-CwC^*{l1nvB{f2!+AqyFb;s{-lFqy} zJ(G4EV4YjjdgmZRsgA?kj%#Wstk`eVDx6r>c;(DI#*@c4^l{tWc9`35An)<~@j>Ae z84H_wSeQNDe7Lk2e4ufF`lA3@mHQIu*ApaogNnxjD%m+85A66 z&N#QWe}Zt?l^>~+4oRSMiavsl_X%4xzwhcU$xUX`B`o?y>QDacGv@KKS7^3exN?Hg z*N3?$9H#AACC2QrCf)3Vi*p>?Bv5}LyHXU|>rI$Zad6ej2ek@2blA>zG*~H~__QFB zKV{$X|NK0e>*9E_#eyn?jjja1`s7TrG#NE-?poChn{9ixZ?oBHiKeLvi(fAAeV(r8 zIL-W^mApbJD9jEyxH9Z|&pf+uLvqE>nlK|4O@~uvmaK_v0&R0USTC{PI?edH;lLT_ zfySV{?lTib-t}A$-*ArALlC@LD_cRu|Ez)Vov>31v->3+m`imgn9pne@nWt(4XEwp z8<#HeNiT{aea(F1gxzmt?*3iS$8Kgn^Ja?CnYXPv?nlZ{PkO&wGh;`HkAAb@hN$}T z|7wS;-9p&{o;!!g2Q6#LxM*`CZex~=_XdY&`{r#C%&}Ra+_V~WOy$jzRP}=^n9Cg; z=JKD|E1$2?l?^&t&Yh+98FLzAj7)^vzDvJ4lJr-6Zrt-z=7{^dmNPSU_A4sOPTDvj z-9DiWl(eitr<`9=K2mQ`v**k~2GHt1#S?r^?`uHLwtWCeQ31^dM_XU88ze;+m45tF%XZ;d@f4GSx1#qHKqq0$?YO{tHlcLyzn2oP9J9L2 zou+B8^IM@h!^UAQf4{7{#Gae)4K*^fny)s$aF13veKcV%_XHMj6iRz}$jxR3t?8S6 zr%kE%-a!V>Lsnu7{wmx!(^MLA;c3C$w7xZb;6<_tyN`T0CVIk=SITO}Y2^f2{uvk3 zFNaF{Ia#Z|*erkI+TnM<8FKB|I}hhMgJv67HtIgly5F}W=iDD->E@l1kES>lS@G>? zVy&#_$Z@vv(am7C>d@8YkG#bhRm2Kfq0VE%upu?%ge-SJI!l?$`^H*bXz`%5V-EQA zR!HMS7gh*2&Ykcz;k+Ac0BXWa_IyV+r8idt{NFKx&ZsYLEN@UKcS?)9&ro)%<+S!e zlbo`Y#ns|>I{#TKzH9^^Mr@g}^6KR1eu-7J-3KI&sEed-ILGcG3kn*835*xgO~HrQ z2sz8B|2ueuU(BE7e1k_8r*VV9CgVBWy%J^WMTRB*kzJ2=?X_NRTywdRr=cL0QTO}L z0}h(tnX#Fm7WTITd7kX0b`$(}G0E=ap7-!Ta>wjc71*x2zM3z3dZ4S*ejl*TPdNT| zQS|ql%UJI`Z0KAc-FZWr{dG%2nxoSmg~c~Pm%Pqo2k&wgFZ(5WM()PTaGnqbqt%s? zyQY6LlvomN9P{gcdn4nG{bG%JGj43((5dKEDS2a>`2YTgQ;$Cv0WZesnA}j}74`jl zq6YiQm1Qk57F#%~qOCS5Sx*jW<34bB^BD;R_V1u}K_z5x@WS*&#nrVxKQStjEm zlk*7Nhv#(sdqBDJ{;Fe+eutULoc1wT%O96kn9FxzWyFTw7d+C^oW~SaC^OCGZPe`h z*b+12>~cL;`#SM0FJ&qpTYBie$%rdpXZd@{aYB=}zryRQB`F*3*L3;HmAw+pfm}^n zGvn5xHA-xrY*+rWEjZ_X-^9bo;m#~S0~?8i@3jZMH5@Qo{PPZ-^P7I0m@9B$u7VNMfv;`h{l+X$ z{8N8?VY{^E-gc3qTjHQI8`FvdmNS>VXa5wW9r2v`i5Ylz7N3magQZeQhhlhEZ&v7B zJHOF{;WGQJ|B3zESh$a{KTOR~-T=A4auxeY3EpgDLmk$YnH+6r7|!eqIq#syQ0f)t zzvqy`!h?)vOk3VF-(2(kd%Qux0!cpDjeSbJ3NO=s?)(c&_zKF2#&QZ~RnM7Kwq-qH zO2~VdvVfJL)b4_{+>SSnpqnrn&w@^NOL(r_G}4}XP$X^tu$^p0ve!^68L?xPiT`(b*eglgnW)Z`4hT zJUn_=n@9X<>4sa}h(W+5%_eIy1YFUf_0zx>>$t)E6IUT z@y8xK6))R8>IAqZJPh^jrxfq zLrb0Qa}PrfeCA<+T;3DSAUywSFwZomQoBQk6?;{0e9~sKarkAmWHZOCzdMevI-;N@ z+qCG{lbfbIf*0)WaXmQ2THI~arj%e=AU$KgqlAk5W4%)jIy*jmlRkXhe1fXLH;Zot z0!FVNoUM+Sdf@2Rn}JW@M^?P)oA7n=H$&(}cnZ=#-ms>4_VC;almMOV{mSWcAh*ti zW5pA8%u#*Bz?8Fn?&4}L(A9A_r6UI5SW-AQJJNC_3FMPaNzJYCfU!~dMsV`PqSSu>{E>Nyc z+$?6`3_2aQUr)42yo)_f!o`A2e`mmC9CwJug-}m(c=2X36N~yeP%9)`4 z_NY4BjXHj4;Zm#c;`D|OD_JAiE^$ZSNd3>ASQ{Ov?i}W87?U9UVMqE6ANF-0Y)<`c zJ$Qg+(;lIp^Z09ye*n$NJ0)Z}$WENo+9?s%kmkPOX7wwE6wa2J%qj8bWAA12Z1`>K zuslYvnCJbX?Xx9A9yyjOJu%DAXA^C+=GHfm*wjG} zY2U)uwj+|4r##=vAm&+PPgJv&@&-Q+5A`*l!8ZiFs4HUD+usD9P<1_HxW_w8H_;%V z@s2C#*24&O7DP~2Cpl@4s-c0d|EA_f5Mby!EOf$4VDFc?4Tv{^Ji_Ae{rt4 z)Xo8Vp%2@9n;%%w-3Fa@(Oc9gzc2j~$^V2!e}6~qnc(Orv%4rqRtVIv2A|p7X;64Uha+RN)e7+PsC)cP@0ji# z_Lg+|s-Vm=_xgQ<8Pd*H^7;3i%zk%roNhiE#$c_euy@Ck>2G2VH`Hj|eahZ{Anc`9 zLSBy4SmcWvYeR(eLR#=`Y2wtQU zzb#w6xvP!s@E^@!i8-4EH}A@p`)1T&rTAhVJ7|ZtE5qv&7Fn-EhQtXMt;_P#JnCki zRnTSO{5^H^GT|*7+a7B&zp3ND0KV^O_xB?)Z0YAxcs3`_6^J>#+F`E1jocS6W+gs4 zA${@URTYn#M(Z97_E+@*L=n_-XQ+(woS&t@u|idEQf8R;mdlr`J#`+!$$>&L{M6A%__ zPLzga2+%b^1~YzmCg_L0J(tC1_dv7sJ^%lNf~0`t2%(M52e)11SkLb$%N?M8$W8u| zVeAgJ&qi?*X8o8Dvcb|_@7=*HxfeHLZ|s#ScSCVIW~D!ReU9PcMynVh zE2$w@yPkb16|>^I*#Rrn1xv#WW?%eXp>VqK$^k1$1+#6Zxg5Q>BviX3cyHx6TXn!} zc5~mYr(vyr?$`7btWGziIi%&b+-Yq9o&M>FvA0X`vBVSMO%AUdt1UrE0(2MP5q9u0 z<;|QYg^SoT*p`&4s^}z~UMaDHWu2AtvNK;L6^{Q>ESGUW8pA(Psj&A~K>0trFS8j- zoUJ-ui#J;;@!n!*`W!UntxVg2o312-APCYc9&`4d)0E_4$G^a zhCC1UQVEB-0s+_W>q%aUU<5Drh@tU&&Y&K=$C6bCBf6i|*=HWc{j%Q-LzcKVitDhk{ z7gmNpcwE*fb#~eL1n}`x@42q{aeU%oJM$jW7c(nW`1&KwA>o;B#lfQuYacUCIf&ZEl&OQWnEnhN2 zM(=Jl?92be_~2Gnd7HgQ`WyLM`zJdFNC)K={RvIF;F)@W+hK11rz6!ob3ad&SmnRL z;K!D0jaTy-&qg?;>(;z^C2_@ALAD5VFdWAbwo<1Fx(8I>t8i)_bTC$6+N?0$rO8S$ z^C;_qy$be{U9QWFD}E@YOl7u4iLnEx3J^$$Kuv~C?&4#%pticSs-!pGxXW1qx8~&Vm34fW>wL2mn>|ak> zzu?$3L7;hiqu}9dzlwPbwFSIau7B@fdxCA-cV_Upgi9R#r_W)vQ5Awrs-Ohg z&?2s0V95O9S#iX1=J13jD>mN(K+PKxf&mqkB#Ek^`KS$KhpAtM%kR|-&izc*netLDnL1u94+@0TOf<;D} zYpt{}^NPz2tA(5FPCNQs@YlV;6gJJ4ag%@Zg*EKI)JmS5W8YQ#VzZ*b&-dmxBtWMm z_C0pB=j2|Zm-JEb!=}|Qv&9ZuE8O_Q9Nl&GhM}MyFDONNvU3{f&AIpM|1q;z(D3k^ zIQ|JtpuWqp2SLs2g_$m$PS!cmP;=T6a^Kpz+ZPfaNl8tJliKLLZi4?IrnyzE`)s z*jv`->cyP(GClG0>J78$$=%iw>?~%l8_%gvadDV^)$#Pkf2y7a3gtF8&h1NcxSw;* zL5U&P@BLrKmkx*Woc7y2XK~gsPkAQ?y}oDT+^Lm3AFLh9WD_bT@>p(tk>H@qyn?wY z{~GfW`7MF6R~R??yXNe&x7a6LqX58?t=>tRmldZ+=F^^hn&alNIo}U<5VcNXO;E6@h6TTC54<_z;Ei7)hqD#y8 zMTz3K^D&yvb1Ybe%J1++zWQ8nv}ny{1%>Sg(~KdP=z;Dqt4dH$X;oRDwjtc&Ttn_= zOOLtvN-4qS+a|9|VC0&8w&5*fW3C%$Oz&m$+zDIFWR0>}ZcXT`u~dAKZV;tZ%~8kPWw66Gd%2 z?rDk_DNXNlvI$fETdG)m$CL54qzkJevkhp|=|{1Q=g9}zPkg#^dRhE|&9WzCc_u^! zu(NDA!*zu1Y{P>|?7D}URz~i~W&WWjFvE7i?2BI`6^u2MJfKVFWq(2-nVL#;B&!RK+Kof-cAj#DK2oQdnK@{Mwq0iQyV!XXSIL}Z%@g9jT;Av~w}0;Y=Lfb5?ta3xQ}|HgT(;}~9~_BeW97ag zeEMHr27~@Vrn6OZ_J3<|Z1(JB{HZ6fo6p0}$xbx;`P5(@^|-EPYXybFiPiQA5D)(0 zp3Td6a`T#*U)d_Qw@bz7qIP}y&dfUfTk@2Stz^RTq(-yFhy9L4)s$H_PunQgb{jHS z`egEk38n{*{x@DAbF%xrMBIeB0C(19Y+Dj#uQ5h$spY;?abx4|7kn;Z%(u*wCMPy8 zVllgX(1BsW{Jz%ge)f!I%vXLMNRugg&aA?3#ml|soxao8yX?yk%A~ReuhBcC#&7+Q z>&ioi`xShXnI+jK$DcZVtf596be+VL;EfJ*c`p?1R;ayL9R@kSZWl9)8eg%(iq8v= zGVS?rNbdJiw_g!Q5+wad#+0N|TH(9jH_mjiM^TB;aKKHjYFJx zu&n}bc%XClOs`JJSeZ;QVzjJ$(kpUT&71iyQB~Jh9z*&ZlkitK^p4w^WwQ<~d{~^}|Z$gp}i4 z{_6@S-15JiV+T!TMqLoxGyA!--wdWw7x;8(%5U(cbIKKIYRnw*tM2w)jn{wg>~~x^ zTqL=mV@u+RXgld_b{X7rsBnGr#e1`Lzq(uN-9AXV?X>GgbD3 zZoCKGo8IvCma|#<{P%UIKX@@0B~H1)8`ox%T)pG7&5lxuG+mn$3gY@bMOI?J;Qgjj zGtliRJgf6&9$^5jr9HQGwWP$^9}mhJrX@DM`{(c;c~O&7mV^dN{`@TChHniGJqJPk zmI`>9zLDmeP?d0ceVlu4%kE2B`Ynzp4^Bw*6i9g|f7?hqMgO4L!u+>8SjFd6?(I2f zdx!gs`@ZMQ_YL_Wkn*=mn>!3vHi8`p)GA& zcJr*?q0r1!!!w~#=ZO(l38&&GJAo&u5fZa6fV*u<<$_Ow4tm}9m3YUtGV}f$cCq;~ z<;=_XJIv+#5`EtBw_{gN_k${w2>_Er(_&+-&8ITnp1Au3A5*E-1br2jlg;0nTh4H# zFd$|mbFx5JwA(I_6cmuYZ=^lJCTFwdHc9>)m$aVzmAjE)q zC>PHKO^7VhQ{-{`TQ1KyXW*^)Q!gxo8a~gxAu{3BxKSx~fkd?f7oP$)q zlu*(GKF{B?@AE8|vrRFW+}x8TyqksliP;4^fg5aP6C_`7W`&*)t6*;d{erU`OJlpsi!@i`J>7GT3gocd{d|o#bHf_z?R@J}AKg^uaddO!*>+1W zfoD>NwMFZ~Q*zbMYaT6}S+MuTT;Y`R1F+2^OpT}OubtOO>)`#yaIQvS+LHz=`82i; zMjZk9GII{dJXIw7?3W5D_S-IRbnsp~!CLNxxS-N(&R3vm_m($|xncIFKD0K9G3@=! zc)Nyg6ZaL##=HDXR+GZdRjD)IR=yJa&|&Vx$^(8JYnYvM%|CtUHV{cIYp_;aF#BTS zv%2X&&OgXunc2#6wqilPP5A$Maf{CnS&#vjttbU#N7q-l6 z#I~*BLJa<#-7u3cXWF4WPkjcxy~eC%7HM-^=WJnnU2~_3J5zHNXLqx;$^$=pZ_fe+om#7D`-cRT9 zEQu=;ioff-ra7c#t!~`hfjI5~v_0K9ZnA^}=#mt>19SP=9=y5Gs1F(&aGJ|Mq0+!~ zc6hq+k=M>?M%ptQn~!J58SCt+XmGTUG)nkZ_Rf$^zV^!Qc85>9&MpKUO7Ls#^96qu z5)VWQe3{A5CiCFf{^$?gY>spJQ&M02nf^Y{sDs;)t^4S{rG_$f95Gar~Xq>BEp}>y_i&{+5^Cl42=t#u<{S z#tmi*CU0Wl-c~7ltr65=GFIH+$Fl8lg=5yE*^1sC6RhQaUWmTvxLLl%N?yVKz?G7- z4L!@IrdAjoc=vmTmFOh~mb-0yLEURVH|m}R-GsO_VnJ%e0@Vl}5vG9SOqGzk4H{Qh zeqgE-_vqVfdid+?>kH|~OT(2N)y~)Y?DjPOPq4i(N$bKIcC+rpN9I=7j1E{S7?kd?l2@plAXDVd zs={Wcsl9uKqW<+c5A)=o{K&ZQhJD57jeCAeG`G2`bP4Cpi8v<^$)#D7Kj-IpfuLQp zA3nNVUSMjq&68(?YG?}+@6Tx^5zm>Iu!9B|5`HDhcAT11#1_P`t&iPjzvn5nHVM@e z3wSgBv*&P%G4mcczVpDjM&2cd*f;L{ZqQ^cuCQ8eZ);D=Y0lG)M;+!0L_BAnZL>mH z>D0O74;J*Cn7<%3^2E7)e}C!C;hrVgxRQ5{JiC~>$!o^wd8WTvQhr_ve$e*3yItO} zLWIfvfxNE+r((c!<}D)J*DlVu6Vsx^|Ei_o9oxyZu5+IIXIx{xu2xbL$b75goI%5b zXQd~47VT2|CVbUlZvP&I6Gfg+`ZzaDesAM;=U?rM9R3)sI=dx$O>Y?$ug~URH=jjM z-jqF?z0~Q^pJ2&XyS*gW%$1eUllytT;m*Sb-R(@8ZL+7k^Ynks_T<{; zFuElLSs|sXITb5SCiVDRJ-Ww+L-#z+NeQz|kM9Lh+YJNxc z_=A4?Kb0P{v0+rJ|FlE?aBzZsH1DoYB3C#WXP(z6p1>G=oLQyaSH{el>0LttXqnQ* z1%2$yf($>WmE@dC+$;`S$mO{=E(i5^#q$LRrX?;s zpK-wN1XHdJ`$@&q&0iX<qYS5E$*)Dv=u`$<){cKf(m7HeT1SiI_ znF=2Lt9Ed>eTiX+v*QS6ezoGjl`}I-rzD=bx0nYMcgh`i1@5#av4O5j-Ln{c7Ds{t z(}BK+tan+9e*MT~3-&%CwC$xXyTpz8%MCMDDezeSsTXW66iS(_n9=;}SBS^r_6uv+ zb2e8-epcF%xIW$~EwQZr*U1N3O8ys?Zm3lNFVk7FMPicL?&{wX4n-$E-T2nW((W`Z za!oAnNA{d+%(Iytir7^Zz4JSu_gO#DDq;S8@9sw)^SnKYGxqhi9yFJ|RLMNIqV>+t zA3uKC-KeSybS-F4sr+7KAb$;Xyo;w*gyZ#N_UW?SCy={c}GgVeR|n039{@QJ81GzK3bh+%R`wIsZVkO7uZT}6s_)zHZuUt zb{99!<-hUf_;z!Di6{GOQwzSf_q~+qCgz^j}Od(rvqOO|62RMXevcuPb3L z_XHWxvMq(%&K`10%yO=ovDGl#`RQPlSN{24alz9YRtgH99kYsgB#Gv8)rCt1T*%tzj)*rahzG@-1kTPpn;-o4`oz9_n>X# zm@PFyvj6@q#_*4^i43JW39lUI3SQ8Cq400n$GnD_>2mYh&y70mcLEtZ zo6qdnSfJPJR$=6(&Z1IZ^R=$+c(%gtD9DV^y zH-BIAT`swApGi{1Ux^~iIV*Hh%9yTvywKld619Iicx;E7qaHcy>% zd(yR5rnUxw2SrBFYAbFSwnb*EG4p?GxihQJUv8%`^R7J~KJ9zXbLrPJ9)JCLDGS&f z=KXD$$v*q5!@CI$R~oJ4ubEA_Sp=Ai_0A$bG3<_!u!|#nBh3tu{R;0Sx?CYWhV9b+a@0F zJ{|DwBR>w!wB@N`u~Gyr3i!yoTlMd;+!K=&c^|Btuv1fzXY%tk2|xBexAJ<p}2YU!;HA0R@CSOX)@)cRycQP*Yu&sIAcsd`n0N3)n zskP*iGm6Fs7Mwdim31r6f}H{p>@3UJ!$CuClbqkJXgK2V+p(!ZJ-*Rw{^2tWxmN6n zDdi1M^rzoVc;GFT^x{63rKa{h>#2<4>MUln8?(1D-|b&;&b@J`HnUy91ICojJ2Wjs824D+Q?(2Z&JJ_= z1Jsi`MN|AIpMMm=^St>=PG>BSSifah$JOc$wxCrl6PPsfPJFU}?4tT-^DuSB&Yv2G ztyC^=UmtZO;0S}|f;8QNliSiGWCD7voA=8tG4_8Wq{F7goKtP*ceeS>N@m@qlN@I~ zWhm9**(z|F%dzH*ABWG`%j}#yNfDcjUs&AhJUaQ{z7y}yrh=BnoozdiA@=1Qn~qGv zBg9^T!+dIdH#_jaLqtEnFRzYH-3%#Oex(Wi|hEc|#6~ zMR^NYKJJ%`IIX}Sa;@)VT0-K}RED?TJ9yV7HstzT4>C&9Xprl!_$n5sWzUu2aI1IRuz<95~_5iA-rBu z%6vl~^9dgK(o*p850|*J^|t@DZ^N8Kv zz$SEV!8uO7$}+Yi3wbw0U#k4Ev0UK1O-soV-zOXOKP#))|7Jbd;=ec5BTUf$SR8pdyY$Y@%9JXv)5EqD&c+ zSca_Wuc)jEG8vZB+H6z4v0XdKFq3)L1c6F>4iBCq``L;=zFo~Dbz$+#?YI6W2L!t5 z>}G@x1A!OlA5c%@luvuGe|e{IO@jBvUCSNP^h4#Cr6=|K8?MN3=JN$z?Kg`*X77oH zJ>c~Yo1#*<9q01TxOE`ogj*zN)7BZrx6F?AW#V_8Pt3lQI9E7e`ID1(%6WFhPT*t6 z@C=*4^~y67)OzORFf(QfW}o%7q13>`v*t&dT>?mP^1n%y8pqO>rWpHZ&+k%Vvo71t zRnfHUa=gcB5y)7^ufjbBhoK8u>Kb*AI=us(#m@F}Lh3^CG`UoUlZvMozZYkm$@#jX z;fBBHbHg7`oo`J9ZDqG=E02At#}@FMY0Y=WC32I)0@%90f=*XBbVuV;>11)kh9~^* z?;UdBv-tGFDq?o8%(oh654qa&>}#AKSxN5@sjfBYnhYvMg;uvDd9?HFIVp4YqJpWZ z?E+Evj!^fRiW4HmzU+2zh+6LZ!o`rW?2TSk#0G`)B?nYCb{>Q+8amU^*_`H>V65={ z$4<#PZxxh}ft+UDCY~Y&x|fsr)&@UMP$^!O&ipKWhQ+$YmEg+arGf2+zEew-?Ik@J z7u3of(b?Iw`X`4;Y(rz>|4I*4_S+?WXZ->|2P?jqEygg7P4}!*ID63M4Aqq0q`+%z zYy8+{w{lMgZKl*=w^}E@MTL7ATbZ-f#)lhgEf-D5zQ3VWF~Wa7;}y=vm-GLBQfLn6 zN`ZG(zBE}W8i4LQNZ(+=aYd7nv)OD>{w{tQzV9ri$Lo!^FjjxiESzw!rZiG4LVd+& zMq{QUY-c+Tq&b5Yi`YQd4}sbrjo+G8n5-2RJ=(;hut%tZonwt~QTkEcHuj_mZT8!4 zp93vqa{t@}*{0RZpjKxqxuZ{}>IeAfb$t&$@HMX*`pr7VyM9Yw-SE6z(Kv9@DY1y$ zgKGR%Ke-??{wWe~TGsGR6|AT=kgSknf~=PU&AP2*&2`!CI+r1_;cQ34yN}auFujba z@d|7%m+bNDGCHs=_K=mlLObL}apl63&1Wpq`7EtOuPkhQnOWGZ<86Ir!^FlYhHDoO zm}xU@V%}n}vVqem!s(5W&ICKq$mPb}yxz@?v0K}D%CFb5T1)TT%=npojc`+)iGGT* zRZ6mPhFQyv;Ps#@*N(qydcz>Qk$VwnrnP9n<&6#{uisfcV4abau)NXl(5$-u3eL~u zs;4Nh%N~wCoPVBSH}{hh4|Uk2Z)ZN>J8?4eIcSUX47M8+cc06vZm?sy!?Z+bKt7gNo0p*9Y@P`kM)Ern=6%9vA^odJi-g5 z&w`FGvB)?%ZGVo9^ZV#S#x25TY{n;kF;9QUw7u|#)AT&ke4DcYr`Zd`KQHeVsGOiJ ztN8S4@&X&?4;*n%{5W1DIbE2mz@NX5>3rLX)y|i=b27ysi|qIN^744Cbw4P5YU1|_ zg81->t4*7FqXVu)@BP5R$aY+QMp z`Oe~I(0K*ipglT!dTYF`d~6|yJ_tL%tJ$KalNwO?$xUK?_OT1*Tc<1Dk-oGpYG*04 zQ=IswKQfVWOFq7A-p$j@dcaCWzW@Az8(W!g|K7Mjyzrsc3gb!dLXHTeb8C8s?v#}1 zySCj($I52z!ArlTZ$uy8{;u&9^Ym?weDTRQ>i#h>uSiz;AQNBbMRj7Ee&# zXk1XMupznJ(fwW3cXnfi_neK9U3Sb(ZzPb{j#?TNia(gv{f9YPq9d}2^%8qj)6oM5 z4OTe#{q*Abo^yB8bjLVlKG&E)>)wU;-wPjZ)aI8kyLY+yM6*?V&V;k??-`33YG@i8 zAQngkq%+st(Yx?v&8s}{%0b8Jf@;rI4!!MZDr3^RVh{b_xWSSUB8)IK&RgE3-DU;X74)f$o71z z7tincb5my&NKP_yoGuv0-~1+h7N^XQ$Q=fA5(D2Uu|=>mEfK%6(cykXpH9CouLpmT zdP-2Cl5?DXN~QX*Gwf&bL5plVuKizav6lz7K?F3ZR$dG0!C(B|eSoL_GtVUj?hnm5 z-xy1s5{edBJ0$#e$oa37W`9BUS;JCiCU8gQz?Fro+dtYHF`PfDy5W@2y`KzLk6tHt zB;`dW7PK>8;bh#&d&lyiQa#@d&W~=ze{Q{Wmzeg=NiVwPY*j-BsH=DNP2G_XXL)W& zGx-%XnN3~2@a=C0@Oh+boAo9C9r=H_qxi(i2%ZPOof4)?IGL?cU%2A!JxoIfC6+lW!{)FoG49>R!oBnJ$DgbzANs?c*zP=JD7A5TcF;=w#*@UkB5YR7H#j2} zBv;mVdkc8!*3!h?VqIoTKORuI5fHtK}BQNFUid4_>Tj{jZKSOzT3I7FOVJr*UvYQg$U?rdVtdnQK<1$C} z_(m&5&_&)AAGbYCCE6Zz8ael%y9?6HyrFIF+qZOgY5#MH= zxj8Y^lzBxn)1d{{4i4giN!+#Y$=55dY7}mFuKvvE_dqL(=fw7T<>FHfB&417&KGyB zb1Sq04WIl4UGFhjK4H3u9k*$kLtd3VdtQ*&gUP85?rWc%l0$MSx}6%e(g_CA=)_jT_$mZTRW#D^_^( z(z&}6d{4hycfmKC>kLo2-#_+z7xrAI^ci*YmLwExKc6D-|MSGerz^MeEbwOEoUPcK zDj=OEkin)>ZJ6RB3_8)H6k|#0%O{L~536`>xouzkClzt$>*KQ6B#WupeM#p>-fAXNUe7wDrl-->_rxG?E@?DVXQf2W}vd+J8H~W>JJIpL+ zGj0jI%X4F6L#f8Jx3^9*yv}GiBDFlJtij>Y?@!YV-|S*s8F5|a&Y1}-gpUa5ygDKv z!#jtU&9D2+edawXye}0NZ(gqW`ctp(M)|Lu-f~wsE$#kuIQ!-@ItLa??fG1obtv`+ zXT$>VGCxQ6_lIn{z2&yVynfgn&9fuTHsM#|>J=extWb)58Pzk{v2tMb5fUf1AV+7IM@;0KPA0n;+Lgm$vNn>>l@* z{N)bZa@b0KmRQHri3|ETiquoOzVNl(wO+`3&ZL;_e`G4p20o4x8-Dzl%CjJnFQplD zQ2HmW3!k(nRD{);wrzIITIQR>+P(OE&jFEUvn8OtaaRubozOb(op523``k>>X4_rL z3DbFmxIo85IT|Y{e04v!CS`*m=kW_%piPDj3BMgLOpj2^Zo13Pbeoy!c2D2h$xN5o ztrfH5)n4?eKlOqcMRvAL)5 zwaB9%6;Jxuy(Ap_pR#ryywYH$wp}c#%*kOcUxYeK8e4|Fhhl*ZE9lsfmzPgVeEFmJ z_5SbU9TSBwoPDt%`r>`g%?1@amK%ajc1*L}aJK7-&8E~96)Y#yA(st+ZiU(@{?o|m z%MsSyM+{!YNjjH!h#qc}HkJ&Fn|XjCYTDN+iE_+l46kDvo`9VlDXaI>d%1%6)>ktl zjRm+{rmbn8-@po9SZyQs@M;I}Pkc;~mnbOELJ%!vsNIrrL1^&DP-&A;it<4ONUE@t*Hh2N7Wyk|LB#iPGQ zxGBc~G!D;@WG&nM^u27Gs3T{>T0!m0l6>iJo1`}<*P0z}(Olx|>u5GxIfm(V%K;aM zx&8MzUrWx5w>&jLbkf-cPdHZY$_(+s=JTPD;e$nqvx%Pe?Y z*}1nxAkBQ;?Xw$q@-8v6k(o5%Zk%J<#Invvg9FpUG#!=|P0TlEM_#>d-tg7wTeb0= zsg|b>aK6#>W-`~+Whis%k#{g_58D0tw?6ayGFC93+x>P%qf)-yq7w|0#0|GGcT-yErM-7|3rN?2eosSuf`LF%F@#m3B^X?W)=5>A?HD-rTc4{m?U?s0` z^#4AF!)@<51AjS)3o6}bWwO4@^)p20#@pu#%v---1)rpr!?uT6<=K7dHk&PdCysxA zcHr_lg-Wq4FF|LLeY&`3#}jjA|8qulh0Ts#@l6MPPj^0iC3>Q&C<3(b8N8kIn}*rX z>hhlw-_o3=JWhCTb@***blU6St;A|;2bl>GwPuSPS!YXD^4WZS^^4mh^83rD>;=!6 zm;5`&?jaY%m}kdS>QN<8C6U1hI-H%4{nK7~&=D@XH?DMizvV%Z_MT>;ioSzfJ2YM@ zaWC_Fa_;!*-xC!13|%z~+F7ogO!!g5f6vl!dVKd%VW!s^6D~h=D3@LLG;Bj3=ZedX zYuK;+oH2zh(!5uXJ-GZ&hUno#uE!<*SundRr%M`VtZO>6Wu{A-@sca^Qg_%d7d$Gt zflCU!uK9qKR&{wUlm2z5Y3}QrK^&$>4t9a9|6lD1uxf4mR$` z6YUj@3x3;!&schL_W23WQ2~*??2RYMN8SdW)N>SUJQ0#LlVJ4`l^r zSgiQWn4BJaJ^jS24Xp)4JHVA(*43%2# zZN7JM>V#TGNgn67ISx|}TPZG>Iq^8p6vhjh;bna**i{m=mp=$~iK^jf-rB0zJgG^i zd98Yi$~5q#+0U6N9!qPU|IOwJZ?;m}c3EL@tireUqw$g&tWF2EK9ts*lQ1KJC31Ph zq#&l3H7?FSZa;sQ@WJPs!^UG7Z&N<(Ra9^cIG)lpPru6sw9fPP1^?qt_Zs*h_bd9x z+&-9)?jEHPAsfSWeM0{1QwD-N+L=)nfHXq~P4pT&>o@#lo%ZYBAK4wkOphMCu4wpH z-_UoBbtUuMBGc#3o!ORaT)DWl_OzeDk`2ygtM9U%Q-~32j!WTug#Zz^NYF<03M%`69!0zSGPcwFu~Pg!p*bFRaDlb@X?Mr*>LA1((*CzffiQ} zbaNNR`fyl_a$n(WoZBxOfzCtib>Ey?igc#`Nn5 zL<62bzF2zVA)9pdql3rvl08xj=CN5W6@rY5t$P{@Jz%x`(2=)0*Gf7RpQt_H$GXjr z!$Voy{f3^p&%j7z!kgm327+lGvr7^SaC z9yEL1_-I+LxKMu*B_-nL?k=4Ve$Pwa~> z)U92URdDh%2iL+otdqofc9w{PHpjeuexkg-K?fFBA0zbSz-!zhIra#r9J_g!M{;){ z`>($(4R^T|-x$BXVWncgFTa;_=FzQT$L)4>`u=mSm1}ljO_^_aPc>q*zkG5*KnP=e z$Idjd7j1XUc^2H{2larin9TdlT$a5>>01R$sg2S#-2{e*lEMwM?LDPWq&*OGWVv6$mmMO|FXHC|Ya57Q!_Q<=}ye6Ev-06$LT!Gd-5p0Up#%uw{nV&hOd`rwo zZvmAS!oQXlcqC5wktN6c39_iuT6ID2deEZIH@rU9hd_%u4PNj~h_sF3Il}N{CjW)b zhy}%h8*=s9XSS||cJUH|*^QX>_+&)b&o(IR{`jfcUBj5?gG?4bGe`x|ojofAC-oOi7^cfPZ-l;;W42f6;$0^dQSW1ArjnwXeR z8-zDFsK+-NY?8a+R?`1VitWQEZ6le;i;2e?Y+e_Bl1o}$Q>eHk_!CFbd&R>`r+Q1| z*;k#}@bIp3Tlj(QA3t1MB*VTsUc0kPV8+*mT(j$2+e(s5&MMAkcT6+bQ|TC_?sD|d z48}5Xk5#EG%%47Tw?$2e`}#EcxMayyor8)@uX=Qv?#VI<6}(GGXplYmTJEcy-Dk#0 z%%zaSW?)MiZ!*O!nt81M*2=2SGDfO;N}aV{GP7+mPKxSyCAxoZ@;kk2YrWkyKaM{? z?q1(75mr1WeMNErTQ>XM-;Mg2Z_J|)3n=j4J;Q19lM8yHspKY$C+F?v98majLOh>~ zrPR)0ZpVa|3lmCf6Ze8oSqT$uK6*W6o!i9u)zwVRoBJ&f^R;a)__&wd->5{|@!iXr zUn|s_H`}Vz-eq04{{E)<-Hed)plj3|uQK8ur+T?DXuRTT#~yW-+06%J`&B%SGneV; z=jd~6s#>_c{=pqvcZE{(jBm{e&zVswF5aG@o-_Cr~cfmRL9e#`v8BG5* z**NVJY#)R(hkr`CT+QbEqU%D}oMIlKz|9i#no}CDa+nv$-|F`L%kxO(h|r5II!`XI z2Myt`jJSSXFX2Zer^OGmm9jav9=)<^Tb%K%33PCB%TpT<^*ql6xwf+kriQQ88;|y@ zZ%rzdta{G8gu{fH$+}A%)TwQDaDUfjaKj*g%VF+>dxw`x_B}M@uwmZR{FM3dXYWls zdAla~ZiNl*>wyOMH-Gu$)0T1cyTr9dE4lpZ`i$M**WYxRxZh!}AgJqep?UFv(&kyJ z63?2f6kmD0;_-XEQGepaHL(oW7Qd7~;{e`#sA=!DuuQSfgSpgB?8}{`8+*h}R{iTu ze5>QZ(sV>(kD{>`r)n0Dr|El*PygSVE%-r|`{>j|8$k@jG$2-v5F01;^zv zf>v$fW#S!IwUyhFzn?e!BQiamq0}lxMPR$hqH-sPKf2a}n>{aW+RL*b`pm?`4B#{I zu9Y}1%Zn9GOFUxharPZ+W6$f zwkJEzF4GK__@Q5uSkRnj6aQJr@KwcJb)SMnPfS{nsy-c@pcAVO%;nE`{^;jv^MvOfO!|_n zr50ZN(;9!C^Z1m${-hyve6mDKjQJA7owtuCNUsXjE#2UzY*zVHon3NDv#kV2sojM4 zOpSB%T0s{%U0Kb3fm^C~bGC$otcbujYZK@?4cfT`2y8o*`GhSl1 zR^-0+lcDoutE=$=D`A7pwl&>_Y3X18Pq-L!;SKx3bL=MsX3Xj{p3oN4%K5ELYQ<;9 z=xL^}gOr_XS)XKlIJUr`ZM6=MGau+M7>ijKIHMK_uX9k3YdkZ{EM1Fv#pOmDZKhlN zO{e89#0g9+<(J%4tC-6D$yWYH-$T}!?5|oHt~7knI<`pfVdL2nflugqKRJiCD4HGWKUkJ1vxk`}xEC=)e2ZV{bk1pmw`USXxIxn@4`zzbmq>tRsC(Js z>P9tJ&$}B6Z{dG(N9lxM;sVu(6O*d@ozLAX-&S()WnsW`<}zg~Xb?%Vy=pmdHRt{z zgVn4>lNi=~PF%q{a~adc=j-1(ZwOfcBKbXKi_= zFzkO-^`UT&`~0~~(#*I1Gw#06Tyjd(@c0KKnLVA4T58i3yfx4k^^|f17s(JWt z@p6f0Tb~^|%T(%?FjruL0%G6F+$vV9Jn<#_uG`OLyyD3Cu=GH!m*F={o(0_O)4Sd> zmD@RF-Mhomf6$;~g?H0Yqh*d(9~PW*_fu233tOmG37YGl)&5^myfyCE_eqYbyqn_0 zul%%-V2EsMtT9x4ab>l%u!8b^&=`F))1kSWw;7xf;Y*DuN@HeT@p)sV{F2FR@zY$B zm>OVH%NzPmO+EY>yqxjHZ&!&GEKIi)vlm>Po|I@TcjaY6sZ+wI1y3Uu@V;2^G<;I% zGoHv_6E&jlzq*&aVXC`KAt%~Fq|$!O`g%3lCob%@=}(;hJB$r+lP+m)a#YOz&v=@y58^AfU=1bw(jUuY&4d*eMY!xzam2jM%y`K>02m*{h3*mJy5E4lEj$EBV%Y>v$yfzVU3Iw^;6b+D;L}-L*DSMep;$+HxiJp*)`E*(CebS4a^BO0b^w~F-*yyHq++V_D%mO;ziW(64T_e+mbDYa+G(V{5xTv#i(Uh%Cwt7*r#`nPF%{Eu>8)bAd_NN@b&e&-A z>BBeI1AFBsT(kyFDST=A)_9=rF01ZVt1lcuKa|U@63SfsBb$ogdmSM+tiRMerIiFZ z7C`ZgA4g7G@~ulNd6qCiPSIZ`j=ZWXZOzvk=L$Z&jB67Yzai<<+BjDwL2~#1QzC71 z#dk?Ybs6d}blk_x0?pBDZXGPxEmyQcKL2DATXUBW+Y@1}nfKF;b)r~aE?_;LYW#yC zU)Y_mUswCN(ViWhd&Rrzti&p=G5aSR@;lgcmzC*Ni^BY#r;I_ zBeTj2YhNTBJ-~P3{o?e1cZk|g`$FMv1zX;1V@U^D5dpTljE5W)15AvPJyy*-Q@~!e zi}i(((}aoEQqc#*g_^9S4745Q_V;xK^L) zM&?ZH!32BDrh{)9xehOCh!RnK@HE81aDMh@L#L1l{!ZcyOus70^9CO3VtUU+q#$nkU2(6g-XJGB^8Yo6Z`y%+ITgbUbdK zW4QgE@m0$KktWdEIrgS~Jlyl6*n}E3UQ=!hdl9QJPj89&rjD&#)z6z76N|Q(Hs>oX zncP?7srX{ank~D6*bFmI@P3&e=5Vb%e%0M`3&PnYd093V-sHdap7B*dgTbdd{x386 zXVi&&eBCjXQT!WY`iched+Xn}A5jHu2TwbIzIW~E1NjpQD>!EsRsH1Jbp74Q!>f4~ zoIC#7eZoPBK+8(D(+30!jx#S2Kf?C#+y;gz37}i-x}?8c-Z;mpTf!{P{v<3tn>A%V*-Qit9!~3rdQ9XA)I`DCW#(<_6oJla)bLOmrHUr9~uY9*V`f7Oe zPwd_ItwZ{#qxr(ae+quwP-MF>NvEcc>1>mRo1@!X(6EOQe~IKmchi)%-6p#_63zJ^ zEinQQ1nl`y-?K3IhlKOb+m;W6*Y~K(O7a=cSyW|m=Vtqkt@76_8B4wL_A$uqtV+yPJSUES zFq(6No1YofB4>cK$Xz_-mX%#hJo13|O-5Y6@+aq3d$8%Y#a0}ibM$dPL(S!%yE0BV z_5Zx?(XD=?Gh89ItZ0H;TCR4=f`Bw?z+g@l4DCmF3H z-GX`* zT&_3Irs2ziRFRMXE13=F*mv2i5I*!*`0Ekw8)?NCdf2NZn*H`Yai5yM4%;l_cFr+Y32!Y z`9=Lb9_EI(&){w8Y~*RaE6X&kzN)t|JgS>fW&hqC^ADQvZolmK+u}*6!tylm%>z;y z@*FwL)sW8FAx@qj=lD9RBsMNg0>459d{0v2{O<7Um{}nnbC+Dx*=h4Ib=V= zw^eh}3id7To;cg@qaI8n{yAoa$Q;oI)76V6ff^4Bm}bu@r$#cYdT=I z`nzv;0{C|9*J0m`MbwnoKuf>_o-;2I-}2x2^-Lz`4w(;nyhnBj9iAn8S|Y+oQGMmn z8*0Wa5f0ys{xPg$*u!x|;pa1vKhqB!GFu-Wlb?Q}vpwchJ9KS%9y2IGScxw)aPgdG zIOXlP^a)&!GMRrr+N7Mc*uT)4*$i}e2>X?v4)^AOP8M|Hd;2(fLvZ_>uT71a1TpavutVR7Zz~>X*U|HS1L1i zG9V0W@;{T%aF?;^?FQay3zim3d|IQ>da?2MhD=50Nplt|aol9!vt|Vikasp(DNQt- z;I#bK^?3)kF>Ffv@u8)xZ9PxNVte65x)OXg0qz^GZ_BWD&a_?ffNA4JS=L+k8HG+a z&8uTgYCe+i==pZrw1Qm`?Drb@CNaw%KfSgqqJ`&v2j5+8r!~tHXJ1I1%U_+D-qy@t zZftOJw-IPTvLDB$$n5RTR^bc!*nDKJ{A75~&&btarMbb6J!9t7P>Cl;Ru@!fw{1>0 z)Ygl5&Xghs*)rnpA-7CypHB8y@eLQw2V99`e({cf2I%f;(EZE_a|HzCx9~41eHxYW zT2iNnS3)DUNwnslUUSvC8nz45%-n3*+CqF!6dpdYJV};a?=6Gu*3+uZRSWr67&Gm* zesV3!BU=t>R&s8Gdb)3m-u03mqtp(@dG98qT{^R&>{eXcR_keoI=4-xGnUM6U&i%h z(oXU9g2Aij&sVDYG=Je-o(PA=G?x!2@89OWxcUi?<%)*yrcYk*#ib@Z_m}+bDaOOn zP#t4&c=K-l1IyzTwOKoxf8_WFxW7t}WiPO*E^KGqcKq;lP0qt=FM z>B!;Fs6Vm!<%G-oml#D}i%C)8ul?q`ZEW6J3V?|U%_INsdI!LVCZ z_V%-)8D&UwbZlIV&)Z{pPRMe7n7BK@c%rr3iE9a<4T7RCawdw~ca{b2YBxWu+xMSm zyMAnHz}3rYx78P%W825azUknCbM9`tn4N3ph&ujuSf1?r+Wqe0hB|u=J?9Jl$5+iW zoc-{{x7>oKpnY%*pgoKoybX)Xrx}2EWXY{*{xp$s)3bk9cuqvVTc8?YVCvVt-Ehs* zwkc1=&Gl0oN*xkD?Z|UyFLiRrN-$p{{F*&N-FcJaY{n}e6-+;Yj-pV1RA7?w;N%Kr zslyx-W)+K0u)1BADHo>guspF*#bNd(#|qZ_HOO~$Wr>x%e|X4rGq_$*HMB)8+hO;#XtmQA9J9_x~ z_k*vVx{4l@?K8cssBYQzV8VLVUGoFfSyB`r4ccM>kYSMJj(~L1FTxot6>-{uVJ5KIZfB%_&O5(io(!st< ze2YBGHAcpnQNprpW`9=OEc(1L>1-q$_k*L+>>F|{4_y1G@WkrIq&227`jRQZha^m1 z^BWzhbT$?(5zD)HZ6!~7(i6#hvNlH-oLq8ZfsTB0l8%SnIoaw|)91HL+B~N#K3~y1 zEn(%S)y5459x_)r8zsLy`KjBJ8nNLti{t6d4${{gt6dYkw`NrZoXz`z(fz%V z#-_k2wG;dgG|lZ|ebsW{i2u5{!wj!mK!-ZbJ`cXOS^7(o(}dNEGeyaHgS*J#+xHm))9%`!c>fZIYt^HVwLIZ76tlx@T`VO(oxNiC zWImUY7;}@AqJP|-gRe?wR79rp9^SK+Ut&Y4jf2$2&conk=q+F4lOY!$FlQ@HUA^+O z6VLX>D|7BKTXtPh{J{};k!_c&>=Fa6(@&dEupQ8oYw2vXl3&pKTwxzmiMiRD#|%Qu z$ZJOaD(tOaaGJ-#d+Uc%H^`dS2eVBR7YNue@*PkpH*%2We$x9~!LCZ3WxiB^ddl06 zu{=kOj=bgio4@Snf>REb2ew{kPBF?!V@W$b$#ue2mIc-hOKNQ%swXt2**HktG+nT` zlC`|h*d^P+ty}iG(>FaK@M)U)zKmQQJ zA%o2(3pXpe9%U41WzRWz^-OIor1`^KYtL~;33PFxmROJe1&)_J8yeE=Cs@m0>Cgm~ z8YjaQHai&0o=Dp@+bKP~VXb$BI?I)xFCxyKW3Y-6Um{j=O7zpk-6wuc?0;CgDl_56 z^(Lu}3(m3UeEvDB+dI%ozI?vJ`YF=`+eE2?8k`8TK8X8Yx@#R(vkpD!xgP|F)2BinlV8LLOVJ8VC3W%5RSScUV`t z?-yoCV>2^NFz%aX93$2mlfn6_% z*qsf+n;bSP+(>gMaGkiehqL*Vre&L)+ldFPkewDer&l|GCYm?iMsi@EIoO`}n|B`f&$oY3soo5TvhNqz~o;6!3E;z^T@uyX@#PJ><8+dH?HEXF& zN1^^F-IofWh20gOEjL&-f(Ei`8lE^9D<3b{OJgXtIp>j^VsUuGM8_DeO(tg&i`4$S z6POTn<7WeCuT!3*y)1Xiy)*0CB`)nWw2r%BrFP=kbf$c(`&RYh%zGJD2s7Tg?ATQs zdtCAB*L|(Q5_0u>jvCx|oZ#pr79`#bzA<|G2j?r7cRX=Cy>(r9^8N#7A6)fmJCt)} zs`KCV^9OpGGI#LbT5zuE&d&f* z!Q>TIU*>MWl;e)J5$yoOI<+or&S!Q;;VOp#rq7vHH%~=R)wXV}$o%-YTb)Sj%9c8&c2(3== z*vLCe*3n#G$+6`byb%)Ha=2s9mQLKyvwr8lg&f?U|0glreaTzxnf6}~=Ju!a zD+YH3eTov;XnG(}*5;G-^l!#9Of47RSR9#u$iPvuXpLIVNs+C>ENeb98i|A2oD<$2 zQ02Eu5?{gx8h`~YqW$?SmZx9-PC7?_>l^DxPMaX{aM;N#WuV0~vz{tk=>#3b&1wB4 z`qIR!hy6}ivEDt=UBmPKm2I_zQ+-1GA+D${)?MEZ&tUv5gtFl6cfzA$F*Bo@D&>;} zPj0ZWNo!xZs0UhD^}jjIE#bFCLe|9Z#R{N9td!h%VF%q5dNj!-6eiqDW19fJ-dBK4 z=-{J8Mr^8y)@-k{E~4A(T9Q2GKAuQygkC@gk_j5%+-zRW)zJm!3^DB)@EHO@xe z(_Z%6nv2tSIZKshTl*WP>~xmWF`w^fwqTWaXY)~qxf67a%??>BeqVZ@VY;@%wZ*VG zoZFzqv{Dz^N;fKGE^=~f65iDFiF-o^)5GuEZ%DFSRXBaiPk;XrfoWU%6GcldFmB=L zhVQFdWSw$sUNev1EvW>aNuSqhxRf|ZWbh||&-S}<#{H!B3C-pWf8|cdvV*pp!fqS? zB|X-{cbTMb5%}fsJ7kD3&GVAJd+lx z`@CX`_CHYTZCb2u+_3KL=D9pKy{rFUsburhyL8EYrs@)3wy3JBPd>~7O+fFu&YUJy zbe#Dn8))n@W1C!(K<#e%HD5k+dn~^>EmM0>ap7CFCkm3frHUOlLK4z{Kh2x->2L6P z!!1kG8mtvhd^?8kbG2=6H1dn`ZeyDS2#oX7|4I8ZF zctY4fi;j+eklV|0%cE~c!iodw>W9Co&$zsJg0-WBL_)O#w2|Y-R%(^7Sx!Of&d-De zx(uZz=cb%V0A-?$oFy*$o2<@zc%-uJ{>`igx%K|(xe3iIT+b8kDe(qfp3h_%y0SQ5 zGVJyI_xDdKyzJN&$z$@HabJeOipRGnm-D>%?J$A22|P8pg3(&pHE_aH_S(~a#tlyb zo;+>cu*=o_XiMVBIhH)y{~4FBydRr%Ve-Yqj5Dv&XVi%a{ZH3pG!~z%5~IK7Goug# z_yq0d!jto7v8{}8C~rD&Mf^@{h{u9Hj!$eQ7c|3<$Q(YsAz%LR((C?#f3_B1^kP%4 zek1)+qJ!m!m7Icd!d(7{<;*v47(DlA3*`8pNv-V@qQ5sc_MJHrMCrF&&=~jqmOFDS``vmUNpN-R> zX1;Paj$vOXapT&~nT$u+WXdy}~P=KVtj z-I2`)w{siKW_{HBjukX@m*)LT=$-^O@?O0ZqhjS}n9uqHUGz z1W6spY0pT<1aPVG%`y$_I-k&RwxZ$6!uSvlq1|Pv`iIT8>wmb(U-J1*zT>57yLW0c z8+xyMkTuOA?V;WghqO=!+1YKi6DF^cx#m1gOwj5s*EY_%jZO@&DjIqkO6~65ZIpSW zykrsMy9saD%bd=Tx$@5^heTv{_=>>hP;DccH3WE<1 zC}Q8yc=rO&rGL$(P6s}g2^SuhUZD({r?dVg#rJd7O=F2q@9v~mRDV`GytlSmqVKy? z+6hk3@hh|6$LyQ$=*(*L#WwYyOIz-Nr?2NQE#gs_Q~K3lk1!Lsv7O-luIWxkojS*v zyEm>hoY}z{^GdryOKc4fWKc=Y)8J!8>4U=muO=9L4sqWyH&TtuCh5d~g?7Q63(mPe zwS2I4bMbfMEgK7rUif`sUTrx!hU-m+gIkjCvtNcjeY+b?6W`d>&RdxJQcJ}0g6<1` zxqYb&_uKlEK2KI$%y3DY`D{J~oO_g3*-y{S zt0g}%8S2Yfam6}kuI>L@Cy?{0+o8NRrzK}oT*U1&3|4*OEsl@8_DtY`&P108iDfwN z>iCt<2D-K}p`p}Hgj?ZspTqb1Dd+yPh83wEntITIu}Fv`yA6Eq@16IsvzoP;>w}ASn{zGC6ownmiUZtPb_z2Y319gMy~Uwu zISce4>|b-Ew;MEAX(-sF{wiUcVc~Hu^I8>K+fw5Pes@dRjiMhfYx+B_F6YyW-*)HX zty>;_{bY1Pu7~~n#`Y7Jj$P&HkGD&*DF4iJc-7w12fH9A%!F5n7{)N>ec1oYzmIY6 zX2#9DYJJ&hpgav4Uv!#bk#S9h;l}YT^_zMXz1S`#YM1LK&5&SvDbmz;zx8a#jo7IP z6`Xs##kV}+0$&PXEMCI-uqgk8?vsf>k0RD2Y>Ebr$fYx@J$uM$8}a0#BHOpk6GFd( zR_&V2Xuk5M?mLI72Iy3g_9aWiCarVato$O8HR!T6YtgF+|6;+z>b03{7kS@S8WzKB{A^_d)wy=%^E#NbtKKizZyw=bDS2~^rUuc zfb{u4*BiD^(3VSAU`bFb<++94GTk2N$oI2aDg8vE5)R`FcnSw9dRG(XHuQ%Yh$1 zf8Tq&6?EsxKIDr#K*!BQ#mAioEiL}A=I(8YqKM~)D(u&cefHmEzwk zIP($#`0${8#6PRN{6l%3>??I z%N2_oA)Wg)-}~XG1kNz8{C^?cE@9f?BaX56Z<`z5exeh0vX4i&aV}4reZRz-XI4f} zq#WNdc}B8Y*72*%XP$E2Xk%)F>_%>5nJbcpGr0r#lajkN0@5EJ$vpC|h_y12E$Pa^ zD+jFP73{zh46l!?)_=a|%XXu+g-3)TK>hGthD*uJviqx3j@7JL*7)vUgD2={wo=HuKx><*cozPtnCvX-MHd# zX2;=%dz=Ti?%}$h+5)--TBI?Ot>V?ybFByVT3F5Dxshk>{@rH9V@IDU3il`VdE2h| z94N-{|Z%>E#JOuA3gUyWHUW?_#Gzo3rmW9>d#R zAJ|0Kd}g$oCvLL);#=OxV$P^#tkJ7jgFb)YOZp;y=VihIIfr?SjiqjvrcE*Ch_gC1 zVLJCs`wb<{Qq7HPm2Lz@vbwSfuoYhOZ+Nm?b^3ayopT=CzStRA#2UQ$srH8)cSg-N z)j&lJxu`A4mWOw)=X=om!tD;b#3LJr%|RVr!YcKXRVCN4S59NOsW8K$L+ly5*^|%z z4JugjlXjFRn>LH=S8@I~D~QeXZN!F%SjCjJw#@BX&6i|7+_|oCI+_Vz;biQb-xqf_ zVU~Q?qdd?qiW{Jg{m##gYraSQFK$y%KH$;9 zr7fI&UI^>$|BY|A6{FlTH9O%E=X-~rhkF$lUK3oS5~1D7*y1R2;p6TN-W-m9ZrGjh z(RmS~b7Kv=hs@6uoeOdkv%*h!RCMI&GOsEA_(XY0vfknKtYXZiP7YOtr{Z6y1~|NG zd9#-%a@B)1tNR4^Z20ZqAoMw3FF9h8_bsX18yk1?STKBA8L{CU=aS%0Ee|h>N`mJ5 z1@|cM>|$mq;?d8Gc9_e5LsntI!~ zw=%YJJE7!B5>mTPOT@(FNXFIdIk$l=BK(k*e7>CHD;`11(1P}qQ&uN>A|!U(HSb|v zqQeeebHiu-mn+2{e7EM&JKI01*}fHhFS*W*!^r0Lre?-%jIt%*m5WVgi^_NArOaq3 z`_2yQ8aK*b{GH>g%?w==dg9`S-}V#wAF_77zr%d9`q8_lznhYCJ}szr^lMvgc;vM+ zTkizunm4-ub(UqzY?Y@eUf3|}pz6`N2W$C`tm$1C8gWlhm7cwEuF5y+g1=9moata@>m&X}&ta9*^YAm&LSRQk* z?*{8i$9EM9@`tNmJd17n`t*RCLcx{G@)5_@TJp(A8n?!@ZQt>q-?<}Irt4~ZLH5;&Hp|0}gBqr6~@}Gdov&ZvI{uA?obsW_fLQGvgK!?>Navc>%|nQ*3gYEw}wu zR4}}8S25wMy29Me`(KIiTw&XA?!-&83mgW*8TSju5e|7=u!GNwL8BM5zNDU(JoQF#u541GRv)~k2)QM6!%F6vtitwOdtRKXS}lFJso^ir?0nr+gDDQN z?eAuDL|)^Z^naP^;RPZpCkvjPihNKjF~LZ-Or7I|&kfdAQ)9){PraHG0xLmB@3Mi% zxc)kO$c6u~+4*$_V~IFNSEPd>n-F78F{pyI`ORp=rqZ_Or%WX83gM#PLIuVDm>+z6 zeauT@n_V@_+@pf(XC0T9=_WD6I&fTOjmlz8Qoi59w`+pH7WtG{rDkkTc02sKr6B%J zX?|Df+fR0Fve9M+phY|GpPs$TNj>pX?8Jtnl0{XrYbG;pTJ5pA&CyzZ(-z^`HaR~< zbA+wVti4v}%Hyv63vq_SlM76xb`G-rx6jWvY}l}BiHP&2&DI-)nQrB4bP8_R5PgaD zZnMOkr2@HZpe!7bE%ju|Q6|uOs4tD+*4W$k?J{>Zr=L%(c+R}!ndOgVRUVTCKuhDn zXNGq0zN_ibI&_zJ*LCJ&p!`|QGg~U)xXL$E<_ZJ;CEqSOo;b)-^sS@Jv&=)y`M@+5 z#02rH98k}E=Hty4)4&U%Q@I>hkqelooM z{Nc!@j}1FJTW=IJ%WmYhzROkV2I~(*F7W1b%yO)_caMwBbZ-b-WngMSd-B;`t_N;w z2+r+qU$1EWb>h?9W`q1Ub_EPYjSbDsoMF$CCbQ?d)qkDQ=y;RK=n)HKB~hJ;{)Ld3 zPYcezJpVq!AjH9ZR`a*&1^U~WN`2IF4!)W3fIIrerZvIRioKEQ_2QtQU!u-=OLOMu z7h-LKkjr#m@J8C-u_+Y|Gu?V~f@@qV4%*$)mc#A^6C-k5<$EE+cm zZ#s~pz!)9YieBp`CqDA8$d$OVaI(aL%Nt_MEf6!%B^56u0_K<4- zz7X!(XUu7AF*WzOD;Dm2e=u~zmdQ*%%ef5%I2~m9Q! zB_>*{8JJ%8pO-LWN#fB3oOg4$Af5-UWM%?;{`37!h6mm;F_t0vYTqS1vM?8cjG18U^W8JT3gHCTB%Y zLc{%*ec76aU%tP{v!IU+v{=dxG}tuz)8yWVFXT=f^SV)_&8EXprhXzi_C!<-+|bw8R_ z?eNpg@Wip7kI&4OlxVnalF{j?w}GkDDWS^|d9>}jI3Uyceu6GPT~c}h5pB?*I(T{JAq9VbZq)u{uwqo zonpIeuiaY6<9?p$vJm&PPj}*%O_xZ3Y#S=((LeD=Pxr){+k4)}OE`G1O(<)!Qv7iH z!bKUTS2YcOM;}d^n$ED5>DMB~xq_#czLwBYR%reI@rA;oW=<1jrdLxQTyCiQqxa(0 zjUBUedAhX%{1>;JEfLrx^S4AN;yLp&{%f3!A1|ic2OL?qFXe{@Yh>)E++y>?vsULz zTszyOBOhb7QMAHF|HFhy(LZ7*AKBS^P(^sldBH8|F5Qak75ZOizFaPOK(=?SzvR8D z8uruoQyX;alaqf~%Wiq7%ewkt*MZdV4Kw*CAf4`ha5>u*PRqIcd)$@HC#|qxEw!64 zJvH~^TGrRhZ@)L>M%)*&ZdH61p?LV_-$ovuqDG!S7w)od=wtQ(-}VeXS@Oe5)|c!r zYk5mQ?msLnAyFcs!M5_J9?vvkMdK<-7rlc_kzBXfnXJpUZ%vhIuI7CdvYGWjT5;n{ zedgcs5B|m-_{a*{o?tBlx~JKAL-eJI-|H64?_;$p6EArrddB9$%J3Iy$!{C(*l|Rz zSdrCVwM=-$=Y=zwBtseIG8^RbrE~?KIymv++o}_qLWdd+d0w2}=pf4*pw4`=DB?M@ zN}KPzOA@T*b`$(|G0CpvHWuFbxG{&{%yfd^=~A{QlAxViC67cs-k;;Xn_!tz`Gt?m zL-rGA#0F5OTVTeIXT1k5`YieM|7h?V?q{&;dp!zdQvQCp8Io3BVYkqJam~8p(p}o^ZCg-hnYHK?W!g*USn)zWrQxqxf96P*=Q}lsAIPXXq4>9 z1Z%kyjy=A-E0QOj_|TMS*Q~+(skKF+_Qh{Uhq?X6(tHi+b_vg#%omkAyX|w3zR+p= zm1_$>OWB)ui)PJCS<3Qcul$SU$&FU>C))gO)HEHur8-NaI^pydhs{zutP~gAoWR?( zT7t<*LDm!6FE3&MZAxT*1-j1S#N7V#{tBrU>wDDpI5VAEy5St>t{TxT!bv}`PfvXJ zmNUUVD{<#rnQNSm_I=`F8Vme5-fSzGAhBlhC2r(NE4~uY8H5KtZamxlUax2RwHaa?Wxr0AIsH)w2F z%xvY(TE+D4)K_jvJ}*OqH%|nTDoUijy6k;D+sv>gK`bRe*-%xvTqnvnNHW2D6JJiu zc~Dh$yi71r=CpI0MXm9UwZ`YZ8`p$faJuQ^dok`7tXMs*_3lOo@d{M=yOjG1$-7;@wib=L}BBlj1zGl1?zGyZd$zXjJI=8)7Ze+($Tx4; z#j)dXA;*=I3~ZuHikmd+YpT?mSA_^3-fKKz@xQ4)8|1(8gVxLnGTxmaEUm6~=3oK8 zhwncokM=a@mvNJvToePQ9$aD4!dNEGQDOY6c{^|RYAY2G3LYDjUvsP5Z2Cik)*456T?LG~RvQ@!FJKQi=P^cxKydQ?9)D7ZhREasiwdJR>&e z*{21(bPVO(b@NWx3w!3G_T=ZY>UJnyv33-w0&P1LWRf}aV^y6{_Lin^Z8{&DbVM1? zwh2^QD!#bnc;RID)B}^(Cm72saHB1;a*^86^1=4QBc}^?0x|0Gjnk6mCOX&#-SW80 za!0Xq9e=8V=#t;+P1Bw7}?-g5{Gw zE)Sk9@+>WmvH}9~*LF65=egJ)Pcm=ltIV)vHWQm0p&0e;Z`z5F=02;>4lT>xGe0X` zAr6_O&5;!ka9<)`wVwTqE@vp2+W4F#a1;bc#p8@V}|Bgvnop_FXkKe72-NSo5sK}k%XK<&I?W4B~&yjqEjg@v2 zs_LT7=&-$iys}`mV^-)A1>;Q6sISn8x%@MnZV0V?!~VXbi|>L?=jTP+McieJ)LGIb zGVD7(ZLMl6=H73V^PeU2dIRKO=wRUrp$cs)gY`dZ1RHmMys-6j!nV27^!&=3t>pJk zmN&4eFKcEj5ef^bGmXj3b+>5F(s<%=)t^6J=k?o2V)t9kB4^#AGl<&Z^lfvu;-0d ziurb}4@<0&FH{bgQPKS|h3yHS`~Q$5p0O{=n-0h{`|_UPxiII;-S-oev;B=G@bk&s zIk@2ONBbWAXR~F8 z+x-gg(2a&!WyxvK*uDB8HP%gKg^7px*mANSNh>I8xIepd{8d~;I@1;&?nuTWb>MT+A5wzivP-jxPCXFhgwUya-hPOC|v z6&rT56IY&b;9)4W^NY)3DKlzNcDUR)w_oJM%wOgC&Rhwpp@nTM3nFgMaprL}Ix@2} zPk);&sIr!P8etGKk9p=(#!@?nvJVK%ujacxXMLq zMR2KR{kqJkCg5Abgv}BBWxG18lI|MhH2*q!Z86W1hK9Qb&i3lA=uHCE!<`deXs}Cf zwcjal*kgj!@tqU+u6B3%HH95p8++zM@nO3Ud*x45J6te5G%cyo?=aI__CyH=hSwbx z=YQ~StIcN9z9YKeCeH;S?Fjbfkms3K+l+tM{Wu@6Ao7etB&r6Y%rtYl(H9 zwn@-C&#wJ+D4#NCs`TN-$rC<-4?x*m*?l>t?X!Mg^Y@AaR>BH~DVq}?DHzU(N~!$t zPvAwx0k6MPD-OSUa#EM)56?A`QBA>Zj&RI|+)D`XUX-*gu&jLO!4tb_BCkJuCMf!)G-la6?skrR#5jgTb zk-_ZQ)0>ii^!}tUl)5;~6_}8kv;3>XwsSLhx0#=2|GMIhs3^DLA+{@$h8tVvRJ7~$ zuYKH@!|8v7?R%AgIeOB|pHk(`?qvlJ!! z1W_B%AnVIU)Iru=JsWl%;j#P7D8yU}ITuAjT$ssPV+W{a zv|c_h>Bk&Kt?8Fe^d$y7SH3H->B-M)yVH5joZInS0(7n^c*#u8D+fN8j`>Lpcez13 z@@s^DZB}{kRQL0T^Hq(p>{c(io+V#cR(#`F@eB!%IME%7fA6r~T3++y9Qz5g3w!0G z{Z1Qe%zCysqVE3}mp0$c3f|&>E}dI+LfdGLLm)To_|i*E-UnW#t$m*eUAovP*^yf* z>cMw~^I(}chX%#}6ln?Ck-I?hfk6-#+Id3v?l;cas-OFC?p-ykV4{hVLhzbQo` z$rs+UCmvwD;D0=7n;Exr>c2JTd5&pLsIcaWJy`JXetMfin}5RAc9$N>eY+gLhB|1y zyXolI%K!ZSJX`y)kiN%q$!(IdWj^}MQyFsJvlks_x+1x<<(}ZB zx&n3BSo5afU24qJU2K`>S*5bg>}80x>(Jr1Digod>oz2iyZT!EDK16J}1 zhAEW+>CH3v*gfPk^gDLuNii?iOqu2Cd3bu`4ApQ0(`t!^UV(%U^X(a5wj@Nyv2J3A zY(i&M@%iJez9H#OyY&jkx%}XwpF=+Mbwr0pl;jzrZ`v2N3XX&V>pJX_cV7uS{ z;8wX^Op+fqTt4__L8FzNLZyJ)H2XcTr4Q$49=UjK!|e-+ZDH!U$q|22H3MJnFWs)$ zyvs@@&p|!9(O}atpVA{I8+SZ8FSqYlLXI}a^=;4J>a_j7E>N!0_^k*u7vTyTv#p#U z^K0$%2Y(fw{g|Hf=yeIpQbo2#hiV6>EeqX`Gfhuue8<#y_dTQ4Q?C1-5#PT%ve}Ey z71`LPZ&nG(Fs*A3)GAK*H`Z{_mvVs)fvrHQ9%F7TY# zWOu@p6;zm5GL@lhM0wM)X7ShUlJ^YnxP0W#uEB*jinZ^R8}(UBq*iE1HH( z>pt6gEtURZ{=p}4!z`xA`QN%8YA|!y|E-g=_{GGraT?8?L&y zhxw*tY-s-CAkBA{>2&j#lPbHRm7fHWXMTa{};rzCTH;^A0#f-%>we=?ii zy2FJlb&;DmelsjysP&3|zh>~jx=nnE9OxDo#=BGEf;RBH`_j(Tky-4ieB#&-t?e>x zOzbCi`ES%ZQ7aq8l4hGQ`|QS2tAuHeR`L_h9ld>f0*n5dReWzIq!?advX?tkOJ*~;RRiDe9nQXVQvBBFjE;db|b#&f9@_1mwXm` zJ>Ikbh?^I6-`F=L|#HV1vOv4Q~PQIORx%|V)|2A?*9(?#E;k<}1 zMN;_FT!jU*FG{XpxKykpvFr895QE7N<#f^ww~9uwHj!o5Ud3qQ-#8?g&O z7p@4nl?lI4(Ya8xX6|Rja*GVrB)REaw@dh5gN9oajQdnvji4(hpN8mg`G?zW<;%2Z z|KK;_`ecREqL7W4pt7?_A5yv53LZRiaI+e>ghbG}#QX7`+20;t)jVNavOu{!_2e z#$UMw!RtCK+rD#r;D~Qqmc*v2E^d&=D7EFv?PkU;EZvUNdK2HS{mH|hZ=3kx<2vy5 zH;}SsFE41|LGDD-0^XM!lFJ|W`6pM@f0tbNAoakDh6XG76OjE=9XAgC<(U(8n>+Qehs2)>L0)L3uaaU}GRwYa{#gO%PRu2~5i+d?Pw@vbOl zy40`7|ElH9%}ab{QjqbwB^+f=*P7(cBx}!^;FsLE@javeek&O*cKbf@+n(VD^#?J= zr)T{IU6#F)`6TEDms|XsyakHde%;^yTf*ee--CXQy6OhEe@oo?*|C@VW(&)#zZaB} zPKx@RJ(N3P^ZBVeA|-R)8lFGH9?AB)<^X7YVo}rq)&3fDjyD-`7cwKw8<>kf9T1HH zZJ(YiaO3Su<7@NM9o|(a#Jg~8`h0qKP+M`Zf^pu0KG0ST$qNjyrCofp7FZw6=5?-$hhJB7MC;9ek$z!w{n3UA{V6|A z37j-wUG?PCI7POs61zFxItQ1>H(JRDPMpc(o^~#M0n3}}!nT8+Ous#w6)Y#* zJn?Bqntg)oWM0+C2f`E5-r64d@bj%$8?(0gVQU40@}$=_G5dKXJFkUIWh?h^nA@{| z`ufAx>N7sgmNa|c*uw`pRQ65t+zC(jNd}p9-bqgcU6deuoZE_%yX4Ed^ zAHRw0iP@JN=kiZ5*%8bnlP*&E_T&bU8-k#PrN8YRilVH}J*ZXC^W68~^7;ws&J%js zO6~rbIr=#=i#iMcQOM~|((X#)t9)#k!Ny|tyD?7#xlYrWVbQT~4tpe1|2}z^`R)m_ zlXvn=P>tceubv#r_o~I_Uq$!BH=qCVXs>tRyQu&^{-$sBWzb@jlGC6OFeRokZ!73| zlm17UAcrxfJezdD27HBrIFtFh_>zV>B^SRxk$3j15IlV9_loapTtr!o52WcPcq#7t~6Egyh`VS+4w?A7^W^eO z*!tr^wf%xw7vKMBn8^uCRZThaij^hX&+a&TZozNfO^#BKBTg$SuiBpAC%d zf3qSs$pkWcJ9Vp1N=5yD7H5kOJfG%qYCn_}NGW!h%fDRX#3gB1UyUEsS8Fg^bK59D zTp{0&z0_@jwc_M(`Ba9xoJ_AI8-I#50 zy8u6QFa^E|Th7|xqxOQ{7ssa?HTWI)*CWVRqVx{395OoI#~_#hL$ zL#qAjA2VL!e^t|RH>X+p>#jc>r(zX0&r&e|)uboyvW*|SOy*HIS3_&GZC_#wzlZNv zK96Spl5DG;j1`X*Q#zNm?vV{s<~Vs6a+CyHvz5I0W3}e*wQs7Mey@6|VECX>nr%Y$ zZim^Y5~WWkrZxKQYT8(MQl2?C&V4h}wVwj(N=6{tHOH|~>XNs;{YtQdSMOj%~dUI`=qdF8`C{iu263^=?=xo~U+qsCG$^WuGw{)YSRYP-itQP9&xG(e3ZW zo}cV|h@4c-&K?m&P8tZeDesBFg;T-#g zC+6Q3TIY03vWR%|WXj=$-v{Oj&#<{))W%<}I8_0$wX&@d(mAzd7JlCSukYdc^Xm7E zK@C2uyIe~+c7nIVm89r<$drhCuxb~a-O(j-&EPO-IH5|R++)K^W=RfV_Ni*0e+KBc zRM+uaoX*HQaY35ja{GE^?(c!k3(m3s$hf!nw4{S9U&M0eHSXJ|Km2!Do5xsuiDAnW zB{wz4xg4*3JS^MZdc*}hS6;`u>D{*%C3j9wO?zu~n!zeh{E7URhvhMX#XR~ie%xhO`oyDis*~r0EZ>E_at6hq!x`Qk zTE>>*CT&n9Hcv5ci`?zNJ{Z9lHH$YrD>8-+dz^5%(HX&1&Tn+W+5Z63 z+?t~YKC~=KU?^4MxZA?FnE|r1NrfFU${oyY#rgW$>$^PhTTMY{xPLBF^xNk0u0o-j zX|~h`$phOuXIT_Xyn1|lNN3fJAe|?DtSgL}cC`qkINskX2Hou@IKk?I;hx=x_zZTe zxs(=gWm4J#Glo*TLsbfM<8wAEEBsD4z1kt?LLC2-y^2LyQ9KHUPl7i(m@oc(GWniB z=bfJnGfUZO*0UdR2c7wEpA^jeYKBW*Z`y<(VQk@9vNKOJyfS$3szu>^nt*Vd!sezh z$8Y%utfUrjbN;_)bzs43hD?hFzI&IM!osJk%O(W)v zKG#Sb`0eOqkgJ~-aY*4Idt^E6p2cMipoZ~t^RLDwMimAU4&UoRr)^y0Jh*KSWVQTm zUfH`-4GJ%;=}ax;Je>JpJ7eJuv7!#<6`vDLWiQQi zwG++$eYSdnY6NJ@4<}oRv6aW&(ieZ_7bI71dFmE1x^ISsz#QUc6y$32QL-zW2@Ig{RJ*4W7W(xof8MwS)s|{Lw|FPF0-E zg))y$n2WMmw{1SKSj7KK43Am%=X;Vo8@$<}+Yvpth~y`NkK9o(eIeFtCHwd6gbud3 z6G9`RPbnz!S~9M*VcyhpwBf)S_MFX@Mb8^SdueKph&eBN{XVuiWS-Xn={Cot1%Ah} zA1K=YcoHg8Fh7hHyjDWIIo}OI-WOaIz89+TUa~ zW6zuA9&C}pZ~Tz6^h^$M_HDKMe>r_yD#LgCz=GxZ=MtE9%@nk(AablO5|FCXYT3YvKo-vBy*bm z%OAB)xEm&V0CZK1id*>Xg-liA96mDl=LrO;AF>kO6wh;Qp#%83#0AP#j(jtB7TUqG z+L?pypB_tGdAG7D--m4L4WgM0#-@Ws{$hQMdfoHjb;$@&X60btqUGkI94Rx&}j>w#vi!FXzzcwqCXO1&kdebIKDce zdE3mm!AkaoEdQ6k3JTnEcXu6Qc$Lv`D;KE#mX<`!=zwg&;*U4`>8+Cw*&Fr$H#sbhq5A(hQ;#w2p@wq^mHGH8?VD(>kDqXSkl3LCc?E4cq@>U(nbOv|0r z7U(%szZ~ZZ%$W7^vbSW%%a#Lom|oTV&|8^UQS?OUu=4|+&Z(*?^Yt=zig};Xx^j7G z!d#vSX%|{sUQ8Ek`e9&rVP(XErQt6cnQ#AQwCWRAV}I4t@Q#D=Gp|GjTZoRfq|4Mh z5|5;1BnwKN95yR{U*NsrL@CFL$BdV_U)Su}`%nF-1;(euHagsOXi6 z2A|vK^vBG5c(}pFn(0-@fp?5IcNR)Bd*rHraVwc{aKX9bE0ZS}-*DV4&jvbcdPQSQ zN%8M~IoF4EnUPk_mAM8tcp{!NA7KPH{0?)Td|c#_CYR!t%=jTAHsW}5<1vPx(@Kig zRPoGVjGV%vxdgNy(pb0*ePFa{_k?pAYd$khs{Sumlr?R^0*)QdMK2F{wjE)lV+JW&lF4ftkv%iwLea-pS?6Uj0 ztsZtwko14&5?0ozzMZ9lpyiM=_L)g?7@ zAN%1?ypa)eSwTZNg4RMu4t%<%%Win3@rumaMxC21cc=LINcisG%D0ZE%tU`jFq6%C zmc7DEK^(W(nRc`OjmlSMwq;yn{K;HkQ%O_hUZJqprQCNVnB<((BDd-tHH`89eV*a= zX~x$U4JP2DDG`m&IOhwgmk+GiA;DZIyyEl3&-ybQFA5Z`l!I)V1GSEg3r;pq%bt62 zkDozBqU@9}{S(;!`_#EK%Y#lGtKoa3T<(;1=6yYnh$h-d2-KKU-Q2-+=10 zxgDBX6I8!0kmN0KRWRMKG|aO6)5cvt&n~{rv++P`#0`~1@68`{H#5C#&NXW~>Ed~vPfG(44I#c#0@c=t$(~#-$ z#%jBFbv1_zp1h20^Is=);Av<_FbC-T$4%N3ZYj-=VgudwjdCvRZ^x$Bf}0h};~n`} zm}C!EZ>f@RPGPlXc5Y>EZiu$N!`*bMBUF3=?<iN;uxI8gyOLgVzNL?fNS|Grq1^&~6P{b;}MeSxj4= z+}wA;?4=l4w&Pd}N!D7(?Fl((qq)St-ck5bIHT-Q;xgzYyDHh7%im7o20?bdc?&vBbT*mIpt){mQ(5+gi(Q2;PuT-Uw=GZamxQ z4JxeV%AXo=XlWWYOiTEChi_&tVpjIVW6&x=vyv|j4V}hQmHDnRl-sq0Jn(Y-UUk3% z)Ii?6VI^aERKs8X0Ckr8hIG9 zo2P#GZRlE_1(HG+igb$J?An~K-MnL(U2|-p^5N6j;*t)spo3hV+~i4mM9>A1ZnxC`b>0?9(XbW?pfb(dsK#$sIipITf~D z%q%V9r9SNCPEuu|Mlx}AJ&snqmyS8SYdLU;We=yU+3UtTl8*C#He@<<)TiArdn?5J zE44+T?rQXjjm-;!Hzxc_IK5$AMSj`?+i$&!vb$;?UGqJ$^F!7F?rRQ78~ixzex488 z$-~c|G_Q)FB}Yw80;? z&}^Ihllcci5fd5Wv)%ji+VA|ye4BZ~q0h$5cEM@ZvtJcjMc#lq!pu7l7nYqf*%1c1 z*r5`%BYnncffEYl>$neR-OznmmUf6|3e$}>tY>6E2c;BW^gn*+>dys7YS|JyCU&bo zzh-=5rmKOC)z&6PlW4 z&w|Mt9X89i^gXQo_Kv&aKl=%$ob7WDTPg0C7Or@ITHia58@eyeBPU7DvyDHJAb;dU z!<~l>vOBpiv0Il-pH#tcwg7Y>)SZtFvRAqH=|4H+*rv<$Mk4IwP4xpu9n5D7zj6WH zp|C^z=d_X;RRPZrSIeh7emu9~YD%^A7D3r1KiAzc{Q=&^r`&o|!ers`_f6n=7k9f^ z;?w_pz0EEmr(47zf4sX!QSpS`g*t)nmkij{%j;FPpEiE8`!~}W{~hK1j;7ovj&1xS z9}T@>`QS3X6vmhuPG;r|wwCHgg%8fKKT3k1kadp}vTS`L^NvPa$=&P@bNQZdb2{cR zy=9-7_@jN{|37K)k)W1<7Ent@h3mrE7keJ=<5_oV!aj+33Tl2O+4bj*go&>Ta9Nu`x5fs+6W?pVGsO~DI32@2>zWI#H=Y;M&a>-8 zhE_soyKh{GppgOJqWHgceT)1}*UVBZnySXU(fz|Aljt2wj5Jn78*+4O8~UtlJ|lBm zCibX8l=Q)b^xmq+R-nq@$D;XtthXOKt^l1Bw2W;}L&&j7j`i0I_gp(TEvd2ZajRxa zu0y&4W6HUfH8~yL?Q32zmKw}?s`!x6s!qIe@~_js*GnD|E!5X0Ho4(#%PG6R z+&cX-66TGcf_)WZUm34nAg<1IIw3-xW!X2r4|fXn4#%*it9rP{3wd~JWiD#bUh(;1 zKKsq=h8lH_b=+M4|J5B=P)%tx%|l*;#dhe(+D7+J*O;g8U0iNA!F=9*tCw6hZ@Gln zAjPPo`{zS4o!)hpAD*o7{romSPtE4f6Q09cx+kcHFF4KVC@WH+{`8a;+n3GLQ(}b! z4>9h1%m6xYTAt&VkxosPV_VagW6r+px>uP>ttME@z4+}YQNVEF<8HpF74Dhw6CNZ9 zROz2jIM^|xayP$CXRX&=nYNX_RXhun%kyogC4Ttk=V(~^I;_LSL!ic-Bg9O8<>NyF z>@QmymN@)&cyRpPFGVYP{dtagvnEWK#9Hq0O*F)y;>i!g6X%1{I3_ilyaA2&6!T!5 zGxP54+XJ_+rW!hNgL%45b`ufw&P(#&!UkTIDhJXd}uC@?sf zFK(XFV8yQ>^|#6Ki}d-#R~uH^uGc-%aOWX|{7&wz@}L7aLG6y2g%%IRK--Ih(e9fo za}w*=+ny-qm9gXWZlg0jc}(4nR#GP>ov69d!&b4m(qvIG)2kANawpJk)@KKgHf~lp zVXRW@u5o` zH>)%5-#`E17V{?kr_cC~WQKq)<gRlg(n^X&zZM;l(`?IeWT}uW!rzA6UGV;cH4*Wt`y^2;CEtfa~;nbp4kV| znylnEMDpD@!@lCP;B(&2m z@s0Q1mpp2=k~~`&K*vSAnXa$E%UsAAS@Rf_TruYl()v;Qo-`C0PYyQrfA8>_6_ zE<4Qa7hO2vY0^#ccY;q#Kt~!a4SAL}fw{rad({Q=d58V>Gf8%N$4Typ;V#m;R?k-Y zU}^Iaot;jB%yKjS`b{?2zhRY#&1=TjH4QpHzc3at8_#dx+HrVdt(4Jb_E&QrOkyu} zN>ESsjoI4oxRu9;Q+ zo{L{6EcF7-|I9?0iU!aBbnxD+=(9*<1LXvdDx+DFe}woA70N9fzSkXi+)`(C zc$fQe$!mU*Cj#!K9z}GP*qK3RNLCy;;_zLyaB-_JZ26<7N$Zu^&;I_fmF$TMLOI{o z9tq%lozkGJRHEte8!P201dVa`v7CB?AwI-#wRnG2bA z&Jajr|CGaKc#!c`O~bU#t=tc69bK-o3HhZNl58vy%?^?QJ?gE92#( z5+NVmjQQ+lt{ZL&NZ9Tc{yL$b`|Nj#A8REKMj@8xTw;0Ea_4@z{OaEck5&b_9;j7l zEHGs}I$`guBYFp!GFd=(z$diNt!vHE%n-I>Ze_Ug@j%*pO*H)Ghzwbv9-bzjH1svi8^bq zc+5D7Ju#&+;5qYbTZKZgm}*-GsSEzcna)-<^xbuhFKf-Qc+;ZuWb*n0vKY|M2#e$6vcf!W5+Za(8R zMnN&3G>c%SNal_^KN%#u&;0);7NpR4#BYj&l^S>7R)Yg(vzs%ZCy=H+1a%npSG?8h z(g%$WD1Zk}v=6BAzmD-S4M^H>qVY~heUcYHvxf|5#xb77mcwx_|Ng5Jd6?$2g64)6 zRNE(Hfo8CNZCuG%YInz3!Tq1&{m+f>CE_N`1PvRUJ-75PkCHEs2|K7rQ4#>%$+T_C z1RD?C4113h$)qD`AGgUL*ljPcS$4rW_Ke4tXJQ28uW&Nvy7af@xu~acih0<-XwkW# zRvOR_I!)DX_QGt(kROd_f^_=R19Eatu=`f$t}`5F(n%@dy%&Ev+^gVwm9e1Q z$suV6Xoa@F-ifQ zZgajZZd{S7vS7yk++$2^&uo9V=U((bUNv=d!@-|6Pcq^)osTfcfZEcw%&(ve71fu> zT>qpMpw4nVR>7dK_`3jGj`@@W;Nj>K%Tp7Jg+b+j%adrwQ@x*#&X~Q;G0Q4hak;0j zO_}iO>ke}{K%KGui|6-keXjfM%jb7rwb^n`ZxAvvmQWHBlCU|WD{&#+C813De4Bu9 z`GRxqn*ybp@AsIn)f->&c9__I_h{-herGc_ZuvXc=OrVJgTHC%{GS+c{zFEmz#Yj2 z%9RJ_s4wAdOL|>#fM;q--2nv-+d6T`+J-k@v?o->e0uNy%;1mF{3fB81?SpVOtfzP z^LRH8d;Gn|`;1JGi%a}a-=DKQ^k8Ct?M(X&d5$+XVlTuAOlXTf@H^Q- z`hsK5lXGl31_^ToZk*wGp%KSs#Q<99I`xC3Ku%smsgFtUrH(SC6`vd5o`}6*v}QTa z^T0Ej@9v#>Ae4SuL7c_Xi|>lcTuzbT$BjL&1ShpivRRjj&sKJn6`C#L@tkQ7qipVD zOV}Dz#=DdFjPlPfDr1A30ScNGT?Ss{Z|$%=`7PVr9@E*4iboGlW-M8vx6ZF)$q)0k zj)?5GLqaaBTa!KpvMpUcVdJLFI_w8NaoBG%ToYl_>*%(yf5i?|o@OzbmFK8j0beAvhn#+?CLJu=UWgT@;Wq4H~kSy|M zTFH$bb`Sm)pFfs8*Jhh4;i4>cWn+NbtqSl&PQgk>$X@w8=t&6B3!Druy7DM_oEDOw z64N#xwivd=ME{Ik%%=rUqxd6ACF|~1I0T+(2A}EB`j+)zs=|uTjI($fb4}W1k8%g` zziMg7xWW7Kh}A2@f;Ok6fi^?Gu4(u(m+{*2ISy=ZwiVZ;HG=LCJ#t9T zW3hLAyOW3wt;Zl){|HihuaDnf$8!8FEZS)qLosbe2edxpHYURUweopw)4;sU* z1WoI0mfUdm1*nv-1sz;)dfg8NakVDMT7tV=!teL8&GBWB+Y~ZK_&E4%x^y|4lN0h5 zoOjS=xWx=wqIzGy>Ac*NbL?x1KYkHQF>s0UmAvziq14DB?ZK4vhyw{lwqmPIH=KRO zt{nZ~)5c5ZC6_Ewd|GuO@J$qKALwwr zh!dD$0dKTB&E=m^2b))aG?`Cw$4#Tn^BJM5O>a&HwNS4dG@E@m%_iY{?SV8~hvjjN zS57*AUk(~g{4CG(eNMxXotBD9#?y3DIl8;tIFoPquro6rtK)vVEu71y1vTDuc4bU}hucy`Yl||J>d@k`s3OkO1%d7@HmJo;6%vNeLT8 zyA|CpHCm}F^v?L?%Jc1Ci?w2RzK3DT6z6NA`LFyULv`LpJiL4ZCbS8VIh5wJ5AqO zI_?T5L)UIcg4VN^DT7XXzZajjUxBSC?fjiX z3s$T+_kby;x_h;7lg(^LpBsn1)ihYiDD>>P&-_zGCuMWOBZXhvFUGbt%**7lJ?koQ zt?@`RQ}KgG;`&Z~9M`UIKmN+Z>C=l@6Y@RPkFDQuj@?5S+$MUhtkR#yo)dZPiMIX0 zpiML7B_{B1jQf%;+N)qhDpmAg9oo_8s0R{ozS}P zKJ&GU3d;^N8nNHbeg5Jf=sev{>l?Z+7u@6r<^4(n)9aW2H}%@fvCN!0>-r|fGybbM z6Lu5{Tq zE|*O(n9^9{$NPD;gCgWpBp`R)pEc}>W7ugi8{7Yy8_w$ zryX1iw%N>J+&P&MZ2|6d@gD{fAB&7!Dw$8`TnH&#qT#F)6wi6(rw3nA!wKf?+!pH2 zuk0pBqzf;JnH7|KJYfrmVFt^sj=pzqA8gi_a1l{#zO#V$#Sxu@Ofx~ZpIQI((iPuy zhz&GW20q?rU&6MSo5v?C0 zCWGvDZlmPW*Q~&W2k7$H1JC;+?j}fgt`LSFj%Z`Lpf;BK&zU*Oj=mm#H-DWi<#Zq5X$3p(r`e=fAM@@!#3 z9Eda&RBn|CeElTgWuVlFydE zmKB$9JIeAG$rgSVO-V?(ob916X7W4H_sAse9a0x2eS342$9!4ap}7V2cjrHhH+wS0 z;EC_^6M08KWv4u-?EKSO<87t)b;G%nopmRKrrgqaz`&o;bBw8||M1`6=8_Jw6R(t9 zakI%;);z)b!uQICGfccMmn?Jk+pBf0NhcB1LYc{Lt;k(+QsG5Yu|RB4w}b>^tP4kw z_`8i09-1G{?7Acio0V!!*mqc&O`9#VZRO7c-a;3{9`3dH*wHvYevXp)n%|q}Ii9y; zKicEXzTALiBTLhJ!N!yI4!b@`tISsmIB=lhFP||R(j`k1oF6!~)Q= z%Iy1(>ZN!jAu$tc>i}o__PDBRC8p7COFM&_m^B}6T`T#WCG~UGr47H z<<81KE{JZGIHAL}!dPh5j3WwPf7v<*NTslG{PYvJV7O=N$$cMY@=u7|exB*GV8Kt( zUCoZNf}kDmGN3gv`!4t&ZvvGLhq;Zo%e2Ipr!scw!E$Re8@0|VdYI5PNNl4 z*Sr4usT4eCUh(;#@QDNOlKc(X(qF_Xbev;nX7;G_OXg}`#Pj6clGNzelF!yzADF=W zro*Rk)%i@Tj?2^aw7(nM*t6X7-aUQE1ctL!4bvh6g=!Y`v2Uuov8F@y!#@6+xdJof z0-iHR&h0l(QDak?wo;AB?&PWCYdar)n>({0+rj;{Qn}59x9lem{xC3o;K#W^*vPh) zFDA42g;N{%=KiGljL_v!FPYx5JI3{~-e&*wNbt!Q^+L@P&*b*C2`6|vY?fcJG@R!^ zaIe`1higwncUl`Qm|x=R_n`UA2j*+XYpoSG%Wvp?p|E*^|DmRtwR{x~LgvQrZl6n> zE0A+~wL@A1wC%_(+9TZ#MbF#Prx; z4s+1vMB9`yb;Fe%jbaJsyj+rnuKbMnq1MpISn;Jp>`Rt>fI3T>{tF?eC$$PEPH%9? zlGC5%yGht_ZodV;2eahQdHglUKQ!rpMzpfTQuWhsEd9v8=f88I+J^_swr76F-LvgX z6JX&J;c#N-o`Aa1|B2X!xEE8E@{a^w4?g_vA493r4i`mcjV9STmtcfUi#D?1rl=r?2?IP-h6TjJ6Q{^jOir*7vC{zrDT>d|YmEt?s8VIzHl3N0_)Qf%N_j7BLBDRSZE>qZLvqqTda{ubbg2!yS6YZO2n71BW-8`ZC z_>nhPIiz}PK3jSizEE5;Mw2gTv>D$$ zEwOFg-NOv89UA<0G_7RMH3?4^NIYW0UY*k`8h@SpNInwpu)(yK&8((;V(>s1mLG#=MLHG?}k> za2ekcIW@jzyo&Ch7QJUzG@Cfjg3B`Tz@aG7)nYlHrZ=Q}_v-9SJ&npg3+I8^s z+HvH1wD5LRN2DHl)9?|rmYmA&6cVx{vrG5dlF zDQ2@u_S-saHv;!A`0XTi&*lV!l`Ho(#zx5wq(zep{wj1yO>j;ZjVm%VIrEBLdTPLI zzVgKr&IGl2vnzVPf{dYq_GTJ^4&uDq)+e{zppZ}d44c7<%Z)XRiXQp7Asp*c80|&5 zO@2FqCUsesEvpt^;-pvF+!w^0&YR~G({)wugB`z$WXxRtA0KzmSKM5&zd~B#h-tim z#Ayeq4Ul=giT(GEs@iA2&1H+;yPW5RvAlu0;t@gjPe!0+FX9h=u$F;Nrbx*yI2rvr z(x_(B=_C(*&UDazC&(Vnw@jsWGGCG<*KAeXT)FmaUBb(d^(T3*1$OeRJ^e?*;rRQo z^A07SHlA%bU^cs5)zNBGj!rI*V&MW=HZGpsR&vHU2^L2gX8k>I{b$A3ABs2f3?nNG z+Lt6Bj$&)$=lO7sbJw552{x0`ArtdYB85`w4QX?e@K z^XQp#2@{wtnf~AHbx)}0$UJfIsKh-R*N@UG9y7jjF>%N@KVBvRS`aq-DMM-02G+jB zHhJf_Jr!*~UruP07jshVxbv}LC2OhGh5kpZZ`mWc-UuJEQh31dqk59#{MAfr-cIIb zb~fKoTU&V4hOO{~U2$7&^-PH`$_nW|&1tLeGfhv}_lI%MftJT?7X_`=D@>U)=C`j9 z%G2HdJuh{}R=Fa14$$F?R-l!EX~sy4#UIZ4>99{#_HJvs+`FU%;iLszA56>ADo*O2 zDhPSO)$GFd;l=$P3%2Aoi#8Y66SIG`xvlqc=ugyc6*=FH`2Q(f^nQ0(D}3tN-yn{!;an*;k;nV<8YNUKlP*$!GR z^Wyl&LpqRp=uC<`z$8Dv`&0Dq#AATcs!fx%AXGLrg>MSPAO3i;)iK4W=qaQpvu(sfZvBHK4pc)|8 zWjfBQpQ(RQUU%RK=oqoWA3_@( zSC_M9J2lUpz&bG}h2zHDLko^E+!Q~!T;mACA)eb3Y+`e6omn6)c5K2vuF_0SP`Bmr z1^?qkXJVPJ74hWnnTCI8Eo z+x~4P4vusCRm@KuQ2Jym{~>t&0`(n-ti%crh z-pl+CzvjG<`~1eYh6UNbHhvOl_Ebx$)PbDB&N`D3w0YCPY|U+9(G?5Mxks=)*^v~$ zb!I-JWQs<-(7}LtatAkj-(lnY?}|tp@6r|CQyiqvJBl6nR;>WNKL=b%`RkrJ!zr%V z{2<9+;dhVj*NyTAtN$paeB+3etGOh4K_Nh$<;u?n)|N}BBYC3ImhlM6H1bG!PS`8( zM{5?3!kG=kl_+Ed2XVXNt zkg(fZ_BFLG-qIwwVQvrW>zW1;@V*i=_JiNbAV+;&Si|OFn~}y08ee^@=C07MqmMHt1%37wUuzl~odWOyfM^@1d z5-Wr^m0Zi-^XZ6{_t8z07;Epde>xel;PQG0_m52mFZ3o8ry}5dlkMn`kk7!@lKCpIK!rI{E#ia>z;;!R*h~e znK577JSNHET}lJ$=8_W&e;Ki{saCS(RNGzfKYr`()ME_0zsfvOlU2S`emMbYb|=l- z;rPcx@4hq4Epk0$xQAzXxsgp$GAsM^L+#Z(T!#*veROC7FKCUbj*R1U9;Nr-sP=uk zcK04o&(jiR7-5C*qNVIF|1|0;g|PNbd{ybsWGz_RDOxnEy;RR32{gvyw5I0hmZY|& zy&cI#YacDV{8HW{`jBe+lye_m-0^8!FT^gn;z0Euz++bMLYAgyiKZ zrZF4ZB=jnM?N9Kqe%iRlT3d0hm(ym@N=QA!ojl*)?Mt0t-q@2=SIaGV^oiIs=I*z) z%xm&3Dhf|MXMVbUwNl=dHpq>;e#d4p?oswy=rE6Q3;6QJN|Ecb3OpD0)$;7kd$?5o?Fe;|bdXr~-Qh}11v`sc8>Ef6@O~BFE&fHfx~pHV z%ZQV6cF;&!DgVafUZ}Cc^JD(8JLe_d{^!@G?Jj5V;)cVtzNWtWyd2GUWG5Bz38g>c z+{?3o_l1Ia!fw!Es-O!xpcf(iGx(Sz9ozQ!0v`wSOorOemMcCpzAJDzyW22d>4%=c z4aALL>^tgjEt}jJ%53zQ19GHviOKuJw_i)vS%n)&Sf(5AiLji?Sn?Jm~ddB*ILpm{anH42*(UY$FC<4D5R3f39kMeHnh zes(mL*sZ(Y{Kdd@>J-UOjY-0<#Tu>U6~3*joRItkG_aTpO7u-{5^6pz@O}A0`m*El ziM6kb>I!10T{3GVUn-$ScRAPt_p**WoD#+4^PV=8KRYn&Tjgm+X! z7Ktp7Kh9lj4C>zT%0@2$U8L-Hcpe#kKOL#E0`(Kb+=poXa8k;MUvx_l-{llr!0ito9`al=Gwo zoNN-gFhAc(%Qdc4a>I?H1a%fOX(l7ftxM-HmN+V|IE+|wvs)-dY+)a}kL?Q3ttD^Q z9tW*Z4q~o(aL8InVYWtRY!mAx(C!}VGI5j7jjyK_--uO!jO@KV;Ff3fuE4(Fts3*M zli>6jM@?t{P!`PY_^hJz{mMQPe4H4#G2_=ho7I2 zMd=TL=9z0{Hz+q+8u7nwcyh%rg(260eJ1~F@ZI6Ed^hU&CrDk`xMzW_LU4$}*A=W2 zy*D^iLHb08-v2!C*ziJ~;Dxw})#(kV6C3C92OMW!^5^3FsUP}|ufEwYacfP(?BD0} z6HlyYIdefzpC>utUHnmoS&Rp-ePo!~=qqFPy77*p;*$Eux6kt=rMR4vd@ynMgD(sE zsy;nrD`aQm6+NOEu;Cm#=3yQSWfy{vgZS>Rn|`C<#LR_O@|Tv~vq)Au{PX^VT8p+d zzj*!~D3f6R!Sqo+AwEas-{As_eJzQTxKy0Q*>e&%a5>!BX7c!&RvXWYYg1BdvqAR| zMF=G9mi>EC&ST!xV#CCQyBnJihOqAFiDETMXt`79us=Zn+!Ijveek!l-rQt{mya#B z%}?CF#)vu6SV7@%!d!j{=_{Ox3m6+@Pjeedm6_5;M4N54h(}7JmHb8ae}-FBl&AgiIP;Z#x72+j?Fmdb(msoORIUGh zFFhi-$HI}b_8GI7jKRnH1N+=g2zscVe7d^{e81**=4Em_A2-S@0j*)KIPhVL<9iR$ zfK2A2h8vR3iLxE#P-naFaW`jJhjh5(+=;%ozZ?D#S=?8V_tN%|!XDY8&(ESCB#BM< zBg^*Umgj?mz6zE0{&&0=CwOn10N%^~rcdBP?sEmu!R3FIcG&Q~p3oxKm~!u`nM}db z1?SrHxRy*}xyuaNAklZ_=vB_fQj>yGiw~?eD?V>DW!lB~<~=Xl`=+oBpXN*mX#*Jat=%Q%~Q93 zdDu!`K^WY6PrJ3~^n_2WSAH_g?O{E{Ju9$ZyX|a=KoR4wmk~Gg6po}Go5^b}>BDqK z^4!^`H@ht@6GbC5GtyX&fUbr0-aJXDyP?|AgPZ$CTQO+eYo>zbm+143za1w@e#qBg z&2_5($h|e0JG!eCe5G}Q`o5yBh zKhCgs@FTTp*0I%`Vq*Sz;LPEchi7|pdAg&g88%qSPHdYH%5(yrm3LG0=h}*(7gxK_?hp`-tf@F_^@+=ZS}7gylpc~#My$g zdD~{Mt~U(eN|?(%!4g~#=BVjaUg%-pb@$1+27yn9->f>!(VLD5R|et;auBJcCieZjCUL5VP*_Bn3trzFAyhvIh&AMRIvIoNI6D zl4@ph)@|Ot(ad?#UQy>IqEFgB{9dnE+OlW`M+DCmPR6xNbLs_*ntQPiCNt$)rC)GA zE5G6LMu%6BGZ~wo9F)EmA1Tbk>}mZ#=)vWVrQr+CvA@WOo8T6}u}y06yfti-HZyna z-8sK6>D%Mz?GhGU_4U5hN!#&&i=Oz6(lYh*Cv!aBl=zPN*)^F8p1t*(9=Z{@>ta;*h z!so$U#Rc8m>;KFFQ0pC`D`CR=RPx8CaHBWoX($8-Z=Y%Agq2Yr?#g?09N~qg zJ=poYoBNuUZ52$nsk_5$Id97SqcYi79!{G6`{==huT$mM9M5{oV^CZ1wv6q`x#N?w zCpbmAdGp*+WGppu;7Xh;T=LU*?{A3-*5IM4a+MX29erjw?^Bii$)a;(Wdx`ywkbJh z(w3&f9)2LrVF`1vWWx8V18>0jko(umh@)c5cy2aM=wsXSnbGu#Uzyh7FPp_B=GC_7 z%ocbyow?j)6SE@sW=Hh|PR-ZG4P8^YKP%4l0d?!;q_a>Xi`I({<{5VcHJ&_cg*SlU)qCo;& zyp*O~H=N|evSoYo%{fyY&4XlJ?@xKUTH?|@=XaemRCml&RM+Nl-REP_mr=dpZduY~}-!e&~ zJ7GWL{RX~S4;4TQKR5r{#QR%f5t9IOZ}j=N)QI3ITxD!)J~KW7-sh8t|}+XVXjbm+hU$#KIdiEcFQQLi=^2( z=Q=b@OS&6ylVv|Q%awx>+;0*x(!&p}Z7B6fU^-FW-te@+dxt~O20xBXw-e^_$9w`c z+2z2C1il`(cJzDp`)osHx;(QOv`M3RRE=-;SBG~K1TNWs{A1Hr^Wp&aX+zLfCHR3J zk<&J5%?HnHHD5`1-SWnYZKu(_vt0%L6B~ILUe%Nw^<{tk#=fhzMBa$|(s_f*bVX*+ zXuP7LhjNB}M~~5xMIx=c7_W40;BH>C)@9#wX3(tlT2O}aJ+rElXMrDw$DDxY%s(GF z<{V@I?}wM$Hi7MRPwPsFQw~{1j}%|uDVJH7wt&^b>@8n&u0hJ$x85&yg%wt2Zn&|O zdxBti#B-(;d+@TG-K^7XG9Fu6@GKPPRYDy|+BEb3^YuvyJ}oAbpgZGU9r*3oQ0)-Y z+pzfE^E~4cNuNgR+Dxe>n?=tua3%}bSB0@f%)79LJxADT#pQ=f6pk;@(_wj+(C}mC zF*Y9a`}>k_d}p|Hli}pz<9DMI+*z)0ZoJT$lJKc0?Z-E%jq7f%;xSsZd!cqKXch9c ziw8_^fBd=I{Dzn33oeHzeJB^jNOE2JU8{G*ea^|~2XULt+vji@K7VBML4*CrCC4YT z)mP4F@ShidoMHEUX2>0RMlp5=3mjMrlfRtaJ0aEX(YcQ9JAC{nN;}^Kjuyg+*^1_6xJ5f%jCri%(`KcXCiq z+IhA~r(UIuQ|v^}1v`No8+R|@eRjfogTxD-Xa6jC?H@wVLHl)ax54wfcUWJtuGpPu z|4(A}o@|>XHuv@vur=RG%xm*0Jt4;$@SM49m*}UXEenFzI~;%8^oAujguOJtp<-9A zeDn3hKkh4Q_`0E&AcZ*!hz2%1;CCrW_^qQadqmXTQ75 zx+k0FcCkhkm6lkhOpz%G=K%F&PhUHmxI!yXS)28oPiG=SsnY~g&~5UP9d%Y>MbDWl zlR?+H!H-eQ_$-^e>;5|Fz&a>xtPd;e+p0&%^@wY>teyh&+ zhO>2dEK9l8u|WoxI3Gc-kvt(QIzghso}&8djg;h_o5!2ppu74|8SJ?86QGgwGHI(_u?B@^ySaIccsdrpXxcp8 zsKHA1+{Oug`#zkiVpDzbaW`V%PPP8M>I3w>Zd(2-FqTur}8yzS22r^Pn?g10M%-E5o&)43f;CU_9aWXwvag zscXN3jV0tZI$!fnMjI4+XFB7@6}1mcnQeWZ(h^(t%`otYP>`CYae6~TwI1jcpghpQ z4|-(^=)*?LJy~ZoFRlL*a1GrkO6U zE2~5=ZJcuLSe>G-US(x!A)7#3WXa@*hIjk|K$~0}YnJG(>tkmYWq7efC%~OKO=QLA zjoM}EGhT1IF_-b$%N3iprLK6>oKyByb5r6D*&lrwxBX+I&whBXoAQ%q&F026l20Qm8y?^_Z+(9elR3pvp zY?E))zBF>aUgU9Dq~wt(2Y0upu@8G$Ktg%@gUxS_gCG<6y+9cG78YeutV{x$H?_X!O3wC^*@*WSJ-U#VTumnvC z@xB4=fNMOGXsocIk0WQLXpuwfnMr93XImPM+-P`xAJkHm+pwUIomr5f%-agog8*+f zH?W*gxZ}zEX1{a4ylx!gzO9%Y#%r^&zbs*Le#Opa#^~eBDbi+z;FV7;3;taem#|~v zeRAEgH2mbc_5%N%yG|M_`m?ft=Lz@|gL8~5S{ZMU} z)amHh{`|LU&y$@IQGp1W5cyGAS+i>r8ak6fN6y{ZW6r;#rBm_A zscg0{t9Y*b%s4gYOu^fenQZFU1=>EyoH%p-lxDP~-M`yx;kN2i`^j=u7R|d38(H6S4z3#PTg*`_>s#b>Qw2oFS=Kdy$ z!*={9IM!e8%VO(15z=O^p4V)x@xyFYv)Q8EI~-4?ocPDj$9Cf{^rY$O58uVGc^%+6 zyIsRr0kl@sSfR;+=NR(Ihn&LmS@)zdZHbh6nPgL7nn4YM(+Vxvo^Do7=H7-}0if-*OXe$?*5Sg@4JdtO$m1CvU#_I*Q z_G~`jtXd?og7un@JvXGPu6%5Hg73o1hy}barrg?|CisXgV_&)#&jxFUQ+*Osii% z>+=jpQ`SXw=Wj={G#~ZR7FjO!O^M5hFXOwOLj`~H&!z@N|^k1JTpmq#;k37Cme2D zG(iWn7yn&^1+%sCg6Ip5ryRD=ZGJN0>BaBO2YQ5Uzcf4)Dp}80l+LWi|GH(t`JMw$ z9Onw0$bC6uA+vD*XO^u}DiRs2(-{5tHI*7Ulz|GZ-sc9t9cof41Kd+~*}U2tykRDv zQ=W^xEVs$)jsFdvO*|Z7zA%1%^N9ru&Ur?%r?fp`D7eg#1HIM9>Mz%opP+U6eRo~14rwOx; z_p2Em_}2d5b2%9yHHpDpq{cqI2P8_z7bLBd=RL`+qjf4wGISpeM#s3b_{M zhMwG!rJ$=O%N}bmPuD1jRNcT^@$zpd+l^R-%G8%U`4a04Z2oZEbhsI7IyLd`#8w`6 z`P?Ld%TH1Y(ixH#NX@94@Mm#4zr>RzA`(n@8;^&-k2xt2&hcu(pQMPBpQb0qHwZLe zZY$^c&idXsmpP_IZ1-Com}w0-&TMwM(dIX!@$UDF4F{9IlMxqG{gFj$veFMVanb~2k=QiE0e z#y_JMRt}%Uper$Ma)MT3Oj&c|^abIEJ=ZlsXM^Us?o<7{buLr03iG#{&d5vDtrH$C zh@7Cp_KMlEfBge%hrETdd%0iLa472To^jPnZS-a9)&@~gRpq9KM_*s(QP?-X*A{fg-lIvb1faAlPj((d$iWt^KY6d zXd=zDn{#h^Agl9@=o2e#YZa>{_c5M6>+LkbcQs@b6S0D}nn`WnZ2x(Tm5-6SPqSoi zvfMea&at_t;KgC40(BP1DS?m$d~?~1w9`)Vu?eO=ik)LntbX|WPvM7iyN~B9&JBo6 z^xSac7}trFVjIq}n^ivX<2YdpX$6&UGW`Cb!EEl~JG`%IKw~|gYtLD?spbpX6`5X0 zkJ$EG=-LJLQoAo-6kqZ{S5NaWl{zK-dUl>0yn66#+Jjkd9m+*kd=@NTC~$b~g2@}~ z?$jMzP$+M)dkc5zEm81s+;6fKQ_udHW5V-S!L&12p;>`_cJ_ug*JU?q+cLlB8_kH4 zX!>~j`g;k7h=>r5GxIla85uB6VwYr?#C%bqGQj=m7tSLaBRBYQc>FuqyPSth>Jrbx zo%49K)$`fQ>?984%#i6|JDJa1=H&2cx@WZIVTRi+|DGPy{=mb|EO;QtO{=2q$-%D0 z7NO1W*b@_WuuW$#wfpvF7w_}KX`T*A-|w!G=$n7zxWW2k^A08-)MoQye6b>Sg5>$Q z`^g&3QfjPwB)@@Idoxkd`gG{8{d;g46$4KR6k=;AuFc+13Zr7ZUk;UUZ}vaJkn0CmS#%MYFTEWh{s|H@9Yo+4*UFZ2oK~7*-`O5MzE*qLWgbeBGHZZ^x!( zlNAr}8#x4DzJ6qZ@T2nyn@gqtu;^Tvr1hltxq@-R^5n)F20wp-u0Q7EI0HKnH@^P_QY9qT0KxizeZPLwq~k+;5^RKXf!$p%?8QD!CPaX!EKZ^z<_i&hF7mPTw) z4OjTO;IF*e(g~GIK&!ePicV~n11~e(`GxsnUU+a|8be}AeS?+S1IY>52e=Cz<_cWM zVP_Wm@bGPQ&pCF;A?DXO9k20$#}A8b75Cm+@N&j?o`x%HPPfF&o4!Z(w=MGvV|fE> zfk(YOFN_sVykj`u5U}$xqp|$Gg^cH#&hR+w?P1s=ucD*U=;+6B$)b+=&h?~&4Yi!o z$QM268WdhoxtH_cX;ZqWBI~+qd}nTlI?nCSmWxc#KcJ_Ta)5b;ioU@Q3uixOCh*aQ zkh@!%ulpHXi9DN7ag{Cdlu}q~Ly~gNvgSqx2XIsEpaUc5kN`JOfx)q9w`_~$j`Q6p2$!#OVmR%$cxp${J!@BFk*VpEf4oOjE z6PR@!a_)Btv87vIIsGKTShl5!?{CSP=hM>-WA^v{7csn%!;!(35-+tR5PZVsUC{3A zY6pke7ytifo44tx!Wq!nrmrjlcI^gT!9MfnPv#?K2Pe;#fL}El*Cza1QZB;62-HZv zIpObQMQ_zJi+)Ks%;kT=$NuCVe@E;IS^g&l$Ct6C99z>nUDDzB$EGW@ZaBPRxG-_g z`G)LR&>)B0bRVxjJTK<*Kk0qGppUIeokgY1oA-oHspigld&j( z#ZW!=DU-f!U)W5Jvb&eQu2_D((MoxNYE(PFO~Y`rz`SR}IrgIVdVP<_aOW0DZ|Vg-M|RG=vy!2 z8uQIr`LmTJx~@4aV+S>5gE5bYwua=Bw!qm{gZrGWJ9HyoR)9hN6XGHZW-%@c1h zhw~P*(SGhCCr(f-wl#cf%!%Nixv|H}f;sQq-?{1%ecK()tc7QNZOAoqpZ}4e)Gp@$lY)23w0w}!Xt zSLitwvKP6tUXxS=`aev?PAei}8%a!f9X&Gxiv6j1($vtMA&Fh`Gz>njM z(FN6(6TclCPH%9S&aZTwbwx7cE0-&t4t}bq@9mdSj&jUeX64p&bavdFv;%BjCFc#k z#JI^=@_;HLafPkr@(zz&BOMt*CqXzR%;nGdbmCdO(fo585=B#9J-(sp_aShP?p;Ul zEZE!=+=gvUdnc6fZ#(<)d*gC7#c~S=_jiZRxbGEaNz?{4K^*1^ly{4_y1mAlYE^o6%SRyte7!GQP>5Jcq z#jZ$XFr4jo4N@i0Vtdt?Q zbzM|uf$c8oTPJhn=Z2oPIeZMeUNe{6(X%+na1>O+e^}Mm`N5ClN7|RO&n36?ZVBu$ zvaS%^Qz%(-O7#CRRUX!Fff}EL`Sg;1ypU%WW0pO9yDCfE`K$PeId&^PH`Yj7`6yQ% zPrh4uqHc2Pa>eRQhuIg6A6ZKllsY}wEO~9!5f)+Q6`vh5)R;kY;s&5C`n&CaOtn9p zZs$-1JA-XoH)r8W#!@GvZQ_P!9=u8Z@o{?Z!=H;Pc@`|)wBROx(zKX^S7O$+>wICD zTUGl0L>!x{^cB$k3Y{-3?fAgQgla_^g z!n;2FG%V=VepIxgm|wv=x<_Qo2R6ku#S4u}&6rN3r zIB{;BCC|H5O`hwI&5R=?Ss1M4mrFX7H#D4Kkv-nMTA0atmH3jddyg2Ii`tpXp6H$6 z0nMH7->{Mqv;|?uF6U2*J;%i4f`2P6J`W4tlS@1)+S{;uKd|32u$8+I3d z^@77+&DvUT2T45I+a%$zS>~^~qc^!C3yO?P^K6 z{T637JiDjbCZKx7h^xdVzk9Ytv(c9yv8kboYyxiItlwnBO_0$0xqJI`!w4gnL|^6& zl7bUdGT2&XxOCL55`D2Fwxm|U^kwn1hSqY&eDD1qKA16UGHkQq3U_Bo5rZFL16tQ1 zH)E%m-bx-ZqQqTXH_JL3g#&yPN}84q7RmSe|_FiG%kBsRhy(9lbYp z*nZ^#*XZwhgO4AmcKEX>>EN-Z9|oTfdT#(Nu2ujoBUn%^RPy=fl*(d>nzMoK+~&;w zvwnzAJ_4s@2*6zVEf_EOy*dRFR$H$Y+R*IlK z;5$Ss*g0NE#O2K8XVYOQfhq*fEXt5)w7;Vz6pgNde~+~J7zg}uXQ-|+3rf>*OM*G#SPK_;|*_EIvI&U zTU?TCpy44Irm_TyDF)JW7Wi>`tUbH^{)cl%d)X)OwYD`$ftRn9nt|-vqYB5z*-n!si z`!2DR`QlJJZ-VWd(>?n*L)0Wz(3ze#3F3n9d>^Jg&}r1!ei+ol2VXCJLJxY6y?^4P z@VeU6hPNLRBp3>Q?l5D9uju)`Bv-xJL*&gB?Gt{@9*z;S1Ib#`f z_;coG8aLWXFJwk;uy)$;mbGz3{b`2R8(5yaS(3$d+u*2dj@*jFiVIjH7sW(BIL7d* zqCv%BE?)|__w~k8mX&OqR|v4(xU0C}X&6twe51bNkupX_4|~`i-HYFwdV=Ebly$*Y zXQrGJUh#dugog2hS@DOjDKfr13ckI!$x7}Bi@_(|mkaznxUZ+R?aW#EfsbS7#3wrq z<}sE8U2C&B@-mI@z|=nPZBFmFm`d%GgcN>TPJGYOc(;dd+jpK-Zx@_nUm-kkJ=aS1 z)7w*$E%=u#yUbqn`^S;nz7ccl3$BK>slHb9K51wBm;HTBMpT4RL!PJoh9phq9iJC= zMJRCGd(UXfyYq2l4x^drg1(cnZK*u=a!F-QlNO%d;Nbq@)asXpHg`(qIG#B#lt1C{ zw4{SpVhTqWD3>{&Uh9x^!S@Ad`R)ceA!`M_NJ*aa`S+3-N+mXwI`P@;J1j7ZJJRb3 z`_gcI+hY$DxM$ijoOX|1_=8nt{^gPh58s}y=J}q#DDK^@UC%5IvlX5YGKDO3PsoZ= zcM4MudG0)IpHjJw!(71|lh#bF6_#))I`QenZ$}3{w!0O4#TD<_gelm1|55CzX74vDqDdFlYY+IbZ?gGSCpaN?)zp7Hxqa(C@Nt}}0~O1NBXSvY9o)<9Yur-A zQ?AHg+sUw!8GOfrZOaqM4-AkKO&<5(O~j1cyjNvgO55nvD48?f5Fno7iA4sb}V&vyDj(jR?}6^ z9clJu@9%KGvjFX^J_~ht5oBle954Gb31TUy8}{jN@BGYY-6no_;{12}ndf&MJ+FUm z0pFfE0_D${7YT1mS$**O+{D|b3fM|TJ<=Jsyp*YZYzaC7(J$tc`TH};AGqRAGR%I- zu#$D-`nyc?9+f;`YfgXX)V4caVY!X0HM69~W~0EA7kpJGCfwk*l;gki(c!bi3$+qZ zI>>$g;voa!piUm1rr)%GW(zh(H&<7ZyiW5o~WnK z@|NY+F|HW5U(-eN{yv;MVd>Ou&u&Z)OPbuz({g6j|6f-Q3QSYtHsjtV!hIytpq34^ zJ#I6{($9^mI*HIl`5pd(PgHj6)>cDvo9l(%r+>@%D}IION9_3XNbP~oKVh~Dmo!ti zoMX>Ow)D|ovA7Ys%*iO5@xwX23q?9JBsZL6@8Jhsrf@#@);Wa<+TD+QzT7^yk%gBT zbW<<$g12vuFwEZCASplj(E$Ojw=p(**ey$(<#zOQsIa|CX}I!m8vDFQ$K}p5?BZUM ze_W5vHNj}}>0VGaHkqU_``g6#KM$1i=%0`S@BJ-(0^)RYcyiGW&Ma_ul15kDs2yiVV&5=BvJnJ0X=WrdG6XZVcZ-b>UtYf!CPOt8ZAv36Vzn2fxyWh1T`qESrQ;BEq z@1LFUf+I6UcsC1o3OnQ&%$&LW6K1IzPS|;A(+(y!FUE{ut6#@TF1(EBPq#_eh-Zv^ zEeE=Z1$5@gcETp4AFkw5E2WRvt0>3_7&YVR>ZZj|G$0I!IXNOh|VtIGJy? zyW!z`X%BtrYm$tzCx2(iUr^ya@-keZ*ik*c(clo@kwnG?=iC=8wsx*!PPua7uw2oX z<&ze&H_yx$JS_dNm`B0%V`}~fH+j%%@IOs{7o5V5e+g`2EIT!I?M(T@`DsU3Qki*(*@WIRIjz#^X zgIqhVGMX?eE$XPPR9x{`QHgga+f+v>qtl(x%nm&I?mR=E{Tn+UuAR$K!Flc761g@XUi+5M4Hui=ZYwVN-fShuG^k#3A}iDhT&Ds33aD*`DyQ*4SB&cUOFWTr{7&LU)U_t?7xqzMQ1m2uEX(XGEe;2 zU#z%me%$Jy^f_^MH^YW^{~zoto|EWmR&es3JzHDsoC|ykUluun&M{KU@Mr&IC-5aT z!rQMdnPYpeYhly7`}sWY8@nGnE|1}idw6_8d}W2<;p)zGo_7ZiRBUcP7h{oa^d@Ha zY{$idMvuR|erDNWbK%MH3rdCG?|JjAJ14}mppRpPa8r)vnqnp)=jq~N;Ykb+joYUg zh_KEw{KA-T)n4k5kOn%+?+JLPaPzn3oRt6P8uoxoSJ)|IEeZRCQ}&tm&C zUW_PxsoD*x;i=t5k}8iCM9wJfE=Sr?0u&eFxmb=1vQKTh=N%(WPQO&Fli^9imV^172zhJn>{aQYA zyp@N~b7dv5O@VUINz6l_<5*Tl?&)HTR%a0lhm6<5&b?6jvEcXtCw-}wQW=M$1)vom z74Q`x-yhgMxFr0bRJ!rkguX-SLc(I}`q)oM1Uz5-QYB^8@6#bI2dn)Yzj5!Jk+|Pi zWWLRdclkwj-ZTro0&-1cm7vF+&ZU@tBC%pgfF#l)6%ua!LPMb;BCpiYO z)Hlf3{B2|`W9N7=MLVhQVQaZvgPZ*y4om;IdGTC#9!3;1SLi5zXi6@4&NAC(L-Hri zTb>8Y-sr6WokqG~x6~C+&_WpjLe- z&-4B|_LVRFzvZPw%w)GbW?U1*+FWT^uyg4=MQ6{KL2c{v*gIz=J8c!c_R&GCwexNz z`_AW_Wt@t3-<$k)HkCRgyn@{Nvr~HVCy6VQ1*W&6^_Dz7U+Lx9dh=hw@?~4+vX|K@ z@V@GQuOJ&*rzp4~;yu@egoDa$+ROQxuO`oBtjs$2;WP6S6(z`JJU6C=H}ZhS{I@S$ z+%E5P$CqK_&WiIhn|YQVSbF_#>Wbq9hx?wh%I;l#uHkQxDe^*v+gC28IY_Kvc#;y( zUpReNDgV8lJAMil{oZZ0Une5x*Fs;O?TzJm2d(5c3oABT-nwu!6YWZfPhuYL&DwH# zoG$L+3A!I5skUy{0Rb_#mq!j;D`fn8zveGXPRT3-mzJ`|R5ND((|gNm<(sD(tK`ew z)@GSf&UDJz?4v)!yofs99r^{=xULxAbC}!r+gfq@l%hZPc;D4D@UY14KfSj~+_}u) z$&0(Q4;+lI)Rk_VDy`_<4LQbWf&B6AJ3lKva82qLJu>BhEMI^+bBg?$;wJBZH=R8q z)m8Ob-xYv%#n(PK$2p6DHm^MKTr+7$2Z{%`>h%~*&Rxfh+BJnZg56U zTxTn>?q2y5u81=y-PnDakq;Ctc_sSh(ZPlT7Hk3RPsN#^obiu%&YU6v8a7gh_VSQh zB4+lQ@%DR0A!j>I?wd9fEI8EL7TvSsnf+2h#P`MWk8F7n=?#%&yqu2U-UNy8UgzZij?fKh9W4%B1d=xX1k7{-R-PTob3w?guy2Ps}w~ zaE`4?o%zbfhPzFDXNzvcDxR3zuYO)Jb$!ngqaDthQuUWy`d-+VJYzrCr3aw3ifK*Y z%W;41cyjSOsO$x;A53f1Q*qh9M&L|5=gkFY7~T}Le0S1IVJ)|7nAH>X-(iko{@D%B z&S$a(F|3))c&Yfu!$7v^$}8s-JMw=^YHXX`m>7C1agH1N8^1)4&~}qAj?x!6bq^j& z1D#~?%0)xk+3)Wmv&D=-%u!jam+HUgh+T|pEwyuyasVx%UuLPYw}nwrdpKJ8_Gpqpzh^TRjJ zg+FHo-PSQJE?m2L!A3>qoImm=>sb-&4fOSX?&dc$+_1qh%~;OXan2MD(Ba|WU@1yz zI`T%%!_en?GfzPx+Cunw0SS*LonI<3kLyg*j}MKVj9b1tU%fFUakAu+=JkwwPBWLR z(aX4|tow*@M=_((^TX~ZCKWQ)ac;P=aqol)moByF%ygUX-+kk_L3S$>^9h{^bw884 zC7x79O2*CdYU;n;y7TR+S-m`ucqYtD2HlhU@53!Ywj5dh2{LAdM|e2JZ$v~qXM$Xl z`eefa&@~GUSHON&XHaW3H9^{R%#7S#G!R`MXaz za30utocX5Dm&+R+=JL<5d2z|{#>U;js}-arH!pO59cIyHQ1Zk|x} ztmLm9P*%#1O=qnC*&b;kP zR%DsJ-{%Yc_m5tG=wQZj;@fS(yV*9>E?b33nsbSypf+=Gp;dj zyD77TeOdjjlbsrIjHNmbb2~g^CwyJD;HF^7{-!HBbNM69n4-6}u4CKsg)3g7(Mmp2 zZ-Vb4&>fDpC+7C^=jR*k*>sm<-roahdY|5~`^cHSZrpR9c@5vL@1Q}WmEdbI*|eA= zjx#~7fdFk@xoYq+d}WkF{o=Sa-=Ez|Zi_vTb1ITS@@dM1H06^|wVb>_laVVvH~K33 z{7E|{&1T1TW#XOXqBcBjzd9zryELgw@?1R2Qt=akm75n$TYRGV4ExFDy4^=!xxrSJ z1kK@ndE<+pE$j%$rW}Ke|LmHL52a=uV0hJ{@H%i)PtuNZnIc0O&@pLQ7@Lon&Q>H8 zr$5R%VfbpnP5v**6`*afY%y~MBHWqd+nI0rO^963$L{myZ{!KR4W=I_L|>cu{x4`w zdUm5P?}}umS1mTxOOH8dS%iG(ag;uOtp>Shv7T^re%{~n3vzSL7ksySB4YAoX(;HF zUHLV|jLFSbiYNXZQsp;h-ek{Ww0VPkh1gmD$`f|{0neR}iBz2Vta(M$aDk*iztRcL ztQ&s2nr`y$7G~MTu5wPZH*rJr*Xrwr4euB@OWN*y(pT3!zCrMY`_%`w2RFP|Dv(?~ zg)4Lq19Fj-q6u0cd};M=eTDC94}5EAFk5VG#JGO>-ygFWuY7bUThh&x62@=x+tKGa zGs<|D>~`)=%Ef71;Hhol>E{zKSo6$`b$MUYaHYvwVS#daVqf!pPN%0KjrlW0PiRH3 zv+lgy_^w5|T+QIjoPE-IZ=NR{GPrEkpZI8^FV6x$kA1!J&UaVd)VSp^m;dN~GoH9_ z6ZYyNZDQiTH-|6gTW++>`2}x!BC4y3Zh5hN);STR6Ohhwg_F^eVb8&sc?AkheQ#_( z7l;Qu^qk~mQ;Lo})N1K`c#P@OvgHY~6XOHk{%*K_G2^y_S?=%s-6~k&@uw5}o&XCtRJZ8Z{^Qaa>^Vv}wCBo6F$K*@ii3TT(qOnKRm0 zuKYC6>_}ipypS1g@D{v7@V%ed=Y)=HZfipA{>p4RaxO&Zcj4wAPZEu#j;MqMJU_gZ zV`F6G!yx^`3qKc2IBb>&uUcb#$#^q8eMVEFE^OGI@$8fa5qbL(_^|!mfD>*dY-~3s zt!|wwEdkn*+QHo6 z(cFt^4il{9-`{igJ0vU=!dz}~PJY(O4=gk65Kb9}CX1ij+5`**Hk3aJ;Iy!N$`36g0;mdzgC?!`;4nFCA4TJPl7bENE&sE;s8ci8R*XXJv(8{TQ!CwS;I_UwwcFPxJoT+nIwW*z?% z-lsev3>&<;4$F!eoQYg@R6v^P<((!g`30xhB_~)ZRG)JQJNf3t?1KyR)*o0P@#bK| zYGJ0?yp0##-z&;ge^N_HI306WYBhhs$#^?v&GJ&;EgN4ctN3f|=-H~^ebqr$@QL4v zOMBBLrtFw0xq=nC)q6LnF={KnK)KxUlY-UUr!pa$ONvY0DksfS^Z(D@?8v8LuXLZY z>8(WE1V#CYI;^F34(^|u@_g9O<{jv}#`^X@VW@X9#_hCIp2cYnGQ8^u$+WUoAIh%T2F@&z5AwK09GxI_l;y?gaM z+nKI3Rw(hz6k|PG_uzGng?z-B36uEGg#0?-v`wPK@xF1JrNd^ChPhG~v;sH&o-Ltg z*B*0cxxVF0=!WR)4;}cJ1D+>ey~WG(`ue)Wfd2}|J}^{x%C7j#2;b^_k40`j_bz6Z z6tfk=N{e`2CeDxIxcPRb{WeYM5!+uMf;%WIXAA{l=++ z9hIWYpI|4H-7YLtb>`^S^wU4Ar_3U|x!aDJ=@QH9m;>O}f8vcN(x)4mCB=V9ELkYd zd&r7Up%y$E(+C@lSynzf)#C6I_NNZ2xX9 zXKZt?w~GDL(oI<#HZHh*_WdUgg9aw)gmqRp{F*dPx!rh$&wBC z<6HgZt}U!QcHscSt zxiH^{{iOY#^0^Nmey?HEbTwzYVes+f+|812cFG$xykojq&}AZjAWb)67suTezToz^ zB{~;m6*eT7PmE=>x_ovb=O&TU!ntj1C8tE!Ff(0l2DSCVb55i-fQ~$=Iq(IvM#HXy z*SbvH#eB!s=BbT0Ui`M3;D0;`bUxbY^;guL`Yzp->9u;x^QuOn+`??WOV5?xk1U?? z&6e6AdBE?)-VZT7H$a=kU$q?YI~HY?EyrA??&7?(fpOcPS2wj!w5?h#_l#$K+}!jV z-~Tc;=gbgiKK#U$=X>0q#DGZxi8nTWxBW1W|H#TX#7^Dj9akEx6odYrmY85Ir}XMV z>GoBBc&?{8xK(eRllyYsa)-J6ojD$ktu^P_e;MuxGoGzDmwy3weti3ypMh6J*t*Zo zx;9(Q+7KfERR;4 z-^B_!EB(Z}HGlZP_i^wmmO3T8V|dHH@n;yre9$x}+DyF21Gch<@j5&UxH&KCE3{W#c7*F%A;U`6SfdWeu&v$Jgxw9(#p5dYcK#LLqA05Zy6{IYzAn>)A%+F1TJW`;wm|ryt)GT@A z)#ljSc#i?Hbhb=*#plFmX}1eA7r-}(TdRWGA#a;_vU4IpH>Wpzn6O^==j`DZrqd{Udx_UHQc4&j?S zTAv$?-fCZcmcRS=Ky3^u_YzMk{Fr+XdDR6RZ`FpIetQAvrL8$9BK@3(E|b zFt@#3qV2Uugx6N_w1L$e$75d%nGI$6Q+|V1|ErZ=kQ2OdNhhb;aYDL-1RMASvm&lF z#Z2#}+?jo%;M+R!8?8z~t9YKhJFvHw-Ou>O{6}dGci%HYZi{nlJF(PpTYUcY_BAGu zwWo4d|8_ilbx)Ir_t`d{RhP1OtTHD=S0-$h-=NTPrXe9-itSzp-`pSiUu8F9R*74G^nAkndFKKackVjFb$t!{8skevf7uQnoM|i>kx*@)_w4zB#qw7q zHMeX^s5o<`tLUQwbm8goGDAhs_|J)-+nCt?t>V=1x z^+w&9>rS|?%AId)a~LH%`q*_89IGuslj;)dtQ{Oc$HMgRzG_i$=h|emLYQgNeB+Ni zhoA6ywEBQcZJBE?D=HqdF>{>G&M;_s^2BJ(Orx2Nj4wliBAzopX?uU*G;89YrpNpe zCDMwsv(+QC3{1A^yLwuKwm~JAZ=TNR|MW(q(pkuHE=6_|Zo8HH9^B)@zT}uLdy&%F z#kx2AtDEn(ooirAcvQ$W;imeN;Pn%x9`ZZN1X=*TZ2jAW8;cW8Dlo@f*WR~(lB2Gi zVLkh+hy!Nxn$IwPylAa>BFiD`;OUJL28~5m1liPiJ=j@MCd>Klt)1($o}28&l^r)0@cQQlb1PhO|cPu+3%`e3Dzg!-`Z^BS&cST9DJ*vS<{`aM8jdK}=o~LbS zw0`+e`Gi|yrR5v-hYL?Pr#nb&$bW;po7<8@?H!NJ!xjHo`I+|%9Fe;)3B2)Vt5jQu z>VAXD3!6YoaGyCwJZC;uUoJjL+!5M)(Y(!k^D^TsUdMMm2hOmTTXiXTH#!)rZ0LQl zVXwlCOAISMCr;DxdLi=?!l-!T3rxSGj67!D!L87YBCoTzLgL_fhjA>w~k; z4WjLBT&8f}{QpDp%0l&o#%VE)21OqZ`5n)i#d6b_eb(Ot*M9yu{0ek|cTtKh(s5Jv zJ8JtKwIaAw%MzEzH?la+zI4%iS@RSBdG*H<@;YwWvB0E*&-E9B)drp9F6NU9H!5n|0^W)Tede`Yr#=tP=~EZJNYkJHhv#|1DwCARM)K zwPLlD<7W96bNMI48vmCtJdo$nUMe<$nNw}r@ej?7A`I{LFuWIGysK^W_=Ymu+@ouG z^3}f@H>6p8(B0Z}lQEe267#Izhbp+}+QO8o-;?yBlo2JX1@_dj0O+WR2gB54<;*>8PK) zpVOu;nIL_^ae0hjG0*$X#nzJhq<0^F%lP(j#7d5r3x%VajykYq%wda3KY8jT!>qpw zX(vT}&MvZ?aJltOu0l3b;#`3V!YW@yC0=PON>5UM=kn%lNo!pjdS?+v1@K7B#;>5IDc}ey~7B<+mnHNE8D_$o&TCjOlQ>*~B^J0Y}1rd^7y zI<&k^dHN~IGGhh4`3$9Y&z?I@GgtEqN;NRumZ%`!kmlewzx9cBOnG_3nKt-9#p=(D zmzb>;xwkBo*?E|8*LUV;aiFl2cgS+6c1SRme&M~rA&i=qxLK^X`J43TK&vn-$jY>Ls<$qMPmugqt9An{e2DDy=>%v3D16QZc za?h1CXvMC%1AUK7W2c?jP+?{NVT<;OgW8ZG zCs2Vgr_a0Y;}>zBV)dK^i@IM7hbLd2z{vVxS@DYcgLC;SU6$9px+VHyLPM#I1JiZmoB-Vur50-N|}|vvK9k69$tVpUvZDese^7g3Yg$;Txnct!>!8IQeyp z!34$xS^f#vW*<1`UZu38wjI<1__*63J0Z(quD}o97u)acNo9asGqH^)`{81B4L|tV zO&j`7%{tsJ30Y9-%JEaObtm4{gijS>VT+@t^$--vsyf zc?J)xIJs5WcXbG$jEl-|=Pr5D)4CFT(C+$(o|~MEKOdiXEA67Xwt2ULciWr0A{$q= zpR{K!v#IG)6t#o~iX`X`$tyW8bJH72ohIlqpPkTPrOM;N6mXn5_T|~b{1V@M+H+c% zOTpFJI(E?R4zDNCmo~0!pF4rolGVFo!9+;;`c?T;!K(JRe;Z159JsDF%oV(`GQ8G! zn^D7)fG3UHml`XSIyn5cOE8vK_`9Hw^%G>orpcdog>ciJnX=C+E)?$R|6F(2T6}%H zvsA;PMXM4vCZ`rRJU;Qu;_2(M^N9zpa|W`>S-w6faDc(umixA6xWV=V;PWOx*Ls7_ z$ZVcF;c6^vq%q&Cnj_QM4I0emH~Z~l+UN+L#4p+)yeX-nH=Z$poq5Z9X3HW+_s>mz zPeMBy-rRNA_ni5F+gLZFSx#;k|rQt|ImV-%#^DlFq zX-#SRpk}TKbXP3+)Eo~X7xOnAv1~?+8T=k|SyK4vJfri&kuXA_=y6)+a z4rF1%i{l>;&Eb31B4gJ%)8L%n-TtDDutvN4`<8^@;>&-To3quP7zIJgts?0a!c4)N zXFn8Z{uFrPS$f2C<|S;PE$SB*J615-gLbEsyl3~}EjrE|DG%Do6_#&(M1lEEQ}>;Z z3@?M(^K9DB)-?QBaIU?ZGij%O2mkAq2FUV@vO`w#6L#ARO#h0u?xN#?uV#Tee3qhLm%RYyr!eLAS8WvpnhFJ)Pe`$B4^sNmm9eF zH_NQ&nd}}nZ)eFNn+-M@_8x@|+%fvstQ{6?f-HoR`M%X^!k3c^^bb35eel<3*53c? z7t`UC2foiY@Nt~sffU<(I~OwvIq&3@-6qfSP9cGv<#z7#7kq4`HXR>XKIy*PapiE| zEmL0q#0eK$QyeBpe0mvi-+o{6gD34K-=dzcNxo71MXiD@<=&aP4I4Ks4eh$HyEQ?U zeS!+g0fg-@zcTRcI{W=k>qFj~&O$tnZ4=s5S2PE1VcT?vyF^QDO)!(y*Q}eFCr+5I zSj=e5a^>fYIV_Q7)2vrFGG2RWF=_Vc4GoN&++>%e9Zx)R<=v^0Bbm(4Ixm>sxN!Cb zPY4s_WTrD7NFHLIc`!8VP{ON6T~|Ywe|Jc8C^#wniR;%TttWlZ!ycEcV7=MB=KCMP zBeKj3&bdG7)ni-Pa#f|(BtzJ$jqSlf^CNf4_+C{^kX{R3dM~&`tf=D<%XBH8#SU4Z zv+6s)9$bg~Y2h?99xd zRZEf!&bj;C%N1E3Z)q!guKg}IlhsqMYmAMak6zVq_|%+Lc-&*Lh55=)0|(HZ-iNIe zPl$m|GVpWx?sJ02&nd&yZ9>x(ort?!V(fRP^y!}YD0>)uJNJPrKAJH{7tG0GF=vBj z#VNLdS6{plN$@afkr4;oz5e1vY)&52O3M#rw$5|dm0}!j7mCZ?7nz;MC;I8&+J zhD=BMt6V15P3!oUqK<%b2`Z`Pa=dptaqs5JncRkNm{*>h z$0wP4KdS%lJo%jE35`c?bt$}?zo|?qtiHiYzGafqC*7APvT|!aANcL)aC(!&Bfd@M zl6T%J%>K9jZYATp7McF<2?E#J@3`>I66}mk>$vo@;@>CD8y=p8nV>UpKQeG0uu|Xg zq`J{q`o^>b!`JgtPH1YmeH7Z9r+awgR({C@_b*Kb4+jM5sErJiz*3IGJlgW|3RB98@|C(8o zrPPgUts-x6${x9z;X7ym-YJ~hs!x0yqil(czVfWwuss?aIbq2! zulm9cmgiySk+Z2iVX(N4$=NNLvCA7YhB&9a&MK@WU*>Sv*$JorBpA!?_*Qw~4BOcr zh1<<*KQrF0;R^!or?pa4DD}2cSp0bb?~5feo4H@rG^9CC@=`FK=zElVW0fdu!~Bg| zj(v%CHCe*U(4!&t8L*UEP0&|iS;_jA{p1FV(*=3IZQ6pRml-uoOOy4oIF|5aCX2b3 zbj9T_JM}tjGG2;$Bvlo&?qOyM?f{L1vzOcDD9r8Oy})>e z&roJJ!CGcQwY|bNg>st-f4h8nZ}hz7;W1ol-dKHIMsn8V`$jKrJ~ueCzID#VcRmTA z1rs(Ke<~hc+8ivA^_=T5Puz_hjy1`QK^(VUGg>baFA=r^xq8j>lg4Y(4#9Hvg!jK8 zXBRM*+9kM^&AW4e0d#JYjQ+OC8yvDG_PoH~7z; zagO~2&y66Rh~rEuY_ED6{Pr+ybaa2;^kl+Q$EpL;7ef{2id|qUN%G&z^cFOpv|5%a zrmA&|?CS&0CkoHYnAh^p# z^4d;@li=I1HtpQ;#BugTdz<|SKV%*k5=mDmx66xZp3}5!;ZoLj6E>{>o?Os!t_F1W z#^Z{_@`i@K$45(r#NMokn-F!ut>obSM+Mf7b0cUXTxAG-(N^gk1iZ*TZ* zsId6;4YTQod5$2h`I*Tm&K~CV!dPK}t-=C6ca9B*8G~Mj&N{l`c_K4&2U~8y@ok>6 zS0ourog7{*oy9A$=bMw;a>wrbDSdN}OD*SKyhx(&9=qQBUw>zrLgU?c@q)$Ax?np5o1oLXigjR{B!E@^~QgG9X|v*wt35O z=303UAN!pD>>j!q%2iYSRQ(ojEcHk*R)I{}w;ej-_+?J(X9>IOTE-kJCf1!ye8+Cb z#+rUYvp9a9^R)e64K0i%?zHxtQ7AV{nAce9bfN!oD`?;7iSovVBaUi_rWuB zffoL{P0aT^zWm>}xy=cgp`z7mPH~)UHaX~bfJyeSb-lDfUS)u}R1>I3;JWmQXMv=k zz--V-*PAVKR*LR=T*q`e`@+ibAAi_h&(Tn4_Sc_f-OE^VMsHUY==kLS>{ZWMjSj?9XVq7N%!TCE1(LX?=J7^XwERM*99@J zt9ahm?5XCmJQU>-#j02K&{X*FU(@H34zhyAj3-v4tIbo5c<~OjX7LetPxG2(1+PmV zoN1Sh;kdF9r3-TI{pFO37oVCAI?7gX9Pf7KS#Xm-U1?g(!K-^Xm|wA4Y6`qr*KV%R zEbwCc++^2#&kTtW@&l@!KyR5;{h2v_$^o-Q z{^>XTgU;;SvM&9>L-*wg@3oMM z??u{yBS(1^m|r}YykS9?gL<-Ijl&CuQoAYMxe_9c(V)UYVieZLzwm|@Q zgO$xR(TB>qy(hWw&myD847a1APw#6i+rVAW=Xo$SBYGOg*109YWHkO|faT8|A z>(3XKb?-X0!aXEzf5n7_7kuVFl=+fY0@^eM-njE4%{PIsY3>BpT@yZR5PzkyWO}~n z;m_&UCB0Vj8O8kFJL#aMbkVEhpQSshRa8t3{DofC7R+K?#&*TCaV2AKulE0jH>Qkd zYYyC5prdn!;n30eI3o#nCpWXi@+Q#Q#di#hvd6itIl1rryx`KauhDNy)6DieA07BA zlCB5{2QHYr-a#T#_l1g%guL4Qt9G3Sb>udcuv|IVFgGuCYT&7cn%|Z$cEnDIyWv(E zpuUu`f}O)h2Grr+4Y~>%&&0#Bfh0Ob5vX_+QysjO<$ePPqVoEd1_-6!?lMDbE{ab^2Af#{h4FJcA;>O z!k#A&0(XR}>&;`^oWHMGr<&<(odD=4hP1na9{XBBsy}j-3IF=lsV(`T)JfpfB zyz$Gmvu$(Au20G8yu5HjAG-(Rip7ktQWUh?O6@kB)J|hFSd)M2z=9Z&a|}twE|aeX zBr7n23VpvLYbqy9{@}!9=zoZLW#neLBB8h_p>LBv$mLp{n=qAS=1({1iivbkBgpjf zu4~3IRjh^VIr{7?gqc3`!FTGs$Z`bTBnXPh?m8hc=2iyi`H^KT*EeZ{R$jmTY+f(% zZK`NfEW<7bftHhn=hkx{h%8Jzv2>+$+IOQh^({O8C*9hp`M{53(@xL?b=ko*w*>Fi z3BPR}<_gS+y8u4i<-+vDhry>Ek{M<(Hbye;x+xQ{&a{LNG|uC>A^MUm^Hzzda`_~I zT{XRl?aYrf>H^eR()f_>MW1lB$!uQpku!?w$Bh)qWe~S4`|BR@d2r9_f#!LITK~}X z2lsNmPHA9q5Eojcf0^l{|GfX)Vf@yj+_le`(PL`#oG~;%Nx7tNoVKfXWH!#WCcpTE;x6*J)mQE!-sm ze3{DAA9g0$f_bkE-w}4%wlX^m#HnvXcnKAZTd^{FFI-@0EsSyDzkQbrwt@e%AS%lM+7 zGe?5Q0PbJ2?Omv4E}m_nV^!St@X5!=ANV*t1VKlwh@UX!Kat~=*Q#3cjClzkqU`So zJnW#tAitA4wENCShiiRn*i`sl)f`Ckx8ur5SYh0rb1lni=Gg}mIbJSlIId;g(Jjs7K9{4`jTW3~K9!76=Ooj%ZN zL^jCY&JAZ@Z1D5iI?bY)|BIf$1k2O66?-)xZT%h7!W*p=H{8B(QI2h)*xZRKbZ{dGF}Puz{K(I{?dH}A++X2)SGYF|U*TlTw{zdk{p5<#2@SPR zD&O<803gt~u$TTjgFN&Z6+( zhwR+9os;+|?dC0>Af6SQpF%gC)Phe#b3ahW4H|Tmf77CKVjq9VWCwBKCbQ*-%~mx3 zSRg4B;hv)R;gJ&?8y{O$ldbi(=C#F)?`Bqi`N!Pcpzvgi=LNPeo;+GSVHd1zAI#-n z@i?L8g3rls>E#j*>hXVb_*gkrlaC3OFSHWPL z{s)iP82A$D*ahc~$2~Z^^jz#(o&}G~98a%u_-*ZwN#{b4HuP91HV>XH<}59b?NvbCNauD$Y*Gob?Yl}kbg1-tc zPH(W=<9dhr6HA4n;-@+RH73pv4X<_CF0hqMFk*&W)cswKar&H7$?}Hq^AVA^Wi5}fzJA;JR6%ALCgxk+nDU^GFTQQ&=QJYnFFPtm*g!jdQ;B_6AZQ>>T z9kUxG0}Y$smaN%a-e~-`Tye7x$V=z=0@zuu{6spN?Ht>S9kCOh-uyk?xWP(8foB)< z6Vt=mbMkiCd=@#J+7|p^w_`_S5o_?~&nH~jE?nFV3hvVzIuC<)&F}aUtX+2a`G^QK5$hKY4gqD40L4gb^kMD8{^S@u8WWaW=!N4Oy-rxYZ71m&-vf!`$25Scg zV}%Vj`AdFpDD_ByEt^g|c(ie|!Ujo!Cx7K`n5}63qS)>IVgFId*bV2{Js8(aZd@aw zvTXzJrh3V1FAt&K+pU*a}?`*K7!)Eyx(iaoOn);r6 zjcwSqjQ?+)Kn$O|z3gf&)852Q)9jodEiC3)emhEHg0;v3;q}j|oR)1*oGVmP>{woZ z;7Gz;;R%up{5odvrAVGmoFB45=z=BZf^+O0n-?fB>agvSy}OR7sGSqKF7{a2gtTs- zBWKv&$O(Y9a|>5}-!heFvuQxTNpq=Nm)bm4&7F;YdpFIrnW1)`;7!PL`Z^ zX6Nw)rahH%pc(7y%xQK-$C+>b1kL`>D1U0k{JDECkJ+sWwT$lToDPX^xzD`iI&%tJ z2irrA^#VVT#ytJ@MOmh5A6}e3!MfH#`a&n{*r|0t=RD!=D z8&*p`d8%+)IZ>8@*^I>tq+OgUEFxr~)3KUtrA`T14(7|6 zkAU1)%zzwI7h)AQzzUu3S{WMx*uHL23wX|4`Ps6Ae;(t`+h-frK4vV^hg};oq3!~Y zhiS=Xs}nI_RKre8WQKUQ9v4D;z?X8x2X^=0zL3)Z50EqC!Om?iK31(UcAzk6fC_T(mSz;UK6A7!@vlsV!)js0co%Eq1C zk-RH}KP5bmV`D8(XNzcOTykz5Q_-KORl9YYU)YM+ zHCf4S@Z&gR+g{!H`V{xu6=L7rCrpcLv{K#>ydjNodTis9gij03x$ki_JKSnN!L(+F zmE3~aXD^!1U2H8@cG}X+zX5GWEvP#9w=7u_JZ+!<()Q2>#+PbW87d>$Zmf*(-nIJx z_<$x?58e=7^~$!pdzVWb*erM8??#1L0neFJ*nQ5no}cj8ou|Ukz1CrF5C8T!gPiZL zlNo#q4yBnp$WB^q{N1qNtyqe|MGlt7+vVjAW30I)a~bZI`SsX4Y*t)gtF%CJQnmH7 z=B*EAe`U~Q$aP}BXcu@}V&0wmrwbld=-<%_Ksw*H%=pBb9~)ltaEE6a<#5LG?28Dv z5+u5g1<^+VPm%XAnr}G&rtM6b#95Do8HrYnjMsiLL~cpCEw!U|Lvp3`^evO8xH!o2 zvvDX82wzKjRN|R6gww;h}mvAli;lo6SecVq%j^%6+c@wfmch!1{grpsQ zyO=T=WDiR}nR#qO-ftZ?WT)|QO^Do`=9j4OOyZuc`ZlKNJfDN4rtqvf@K=7rZ(9fV zw@KEVudN>EvEASdhqO`@i}WQNq%Sz~K~ML{PGf;wi~de?Mum?w^VJ655beY7QV%Fc zI}2}^)md|&UC%o(&9>qAXEXbAZb4Q2=h#Z^COpkbRowhYVWR-s2_IVzomKkH8UGJ{ zZ@kmg^X*R1W~OqxA4gIp&CFaH&la9(xpHuWAJ-c_fhXtKJru3vRoHGBGX?WoF?wH! zn6>a}4&UK3NgfrA(_#)zi#=$iU~n9CG4vD1q7$;BGv+;-5ytjj^(yo@2E)y=h=tPr zN0~t5AbH{`^*^WOKnf@S^XUQK=bi}o@Py@Xi@F%kf^+TW6Lv7WV_HAuCP}@>R8)M zR_j^iW+iMbjUEfqnfC?+UujT0%vIzdk|Qa$NpQhAb`Kd7XQo{+Rd5m-ijqx=`n?)B75ke=IlK8DG`B*};6Lg8K;UOiUm9x(>!A&-b;-?fBey z_WXiA_7%c~RjNHeHFi$#}E2Kf8_PZcaqHi^z>mjScN09Vei7`igE*-xdJmJ7l4icfy{ZGX4ums zuuS~QPlqu1B-Ti#^4~FL&glv%%}ZBZ3~8&Be^p=wzF*XSNlZ{h!LQ1K?yFoIAdYt>dO6?*vtA1w+|veG&ayrncQY%ughqUO#{T zfd7F<6GKuM5>t+XuG&p9yKiP_&=58)wZd57RZYVcwvcedj}Z@G1BSAK4|VD9>`In4>QWPNTG>+PPtdp|E+ zpT%DG)O5+&=L`DWO0xwHKmFVKum!F6=k7ZE!SAnpME`BU zx+%LI7KJ(gX{^z@mj7@!4|EwCbHZF90qK%2dO6>i@7_nc?OI_o=xz{!3u&cE?-?3* zGMhbSeB5j$uVA)Dxam#Y4IlP}JDlxhxpy`f7JQ0i3zSuBOLd*FNpfrQp#uz$ny)k% zoRB-LuEw+A_F2d6^O}Eb*liCwPceucbpB+6*_vi6MTNpAk%9r~E|(>ZoEcw*G~^kk zD=-(FJY~>OQ1y$cZKkoXMA)}=OtYEpF+Y0Bo7QZ$K)CvqXokE;h}e?DVv-TZ3O=1; zY^#`W!}eZxMfvjsX;vJTl0QpyZs@*Humz1;MZ_w!``Y&|yzDNW6LR6uY97Z6#W@a1 z!ujS4BN(lCS2Nr=G3P+SLC~_hd;Cm7>}NZC?py`$_nl(7THc1|glwN?ZHJ@B7i&ie50*=(q#pFKzYuZ~xM#7sJJD!^ zGUKb9hG~JBGaTO~G?jWKY*u-(Sydt1F>Aur%`5!pG!=7B)0MY&zW!62NB;l+)DNw3 zcbcKAx~GA*ahcBcf3$Cs7;N_9fSyuK(N7-8ys$mTJ_FXbPa6;i#8^J*2Y8^x_Ecb#B1@Gx$BNI4!t7^fHCV~Lh-2$q>2y^*HQGR-Tm^Lh z*y+Z;*RK0}1kSX}6|&!&(3c~g@l&*8ectMZO+4I?izinezxtEmWb=~?`L^sc8~4d% z?{t%N-m+PedCgOqA;`c%4UG+3*4H>xu;`5#KMXtDrZ5mvC1H*y;DtL47o zy(u2WTnQbQT|lP>*C^!MuzyUPJAvu0IFFg{ghoctKIJ=%7-PymH=g8qx^%MSKb=^o zqE(;I9IY$oUSrH;^x=e&$7Av9a)L9KF7SP!ur1falzF$%hYeF>j_eIt;Mdxwosuup zv2WvV#xcA8%O1;itdiUId<1 zd#KVHJ@2Si&u1@pa$!*@m;IvGc!V9)PgW}laCg2dUR2?{Pix6yMyn|CXBrni?pn~t zzDe0JNx}5zstL-o4yL_u4r#DbeE8g2BCIPc;j8$YX@LQBwxQu$d&TY_i+_NYF_kKDWg8!SlxjJHeO<$q z65mE1g>UBm$EBuP-Dz)}%YWo(^MZ5j+?P_ zvQ6h31Uy7G@Nwi^W1j1;;aj-pCwus&_Yaua)T>$NME#plo;;Pg)T!WZ8=r9f$EO0! zD;6^vF>HCBe7@wwmb7o1IM@nPPY51v7n_rM;Y;HW`EB2sx3O@?v$LeAy)kmS;a2kG z9D9baRR(`YtD^bgnbG``_lmX{y}9w~)P=`3vlpi1YdL!eF8Q#(`Z&YUdii?YGzZYN zSn>;cpBuO?SQ>WX({Hc45_z)iJyMC*MdHy97OoE7tdmeMmof6J9xkUJs$l)QXuZ2JAJ6*AaI!hill`vXC(Xay z5j*V)*jg^|u)p9FxFIJ{Gy8%gTa($s=5GxmEsmcwK}!|*wg}3W{Ly<;q8;;(G1rOx zEo0>)w#*qdJL}sYp8a^3XV3Kw^9z`)Wx025KG?wCV5P9Bo_WKn58j^=8A?qyY|cc!%nyh99DvG1z9+3WdF^J2p9u7dKiOb&nsN7c=4%%tW&|E@*eAoi zM6J$En0cQc2Qw$bm7g2tPd)zO(-B^_|03}P&zXPn2{;}9(6ojr*QNd>t7Yr6xBVJC zx8>*0VHQ`u^0Ps+rPRsc&xfrYmk-3n&%P@#tKbRKl~k;-!fM2`K{A@{wPlY z`;!?_l7|naotPwdLssF$^0>yn$E+V6Wd)w>mECcNFRF=k7URj@uc;S`7~cucv1@*K zV_h{*&i?v_tsQsVW8QhZVJm(zdBeNuj$tk}RYlx2>yPiMa7kymveKbU+~e%LEDvUx zE0&Ef8&@)x21LzJ=naRg>$&iEd+??vMa8Qf2c6Q{ezcW1ZI)Yb_Spiy6P?Q5dRZq{OwN-L!gqdD9{IK3;sBpgGfR)0ANd6MLbtd1R zU2$TIIlU&K%3-cxgnR1idA&S4tYi(oK9Cghww*HjyyN$}hBW6V3zo;dwW{K=u{M&v z0UIEG5uy{ZoTcQI=!+9^6Mi0F;QpcM#@_3V%a2S=wx9Uv(nMRH1?M<(W{NV)F}zyx zX5NMK8!R{UCSEApAmHwi=7V}rJ zyEwBIUYeX-B6IlP((VJ|0!sH;nIK~`0qLM(E`zh z@7(w?7rJ+04G?Y4Am>vr%_+GVaDA=F4!&G<)56+UdeS{wLNB9I}VG zjo3lM2_1a9rU=xrpYS^&tFXgL@q~Ipqm`n0h@pG2>v!dEE)8Z2o2?Z5#Gf1QSZjGI z;37|E%A?mk4QWmec_CsAZ`6yo6fwQ~c!TA;-M(|}tqZMT1BI=UTp-t+i#)_8)>rxB z9K-8|i1ytEGgwm=mpCMRuTv;@*>IP6(<)9OH%a63MhotXGQDnS(Ai^O%iO#|I7#IH z*L|BG{C2!xt#IQK;|gP@S(=O|&)(YJ_|QW(B~oS0WTwl^NXv~AqI~q`x$FerEB$F@ z#Da5dpcFbUSNpK!gYt$m)~6Gq#ZGKUJ5|T_#E)ae=Y@$JmZ5@>^Dz(IVFo$0?+&Nq zccm4^kAl(|#qM1$ZDOqT6x;O6|7j1;k`jk=9~PIXImil3s9bRN#e%;I2Ads^e^k=n zf9NXcddLS=3+7H}Uv}Wv28$j>c?Q{o+|f;~`TQIwcp}(YO2khrdux5*m|e|>hKFaa zWrM~!ma#pl(}iwMC>HnO%{XkeM!4x+T0lC>HkH?}W_9wsFjji;Dp6J-XZynDD~FD- zPIi^N=6j3xy5E~g+D|5L;LAF9KzK;Gv0q5;M#6C>ibMv5JLMf=zZ`CF~Tk1mF z*KqwC5{GgXf3r-0oSb~7&;Ya()W~i^@v@C~i}-^2Ys5Kx&Ys)48@w_dTzD?l-`;e# z=)kvz17?ept!25N#ogcmRlea?ZD-pKJo#Aa;IMs3^E-iyZm$~>jHN;A^Gp(C1sbo; z~W^xF5AccppM&*im8x96S|HQTOme#(X& znNmhMHh(3;D-7ByK{qjJX zwTHgPo_$;9DVDN7TILqpW3C(f**=>f z)>~gQV< z?PU(ru0jHCvHor+Gns2I8RllN9(p0x{H^B73J0@LP(2E&5DsL8PZE2)fscK~W=5+# z@g>qF;v6sd1O)C?l<7B5;Ypb((oy#<#hiJKa?*?K{OeOU?3G_|_L)KJ0zURP9dQ?q z74Nunw^PM3=IH(&$B^@^>)6eHZ``t8;vQtbKm+tJ+waXWttKsw)ed%b?I9&MtfV*e zv4YNG{G4bkd&7o(x2o+W!HUG?Iw|{)H!tUZ=;b(F;Lx{5ojdz`5T~;%mYac2Q+1FP ziBNwUAEW4;>7~N_X<5mQmtml@+pVNQlh=JSwk_{tyyD3CaO&i6qXsL*1(E_2WO9_P z&TQOJtMJ}P&v*^PyhfpC{Fa{Uw^qqAuk-6zw@{{eXNu6B{oG;sNgoRPm_JX1+-(rd zF>5cV)0(uyN?xIIg3PbA&lQYI_+}YR(Ol9vJ>lq7CqI!d_jk2E{Q2gs#zofGISp1~ z2ArUCt^yf9`sdC#1zx)Meu08C$E%t-A2gY{4^B%w_ylxc+`KZ-th8Z-JBte6>z)VE zX{Z<0{qBNNJBLpSkZ$}Id6f>v@B0D*jyFrxH>5cyyec?bbKuBp^-{x( zOeeF|%Fu4`%>{j2KD~dx^00mJMTpx z%Yww#Ff$p$E`0)TkyvtS`5e%mi8uC@nxKNygJ+98%Y7XV58kTd%+K5+zz4or<{h=4 zo9qx5$NI|Rz>|Zr980)4E>2H;7|dDl4D!1b|vx*Zj+@#d&yoD^MgnDJ4=x0Z&CfaizpWH&t#{plwVBQA32N`sY_fhkM6 z!-QIvS1l8)m=E#qvHI0ymGVpQJ`cwx+YNjiD-JUXxj#1+VAwxHVfJ&-^iANN1?Suk zwXpIm(K~p^jJc_XNi0J$?5OgIufJM-CY-LyTRVrTOmPj!${Q!n+3o!;)ZDYp^zbsh z6U)3S)LE+b=xuvkzOl0UvbkB?R%wOfDxf;IbO9enhuMYg2@@u^iSTu1%4xWPI*_gE zpbn(1?1to0$D9duHK*6r98w7Wd!z4xYKr-a&w?x7A5^&9_IHcy4ITCuSF|TYE|@7O z!27<2!E%oFQqNh8jk*V$a!uH0vfuj57(I#gRYQ%4UW;|?2fIfWp2?oxA13KcPytnd zjEuTFo$i3~v*28NqS}*~Pvz$F zhHJhxt`TI-bzs*$c<4GKV=P_2gJf+qsH|o(f0E znMpGhFOTow^eV`SDrP%3|9UaYnYL1g3)b=mts9an9i=ZgdT;np>flfXY0>Xq%hh;$ z<&M7ohpsv*e{;TkV?5u`FfI7uYnKCQ&IxS_<#rbyOPNSBMNRq|_LBGT-F;JeUd-*g z5%*^M#O5=Mu}&UmSX&gf2K&`FMf=Ffe{v@%sD5x2!kqB!l=H%oa3HOL+LYp!ua&<8U=rIC1S@nzKdYN$E04#TOoNH;Qy8-1>W2QC;HTk%XEXCnKh- zMe^XA(hP{@37z=20$iP>)@`!>T3!kZj~1Q$+VjLUIi3)0?Ly2<~bTxWdS&d$6h0rika0p({$`f+&3W>{WheGqi3@0JLgKwBl> zHA%*^bq9_lZ$I1=NU$$pG`YWE_0emRj58U7`K_LE?cL0{nOThwc|AZtI`ft% zTuaJtZh>ra*PpR-lB1dv>${v(NnbVrHg1Kttcq$84&JLbl$s^Ta)0?NZ(!_bEURF8 z<4r^7;ctx!s~Jn}K6Qy1-`P>t(ir_p_;6R{gqf-r*h+$?B^>O#%bII;{8^jq`EN!B z3*LtFF~(_~W!S4Y_lU~j2L_IP2OAeoPrN&6FVE>`Im)5dhZ~z;ONOnTd*;Ir-pnY+ z*%u0P9ge34`4{Rtd+INF2O0p6o@Z*mn=$WBsoRCjiH9P3-QNc^h=7jjw^q4vrSZz4 zBj0uIAA2CwS;eKkCb_XrM*ocBf|-0ba$mmaYwp~<`liu=zK5+B4Yn%O^{SBs^H`*c-FoK65^| zi(U74lkQ2TQkQ~KCur+By}?TUe72(W6_weKB@$#OyxtYYvthS`!(4vngy*0IOBs_b z4Uc~?im^I(;ac|$r|*}_(r=WNsx!a%5&NX~<$_552zHidX8ljaCDPm$<$1BaIDM*PNSdGaDJsPH9N9 zjbrR@XTNwvXJ^yOo0WWxuHU1{U}nq|yd~=`Tib?&6U(A%POouzl_)E6q38Io zZtDl%Jh(j!8a`}WRm)>g2%2|$!g2dQV-WkT$Bt(V_blM%oNs4)EMXCwC6m~emo+c% z1t+X_n9E;TsK_P|S8XvP@#WUw4}2VFba%!qX1C3Cu6BigVl-l*JyTiQg={sc) zcPW$46Kmh{9)78HVp%P88Frdmg0bw4IsCg-=W4RfI4>~$xN*a``YW}}aqm{N)p~+1 zk6&?^aT93c&#lvpuNw}$IbLpU#gxsB0Cisw~}&F*gvi3W@@n`Lesag^no zaC@S)%8OSCo8=Ws7x+FqB6FBK=(eqFDT`Ry8@-~4gGUlJD=Apsco}ixmDDq_13Qyu zX<0N&{}s`h;S}(kc}t+|k$Q%n^%~kIGW{0xzPfx#(R@$y5x>0KT}fsc{2WUQyVrhh z^yS&Mg=?pCQ}#3#HM^+~m6>xkTb-Gkd-u3RoXvjjJ1IGbKm0gs*47rem*-Mf5zl1q z=aZg@-Z)kqGt0qPNp8KQ#2RMB)fx`po7N=n@GB~q8Sb3cw5vQnO{4THYq{O5^D@ah zVz)IU8Zcd0bDZtLLSuzlGgQM3OpE3BGFLCZ8q)8`d1BN0W*$HA$W%U3sSaBEEd@F@ zwfEVHhwZuFnBne>lrdv&(ydE4{%Mj_dF;Ij+`qv?o*!STasRveXVpcFrS zO5BNnzpreZSIxmBeG z<$R!1kY6u}sbHJ=^Wvl{DGZ4de#xbJ^b2qKznEzU`w{6|Hv_oOCpMgI0!@#UziT+j z{Jp(lT0-Ly$GQC>r6;U*d+JX!&iP+9fpN?E=78tSOT;66bCcO1Gwv>4kJX&L>{3>; zLx#XuZ-Qo2uAG@!(RT2zhg`PELC|!YtODz7Kbd5P#0ziO7oKDHu-!CE!rYeaLXOAb zZFX%p18=yOaGtGdm=>papY_o+=9zYG`(_ASx!It*^Ok97`_7=d5p-C4n{s%=<7*wZ3R6mKF2wS^?pRaDaFbnV)q~>77VA={1l+C_zBpp0|HbEV(v#EiLD z4}q@Ny2(51Wr6||NUPV!QoDpK2U&gr=_@}sWbHZi;q6o1w&Vi^#ot?b{A{W}@#PtR zGTdWua3y!JghSRk`NRdB4)1Cdq8Y5JzJKL4dk#NG&NY_k z=gcJ{`X2f#K0l0OIeC3U@J5G63vQoJTpri>j*GE0AYrb^42v^)pfd*Vw%!qJEVa^; z+kcMX(64E;c#OOb>@~IDZ?MF|Y1)QHD}fzM&!r32u$IlX^x%EdClH{{I@@l-jGdxS z-c2}pKzKvKTz+G2?j551eNBD4>)nEC8mu@@oL+yywApM*^O1yVhlJS|Kk8m=Dz*A_ zR$IcsnPt~jKA!2b`3-hdE-{w5v0LEI&x8d64Q4Zwqsv&0uT_aB{VZD+$aZs^=8n}y z9NArsU(5Y(oLRsVt9!`7ogpg8^^D;j1@%s8hi?aAGuDt>&8nW~umz~ATveT*=yY-J z!AdW1I)@zDEaS7`9Q(or&7eKFA$&p6VceO29!D>Fn#ODCC%uKArS=)~O}h)65mQ`b a8IEej+HB%BNM~SRVDNPHb6Mw<&;$U&RKJJ- literal 436989 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 z

    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%0Awt|=Hq_AZqSN+yH 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≥$c^q!FAD`{$Nk7kC<#_>~NYT%?PZbDuy}Jgqb6(ER!8q>z(K{U7`@&g%PSKul@9}|Z z9vxF3$-d_I#tA75`lnyD>IgUM?zgIY%+tKIjWeRxV7)-!lJh4PdtKk2?75WxdRETD;I!PU0P7t_wS-8FRX=gKYmY zPUDTcBu$K)6hF#a<~eTa;aM@4H)77=M`9C?|LNs1@LK~qx9i&hE4dTj7Oj5C<-R6F zBYG#>zAs!m|FoX3NcbqZ?p%95!xM&vv(kD7F}rFSK_d$K7nx=imgv8#+h)2tz`wZW z=Nr8Z&7BcT8)C$przPvg)b=onGk{N0ThOleVjuqmyPjR0jF)7YR##-{>Hq7Kax*OJ#bgw2gaGj+Ia>IX^!{q{63(t=0tyz=!zM( zSGMu3|GFUhvg7H^4#tWGtqRo%WfLd+JIv)T@phEu=VY%HNxYM)ofg@4&++F+rc0bV z@9|snytHq#cbq%%^8r7OqME~2a=U6hdG0Sbz2LpyjWY_ukIxmPe)I#K|8QleKtPks zJkTP`U9Xa7)YgA@-Ef2b!78>1KTm8{RJfk4slaEu^BcqG1@pq?=NVf_fVf;C&6}Bv zzMDQdv0Kz~0mnO&N#)-ULNDX#8x?pb(85rcO1HrW-&F1LWs z0JBv%HsPUQ0rQ4ALQ5`84;D*PV7pWQwPk_Pmko@$PW2!DNP1aIPm_3l_701A|D9Lg zZ!bQsk;kMO_r**8%FlwJZl}QZdm9ftH+eN5}FJF*oV%N5Oj$k}q=HgEoLsQv{5^EN+@j7%|2@>JCfRQKVEs7&!bo86SxoWy*E<{nSTWATKJER%V5MSgZE2MSIdN#(hAE|BN-bcepZ@jJLL-fYNq zX}`F@hGmjF|MltvGkLyrvtInU;ZOU!CFf*k9CuhBS3OhFBx3r*d(Gt!W(uVEpS`iS zOYyL2PvWn2Q+c$6ChW2;wR*+&?wEsz_2Rm}Mte?*ZDW*O#<4e<>9e}VS9|tz3SyD0 z#$RNkL5rOdj3uu9JmK%|J6WMv?aU0OYekY3T3RcFnW7f48Z)c(%Pf<(-^;51dD7H_ za|ElIY&0GTU(oGIIit~JB{*l&2InS)ZOzl7Z6g?O7W3Tx-+1q5!$-$oimwXe%edD6 zU+{G8VaXEeLp=oEU*l-b!UF zkJEE%vkz3;IGCJpU(oyV?dx>I2EYBQxLVd!&)uD`>%1x00J6#B&6m}`&l_By)T|sD z$+cQs`C^*I1a96NZ`e<)-k>G1#Zh((i}ngBL)q{1JJ{4#2s7@!%xwGc&^s1JOM$(G zypNl|96ltt?7wzNZB<+uZvof3)`PBx*;mUu&h7tjCTz!@Q!lUbh@PBa%euf;uK0Rx z`imL6=RhluRcm}2MRGo0d!OLJ^(BE}W#FVnpTD+$KTHD2OL7!>U%n>!LD1M`u}G4v zhRsB4=?#Jk5f;kn8eh(_?@9+9)GJYSl;KrPN&Eqw2kT|`ocr)gF=ex5#(DM?!c1|C zjyC*Ww7U9$UyG6aw`N&~^5z3vF3@{b4&3F`viaC^%22|D6Ut%nb$ zx=U;*)tkVbKf%W0oP(@R#w=aUrks+PJt^YOIX%*|vL{%}zDO?L@FO)P!{%1kb@2t! zm*4N%f0|(yr(-zBYn{e4*CV1S4_=-)x4n;1rM#lpn7QaVv*3Roo=t8Y-aF*x@8+Av zRIato(aqN0uKMhP$ITIs|Nqc=^;ctq$%-fO$3Hwd;KO!7j$eRR>x)AYx0zF4bl9hM zo&D8C31R`hQW3h-R~RvyGOYM4c%ilO#feo$SC|zXKHBUR{(te=g6PZgcdJ2bK@*Cl zU&IL1L^aH zXL#z_<0Ckvrna`+JXS0&;jmeOCxq#9cbegWM@Ad`dnW!xS%S}Jo6@>D%iD~e)2dh+n`eu-aER+3#=rvl#;mGL+}Y_?Lr z;U!mMc)>{L#wYC=pf&ON2cCw^5n5q9cfr$8jcE*@PxMcpvD`)}KZ1Q_ywPt#W=#f@ z&y2zUQ#ikvL}$Ebi?1%6X2Wa)KDI_%x50cyuS|H*yRq+XrA}rVki3nWsQTf{AY~jJv_LH8MJ*vlP5Hz$y9s|;qGnAMoN+`!TkULst?*kBlbpVU11uV{Vk-7c-x_u9 zHC6r5&v1KkZuxD{GN3aiqIRNNOuo#2cu)NdGh0HnOG4L0^C`_o!sl6cB!z`DzS=8a zCMYc7aC(D7*FL+dBMqxBG<7PM>p5g@-BmB#_0ynof`W3?at^Wc-D2-k4zNw?nk8Al z81S5VlT9~cMesf&XKzOn=aR+hhcEql%VXvk_n__gq|(!%1^pL?1PKfeWEp1+XzJJaxFz7(Z34C1NE*voZ%^1|H z!|r{XeY>-j*L!)}6oWno8LOiA8qfafEI8*L=d8q>agF6k`GvWPW#1-Ld#fxso#JRd zzu8K0fohb2c+<3a$7u3R-%-(qb=|Y8h92t7*FHvEo5MZby8N-7Gk?L#%add$q?S#X#Au|){i@}FmAnD( z0zZzP+6T`V*=AI2kT|!6`yylaeewD44MDex1xDPo`4}Km@xk*lv*Cgu#e@S2d5?}c z=rX)+QMg?#dqc64`PR-1_GfP8PfWTu*BvtK`0(Ona)CO_O}&8jBUf&8GRE66u4Z4^ z(56~+oOzo(XuMvB+hp=V#^4&iIt>tyb#g$AXE5GBA zq-Fd*);Ok`of&c;76qKKDvpfNt&kK`R{qAq_o`;fRB=NMEhnp)8+M#ObKmETaS@S@9cTVjcWLu1VDLM717s~CZUMiFO^ae}h$9J9wBXBKd?Ny`0Wf5&_< zCYbBi|Bp-+-`SNLHFc*r$?v`6mcKLkWlO`|9a^;^_km81^g>uQrzt-aSjAR+eyG(PdEf%c5XQ=Az2{0#=z9z=P_AH9&>-2 zl!$8^<|^9D8&w+>CYkOy{OOb8DV$fQ zm5fi_L8oE-nsrcI%+9|5#gSX0PmMTEoi@xlqn~Q=?}3=jq5d~FkAHaakGbvST3Mb6 zekZ)yk{EKBt$cLdj7dAh#^`S|`a^?~)v0W*Wmrh2$7FIN#Yn^|_ zVF~Ar1t;p42=8jh2~cO*wnZeflJVdI7Rcy^_ObFOdOo@y_IBPAF6%(r$Z^k|56k~N z5&Ol0xz*gm*28{{T;t3CKR7dA%3sj2t5fWmYO7#=;8D&m9S>*ul3${`c0Zi!njpyV z3Vc@Kmj=*Tg-ez(-q5(f+N@A6`7${!hZC{}=-$sC-vo+Q|DV0PUviC+fU%W%xuW0t zU;XO&&3~RfXn2t#XVGx;qjf=|Huy@3sd)=}U(W6W_r(7+&c5Qw zZjoiIg(`QXe!MweeF&f0R_tOA(ao8>Wbbu04#h4RMM4O^Y2agJ^Q25_OkP{#0I7nOXc*g@>qXcpfBy5 zmvh)l=t&6s$=L4;PH%E}_859jmizq*zDw-8ByDxpO-a1EC~t!?zu(LQ42N9Z6Wk{# zz1e!=T%tfj+#S}{3gKZ>8o!=>dp6NSZ{DE?7caIxyek`E`a;OxzAk0Lvvye>rp@f& z`X;UmbiGN7sA4F$OAv~9t(mgl!03&W zbgp}eokN>~mlyN;gcU1SsPe36W}Mitgf-$gb0p6tM@R0&ikUn%-~OGmUNe_Jpq-^8 zabZiB!8yOLzsp@p*fy{jz1SxZpw99{D`Fn=-358kGfqFS-#GhVkR$KWgO#QoGp|1v z4=}%s>|-O)*IX=3l``}#rs*R@1;_|N=ZN$Ilr_Ol) zhB>}$>H8PG^X^JGc&`T?jN#&tDtx%@n-v?U-4P9&qS@Rt_kOBjW>yr~pQLp7P)ChO z>H^7$@AKyw6?Azl?pR#ztVEPnlqC zY*0MGTKfM)sbB&2r0*&^6C9*3Y-D4~lH`xeYhA;a`chPx`I^pujvYVWaR_QMfzE!t z(eSPHz#qoX)}MG^ChFz!e4lT3^c5@QP)=}5VYe_#l6)3B*R&aqzc!lrFW`L7S|F=l zwYTAe-Vu=`tE&GGC7A@nH+&Hkn{{MEmg$m-rs>bz+PtSLEM8Kbr{H(gVIQyTmjBFK z-ZwL{H@yAMaJH;r%7GsWW;yFQPS_qP3kZLAT&7j;dybRj1;)8EwkFBHnt82zyW+Lp z?(EisvA;h_y;>oBM%K>t9?ybWS%p@GZ?D@YxM{3;lx9$ne^ObiCRP3Vpy#E|5-GQJ(@~$E6S87A z`>_ZsQosrQ4+PolUDPWv8l7PXJh_@3;WCacQJlYL$$c}8u5_~FyWyCoFn zPDtn3;K$w}7IOSd`ult*wx6JbY0kN;d=Sx@P(3~NSd8BDsKj#{c0X2emMM|Ev1sjV z38uY&B^-<;i;O1tep+y@y_faTlMBJs3eD;6ehy}T4yW0wottxtAu6x*m(C*Ns@LCG zdsZ-&dfC<0fCsLo*Hk<=+#$>))V?(R!rK=w<_gp_EAF`DR%Elt_@=exM8+~s#eLh3 zmOpsIzHXUrkyYbT^9!938-&*v?0js`$Ly%d2|lVTVVWNgk94E4Qr(4{0uyfPY~X$I z;6T&2q6ASr&{2lW6Q;*4?ElkfCI6z&_1%sGH}vi99GtO>=_dOwQ`zeo2b3Q~eO~uY z?}KNAg7rMP9bDVEQuni8Iw0W@b4qy9hJ&*&U%aKeVD?4RZYD{yFKgWkjb5mg%wVYc z@z0%G8Z^Xpb^~ZVm}SnJQ#l7u@s-N5@5HLXSEw@&%+bPs^Bi^MzZ}v{=P*y$RJXHuQ0L@cZz3$n6!sziW9TW6Q*| zY^7Q`Uz;RbDiqw$9=ufX{F@cqg}}WEQcLdL*Wx}rUAo^lx#I$7aztUO=r)Cff^)4o zZZK6w(D&C@6|dF z{cU+;Y8J=d#E&6uDlY=}C>&1sZLh%Q%*8&TPC)+VfA957lP|a|~^5E3+p3n>ZYgO(DWwXZ1HUfZRv~G)i2ce>4e^VE0P-K)=(X7=DyVSClmFg-(Y zCc~?Qh8-K)`gAWX-ECk9x;-Z7OOfQ?9dQ@luxt1>d;)EfJ+0kxjM097&8Y+0dcCGU z!T#oW)v}=5(ko$J8O!UM16M#NB~@L#df=%+^ZbVgPg#N&mrVKQD1F)7w_WG(wG*q@ zvTHYF=`}k=7)9uQT2{&?#Hj4KHrj2?GSHd##W8IzFI92=9=}ru(YD= zqJj=5(cB@1p^XYe&pNAV+>~#9Z-=L?& zQtISjEGeWk!H;9b=fnk#k&N*>7*{qxHgVkXsXb5}wA-Kg`oq?jj_zM2CBsT&6|AQI zS66gDAf&$L@j-@@Umpmnf)hdYe3mI^PZ?A@Y?kNDWaJ6jlyu^jT7DkV&HzbS^h)? ztIbCCc-c?$8-HBlp7uO$Uu~m#&AfdMCW{JZ^6O7Y&}E;|d7{rX={}?0@}P<0tgD$y z?QC)k-^bl7lrWOwi>hMXBn}>YS~Jh?N?1fZ1+r)b3 zwI`Bt5~;`DmZa?(5X1+kp3D-^mLtu=UdFdBX}(JZxOp0|r7k1yyM>rqRy z&;0(eXByt{2OMXZ} zbj!5cEZJh+4o%^@iwZG9vpO!`-fCNVIp9nB(<2FA-;_V-jCkLWsGZVrlacN1e}=8W z8~L4*q}WeCTVSiOp!b!*f17yz$cqo}F<7qs`s2)2o@p-+@*GcFlPD0_7B`XMGy9Z( z47)yaoPG53v$&y(+A+h1j0yFQ(wBEz8QzWooqw{<<=wqQY4#4PN*tSyM6($!FrO#+ zf#J(3F~~}UOHA4;E?TQ7*lPD*e_$+Dll|*6|8`KWXHz;@{@|$22IHxc0jDe2Zp>BS z*&yJMx8CtHqehWrLa9WE-Jx6DN6Wkpv4Kr$k}+FpoGt0FSwUfA`vFz6-`^G9YBua* zePRO{Zdk$(n(tCr70=cdyWCL!zvH`_mL(y^J6IH^mBmtS7;u8lxPk zBR!{K_60}j3xQgO5eHd(*DO$tNK~A$SVVvRox}+fTGwo6ow+}Y&BT`B>&zLi58N$$ zrt-we>dB!8Hy?-d)G2ldyZFuD(e&`$Z~u7E{WT9Z{Ns;Q@4lz_vtK>-pq@^OOE9y3 z#DZDLdwUKp=3Y_lC?WadsX*P29~_VDo<#P`%f}mbyjJ@2;o(KmH|rSNj<>yg>hhG~ z0&DaC`G3+2CKnzL;D-zj#Te|XXuruAxxZEnJo}E+O zn;=Q>p74iaN}@p@Zt^GmSZos1ki6y;bX$Q8Xj=i3wtYgHxOkhPLU`HUzuX5;Z&EN; zobdJ3f^+RFWtaW;mv5Rghjr#xhQ3MPuNv-H9%Yo!^Tg3RH{dz5rGTP1pHoot+O_Ht zuRc6{%hR;T>%pf_hqLc^YfR8~idfok=f|;&;mH%WxU5?;A^3Iuo|lZZ#a1hvnO?Oh zoNsBclGl=QlX!M#C*w{7F0A0K=HrPIY zZ?WJ}y9+%hq#wjGDb=hvo}08gL*UX)hthX?Yt)So*6?cn1f3;Yst7qtb}E~}*3W55 z)5;B#qSagO6elM*oNWHTFjd>@pBtCM7d}28+cS9q>Q64swC1^dOL4Q6!fL+n{%IT? zTr9!qGG_FjC{IwH8SFWQ@ygE=tFu#PTnXvl!1m&y^npnJg5%8I3k#B?v_a+S{N3-E zr-wY8^q+02^0LL9C!8k~>1DD$Ta!6Y_mzUcx^wI|Y#sjRtbLixP;OHoT9G32rQuDu zTMw61D8tsA)FTmB8DG_$Fu!e7u)^uHs>xdao*AbaYRWr)ah>TdtyW%U98*)wpsJVH z+Onrh2VB-!Gu>|Kd-Lt|^gN@4&)m>6Jw7cs$JtiDkSn2Z`+I?Bw%UGWfjs9Ms?8mZ z6&0Rt=wt8TJ)OMZ9D7&tf{(0|*mVyk9Z3Ax^mBrr+M0EG`ub@v-n85?Zi=#UoEEKk zyK&DKE|F{no_UNrnRRA_9#v3&d%{>u;p_%$M~58ff?jVujV|^y-~1b4PRd50ft$umH%Fd?Ga`&|86h1FZD?5iH5^+8vLg$7Wi>& z;}W`^`$D1igTaxDf1q>hIRc=~y~lSv;sf31#=fPH5nLyLH^@wjR{R_|EzVGht1ckm zuX@@xwlD^zl}Dp)9uzh&m=Y5=6EwO1L~nw{5@DvyHHHpCTwaI8!%n=LQ_6G6((%)U z-`^)x2#Sa#I>g;tw1V~JjQji9B0uv-Rk41Oe-S6ZX40_d4Og124`Tp$>a)c>VmBu!JL|8FVGI#I$PmPQd&{{7^Ye#Ssj*#R(CL^k zr!%r$$#YR^Wq?}*;?z_VgbB{Y0r8gaC+hi$wGx+~O^To@jels}pO0Q9x{Z)+$qr3gz zX2r$-{^dPpLHvM9T3s>vXz#|n0+ETSY9x)G+ zYg_3gbm;0&22IvduY|b*Y(@<0Zt_nEJW=%F3xlu5{rAq(rW!4}-ua>BoBX57Ck1Io z=2oP~+Mb`VEEjaXVOo>fGV}S3Z&p^7yoFr&ypwy2q3jko@)QC5Zq4S8k@yns}PpX0-nK{dt0u9Qf#cmJ;D#ZK^9yvxdpI&NTuZy-@vghGSq1+tK?Q z{5Uto%kMdKC!ud&ILi{bE&mrU;@gz?_21p)EB2PSv28lWQMP{m;SFVa-%eLaiKR5Y zWhnLAuv{3f6^s0BXC6pU3x=H4f247Hw^F{F zdzo}?(|67xP$?c%_dD1D~z>5A|1afSj+8@_Pd`Y*Up`q+jF=@fa6eYT4K zB{`U9NV&{N;yb4--f`_=FOPfpHRA>4O^)xJ-{t%{zB%T}1=bT6D_``g2h=pB**eJb z=P1uEo^EQ~kmfd_mi1NxpVdb$6*jBCTuTEvdlW95eIc9rk4H3CI*{q{;hS+5@dtKD zC@)C(-gM%0cXRI!(jbU1U!Yj~@?WYr`$2C5lB$!@2G4cDd%RE9S)SoPL-C7l_!)*S= zt?I_Bmg2ymALUmHG7!+yV9RL5Jn;O22S*!ShZ1 z2TnVc2IW4uCHJ=RU88f+{Mq|N55M!C(0jW)-tHiWeotz+#U-YU=AZxnFPCgFG3ejG z{`UWYG9j^RCk{@&mhj3^oTur~nQKB-8El5VJSD{!e=L|OP%C(1pRd602Ywzi{-`Hy z;I%A2(8Id+nd5oW1wR;LBRbwqVQ$wq=y06=(s+Sr_K8%@Z3`Tyx^ES{^0VXP$F}YE zd*3Sjp00dK>wqJt*W(2@`Mh(lsCGY@?#IKUv(oyx!I?6DM$r8@idq*+H!V2VzIz+5 z+no1%xGaVE!I|$#jNTIUx*rDv+y0zQ<rd?8=NTqQ zPgPs~i?!75Q14!euz7de46D-~t~y>&#GkU?d7tvDlTO0lo3&zGoLY81xBQ`GeMX0I z*9L)`XIEcSc-QF=S#`9-@_5soiGtG))+K-btnO06wcuRPlxYbKXR8{_*0;|*w$Md+ zThX&OZ*9RNH7Pt9$yP6(Xispnwmori`tydYo`&BJ;CA%#<9f*_Vq{qF_w;2uTb-CQ zUq0T^Sm#_y>-Nc=cDET{)g16~;tQ4d{Z9Q2yLE$}PKwHfxvqIDl4jc;3QtJj~e6jb+<@@%(Z-$@8vQ+hEO2 z&XDH!LQZoQ_QfbEZ#?L|S)s3G`^LXt7fBweNc0v`So-J9;*L+uSAKeI)jPN$>)Rx` z5BK<(g52d;x}Ev>_uA1^i3{pwy_<1SYGuwSb+-O6RHaroNJ$8_UzJ$@^D4o zxA_lxKXhDbp4f3pGCHEM?;dOC;&*=&QV!VZ{+|yz$ZY0E2fdvNGrt_U0y;5Wu%tT9 zt|6yn{fP~UFJ^2MJS+)1Ly-CSt}_KWPW5bYSxsSfiiLYWUjnV6nxot+@lDU3-BkXe zUBGkYd*@~)K2&t6WqDoG@a~(y=ps#rGl_@6aycRVLmWc+`gR5WNHZ;K1}&5QBz z_DK`AcQ$bE-N$GseyQSk{33I`_h|>%<815CD5z<+KV$Ehxxv~|VbTHyhkoV@J{%bW z{MUjSPvl2zW{>-R;1t6Jwvv=`h4C?OUi7YG;`8g)is}OUtaf!S+_0>3;eOVWK5lGAj2b)&4=>b7Zfs{ia?JEGqfqWKjvvNNy;5naq(l+-R?B4 zsoYLsUfcGKj#gV#c^`VMw>y3(;_s`^#cb}T`YNW+ALKZdN>vrqR{fg=S`j48pgYGw zR_Me&0XH_i2ls?Qm!4KluvjA8v^F6{L9(Imj_q!yE!!k4d;S|YVgaYw734J$Pi!7PUc}lz8 zI`I25&<Jtijs_jD4KXkJ#T(qF(-!IE&T&!RADw&?0xgwM4#a^)oEA6b5x6M_#qhVA2%6Zf=civ8Oo>tOmwp`iopi`;ILT9xN=P@Ym780vh=#Fyc zmRuG7y?JS(u}Z>Ti(9NQ{&3gS0MVr!R3wZBOuyQ#5_K@Em zr*AAPikt54o^XJ*)XCwMzMZ3$o5;MK1?(akhI*EF4>j;N4m9p~kY>YRj~% z-Qnj!OWF$V7&}P)nY`?p!IQ1)94_*`N-#Je#BqTKyv*c|qvIvk(>VrJS6{knq&20v zyxY5v_f5-+MIFsfFF!2Z3c4YF+p|lG3+AkiGw71Lp~LARaP8v>9+o)0?Q(@X?|A=^ zd^+LSj5U=Co3an?YcB~9IJ9ALb^qG7oIK`IyA7?{Zp`dAy0R>yk2mliS#`|t&d-wB zplq{p^7qy=b#EivBhs2=+7zro%~SBTmXq3dGXGrUIH78SrGH$_fdal?ae^0En>Pfn z{~-1wV6p+1$C9oGnje}D{%8MhJmY3{!VT_Q|3ALD7|Zsh&*a4u?bQk=GOLbXi#_zh zWPc^oM`pvj(r4zd2s)l)+K|J(TbSiZzzmxgQ*=t&o2R8KzIKnB#u}V`y?^Hw;Xt#* zT{2q^{;@CEyi=>s_r(prLry!mqkcHD-m^b+=LGNV_l>LA4>_Ny`;&g)nuEhv`!jD1 zW=&+=y7{BL)cg$-+<$C+%#yP0(T7i4c{U_TnQ=GC9XtQdNs8&mqaRPx&n!Nd_)MWZ zqF`xaNFmcoPKk#>$2yp`a0~9J3wg@=H&zVslJSJUmU);(xa3w`JejBUC&e z)a3r${a;e$tKsy|4d3b$=CypC|M2eb?GeonxHl*sZN4_4N%KhM6TL~E3;a0R4ra)5 z?@8>pGiqEWVe-4t+kV|m{s~n%MIE;<2VQ<|!+M3e+2MPAi?mbU6;p4Awc?T# zEV=NsQvC% zbU2nTWP8FjHqb2xI|G`hX>q5mOJ_LSBhYoI#q9*ov?*OI&e2~~Al_iQ+%K> z$L={hFG|m_yY@~Z@OXpTryoz)Ui7dpTiNfwj$Qs{_nM`qd&Ta&WM8`W)y%UWy8is> z%arg|neesIN`AxHR}1zk-aL7YN3d~%V0H9-O`bBgGM;XI9nfWL4&GZFs^s(BN^C$U zw3-V*+LNz9m%DN6TsZrp)b(>?wRM2MmGzcI4G(Wvp6HMQ?d1!us#(C=ysAlq`9((T zgqaJt*$R&-?i19Qp|+*Z1X?#fYqC;zdB034;HC4Kzvmq!4oGFL(3+?(#d4bA?}p{o zjLu#Y^_zQ|G<-Pb^h$jS$oI~lF{LFj*Lj`^Xgj3c_eMyAasOxLvQ1oB&zXhhop{KQ z>|7)ST9hFjFg?!D=s}i(!k2_+`%Tk^P zkpe31MvEjrGo9CTmN+TkzF=|r97l1UdraS?H@;(5RJyDDiqGvskq)R~5bW@1f*(iG z(L)S+-VSpGV&?Yu?p|hiz--CkJuHyR)*8y35*~rZ7*3T1q_f&;fbN(`vv-JdT{qp~ z;gS_yJElMVmwTpL=st7$rd}N*NwuvW1`;nM4Pth*>`alma`M2on=-fO${UnhSy~vs zv2G|kqF>!63WWgoQ)icUNF1*F7G#ZzyvxaqiBbfTDSM1gOx_hWDC8-SA5>M#6;%siy3)u z%oprui?h;L#TC1h(ffFSRGB)*s>F^@%tpT(XKr_V%HzTJcUs8=%N3~{X&ei_wI@9N zSpQ*Z%Zp0TevRX-7ZPCA&?dGkKR?7aR=#z~XL(`~#cIvZ=I40g4WmYH!>g~arKc~j z2)Qi(+2fwCgXw}k_7%!ax^WYoIiF}pXh0YCp?|p8c$UP zyuZN^Yw%+cS50b}YN4;HIFZ&Hh@Tjk*2$f*CxoChV#B$nrGFamM}$`qC^j zKM7epZhWV65aVx7)d2XVa zbAf%z6X9*@Pd@CGmN@w7!wIera{QtFIc<--mmhj69kw=^;jJJer;XJvp*`U&OQuDO zRPGcx!oMJRU4nYt!(JDi!uAu*|2fkHU2ItcxgY&kUo<(GdC&6)FNIGyh-TQIn9AJ_ zn%oU|?&Kg4w7uC%zU$NsV~y|coxVvxF4eih)bG|d_3Q?34#!NnN(KJ;yXAaZ?;LH| z`tFbr&krl<8I5e7+ZXt8Ff%XO!&d6yaC*~(bSHGMUb(QgvZwuyCl&ng%zVX8P{5_+T%IE{lInOPRcufrE4#L7-pr0`l1Cx}PPyuf-oICSsG#hm85{3|m1TDhZQvGB zOf&V^Wq6?P5o@VkkMeE9L&=dbs@EoObl{S|Q-5N?3XV?yh?`7{9m|^HX-{@d7L#2eaPiQJ^h~&SZ_VrIxeOu>Q>4VD?4hm^+``{W`#u~^G z&NlxqgP6#MO-x%DWi5RYH_LOs3NyOlZeqaUDE(&s{Fik=CAycjyd#Rns7sKnS_B(cPE1wWy z){%UdZ*i`Hw;|1C**V*;V$Y|>4+Lv3O`6bWwMLKue3fPF`HtF3))m4`uWJ(Co^ep- z6bpZEZ<}gxk?TOgtED$*OFDpqL(ftAvi~+crhJF(D;iBy^v~Zsv|#q5!wf;p_qUvD z;JCe<|D8cXiBF@Lv!0I2SqISk3?Jjp_iv5goX-7r{}vnQq{GBzA-|RwALxJjkAG*r zT4|gK^QUEBZ+gx+EfK7IO5%dG;{Q&KwHJTij`($-XTe|j`v;{j2-Y3FmcbnB*P+MP zW&MSld+Hhi*(N(_V>Vy=FUB7Ot;KjM7*F_ee3fsIl?qU2S;G3HenS1NMp>Z{<%a5; ze)7o*tPN?lkE&+{Y?*Vb@2`vY6N5V?-}TbGbj_`xr7OTdinj+{AE& z^PpHC=t4H;n}QSeFn+dI26X`qHCk;MYwG%HbM21!xv>Q?uCO~~&(M0@B}1k0OLLmj zhEh9+U5<|y_;IZ9Vd!ksQw*6lJ=H;1UP2YB}hHn8&+wm ze_*phf^S3ze0?W_peNq`9L+=w-%Q(#C_vN>q(`@RK@N1&C*9D)By=xhr3t3Y(Fz-E5`}G;KbI~62!*^O=crTNXbh#?9 z{M5dEteWnvQw7w`>S}+_a6Bkvc={{XDmF9YOjF6+HdlgmaSax_(q#y zZr0TsLhTPVp2nE7U1)7yaQpm6)nik=6?;9->ePP-S)H~_{_xkAvklHLx1Rcx`$Ie7 z!rGVT8#gO2m?==g3|dbmapW_2;cC`%X4AMWYZe7)@ut*r?A~ykd4)66yOsk+rjs6D zklt0GxuuB#G*IiW;k~}0m2r*Df$)`bF^yKKJ$vpmTP|)s(!0QXK4`6BddY>eFaCu^ z@<{jl9_~=T!pG^Ou5t#ne#8`f7qN@h#clnp>L!kyqHK(uscfLeG2aY}s$Wj;TGm9= z%kAOec2REk?a9(PJn3(D;2qGxlAqq_HE&rW)MfF@wRwR>^*5o-jxGDbSxkN(bWmd` zHE@VZ6t!Oins|FvlOXkfK4Z;Ag(_A?-|7k6+>V<)C+uJ>wYzfWsbSB~QlX-ZW3!jb z2Tpfj2$kExdUH0beq2MDWu}rF`}bJ;#zeUlG9DZGTf5)yEt|7qg5ok~reJ34pIj*) zwqKu79h;EIzFA@m3wQWp$)AUul4O1f-spTV{b-$*@EbpY4$BpD`8^Ixn+P+_y4far zX2#PKHe1fIXH2#_6T4tV-u$|jg_fF~j;>OdHnc3AePWUo+l9CZT-+yuPCnhbRpMS} z&apX_w`;_z_GmI6Xg2`ljXwye)?&>=3d2rv7#8ejL7R}cOCt)x9iE$^9Pvy3wW>9y6xH^kochf!Kc-= zJPVR5CI%<5e+bc;@V}E+|4XP~T3*Mw-z#H1PA^ILs%T)dGgVabg0=h(n=1YtG66H= z1y-9tw)@30Zkx$pVtT(LB8%fvv&`28i^~&VKDMu7mV03?m|DqpXD)w)hw%aS9tTUw~_m}nO-x;3xt+Y%ae*WFV4e}0ie!qCATyS!KrgB=c z%->5+d!9Ku3soNGGXsq<`tV)hWIS8dAhd61D_hLzlfoBP8ZHT_{q%#^xjRdd9fn)#>L$mgg0DR+kU%aT4v(%go9TWzxnPUHIV^)-NQ=ed_Q;XQU~+J;ik(C zw_H7U=)=#ZsuRy#V_mN(FPZ4v7@+2uZ?^aUr%9kuyvVkDf{kY?4*0mdU;%4?*_h+! zUds3)tt522N!#k(0e>eL|2I9S@^0?_mc)-PM}7t7Y?jwHS2)+jF3A#A*P54*5@US$ zlk3(8sgVn23TSeAsIy%8X<%A#Y{UOAtS2-SL8Afb90&Q>tClw~nlproErWn`8 z&gHZd+l4b6t2hq?e%cqsR&&7CV&21-&9`|b%oJb)7btZTEOrPpd8KE(V>^1w?Lp9L zh6fw>C~Q4q;$z@0ASv0w=r8Z|NN(F7uGw-kJ`1?NYdX_5^Z)#Z_l~LY9>C?RI@){Yu8^oU)y8qZq1}`rOz`@oY7wKIdO&f!GeF6xZ14!=NqN4E2P~m zn`6aVCiy5LuEW`JTT|a-)>0b-Z|@GNCvKW+3Y&G;Hial3w|6>Q&vrpbr>0rWe7ght zhXpS$DD0EU`PtgKR^#ILS3jNG{y+a`{6Zp8ZZiL^{~x9HFv?DRR+i^%(&Bh}jgPK? z_lgVOYa4W!?(#MzDH>dyXxzN12{;V1i-4a^%ka@)eS*Cp{L zmHgdc#8L7@Pec6hx7G#IeHB30QQJ-tP(0zlpfLOQo3GLdf8x>&t~tGJQP}?95q!ho z3{%kL8ngNA?8i4+_--}uY0r(YbFx-A(a4Z|zwYYX&#dx}es+ z@IS}4(u#m|2F-xyiWYFW@+{WnRHF zUXQo!H;uO&HW*aRX>zl5Tq^P6kkbVpP9M24c8(a^qIZp^6$xUCm#ZX66-wkvKY3<+ z#$nD?tvit`OAqqg(7MvEF@26#D5}#afeg-=6;%U?(sf;>@ zmAn24bFhY7uCJ*9ote|{_W*-r?c7NkryAA^Gwl{;+49k5*HvDdr2SjiHWmttv@cj1 zu3$Vh`H|!fmB9XEyYKWy{O9C057;-Atqk18d^+ zZ=7W=v(wS7Iq=WEu1MQ?U%jmJ6y~H4hxY_bOMHH-6|{d{wrQpCJduf)RI2F@AaK-9^nj;4`2_!WQ(tEdHgCeLuKc@i_nb_?iid2G{0+PlNmWTl<8E;kMvS z6XrIp{=D!xyX8XP0Ka*RTaGhd<2?ARx8Yn|8}HMjJWH?j@^H3A^4tn`IS5_Mdu+kE z_Bo=@R{He!IbJiWui%;amEo?W(8I;d+uR)88X6-S?!7oL{c=KKqn!E;si`eq-X-4; zeycukWa8PDvvm!Rq)pFBN|w#Nf8N1IiRElngS8xsmNK;Ucb2u(PvXKdrbn_-57=Y3 zT)Ap+pzmSs%DLwlCOMa1-!s!x!cTSC<6d1KholWg4DpemT{c$^osx(E?Fqi(=vXeX z;xpr|8GJ(GLPFrxu>pZ@cb%_aynGIH1jiTWpb1Rt4R+kC{_#|nd8=bxt?(-^CMMp< z34a&(omib*ExFIO?TnTF+R?;)#;@QN#+`z#~QC=cpE}wv| zQuEILkIqhJPk4XON@>A4cjqnK%xnJSMsP{$_BUAJ!Fjlu zP0YT$ak{a--4;o~6qg^pjf~}*KOg?fW^+_M(kS!dBg?G64NFy@tYOp^cbF>>QOg$C zzJa^)rRb?T{v}SVDxmdTOT_nB%C602+9erV+iHLKY)3DT`>N@Uh8}Buy;YhQbg3{K zRj}>pXWari3h;=d^kw-q4R5%aHaaGq$V!-fZQ|L6coPm$mZjIs^9}rGy4=$~)WBL( z{d-2EKtrp@3zjtz4_sUH@9jynDF18KWfo8^zh`>S0lC5%k(2U^HX)=jO@z&3+N<6OhWp3a zUe$=K_c&0%7Qs77qe4We+| zo(D%(Z2A9R-L7MyDc`z_OVST`voB3ioXhlMg2a^?(E5LYU(X)GBD_ zyD>~RUgP0dsGi~WL^epBMU8WJhQKlQ))VYH=1Ug87j0b0em14xgY#d8^ZXMGn(lHk z1$OVvW`5OjK$xGoFtJ2c8R)Wc!Bic_K*zVT# z?GsNvxJ#IaPi?|s^>Z<|8Sb$&ExITy_-T`NL{-bm#ty;B@bW!q^M+iIL&^8=HCBOM!UE>E#G`}&oB|aa*$yrulFf%&t%2t#ytBK zpA)afoK;xBBx%}e%D2r`&G^6#1>3mOhSQHVU2(8da3At=(h=*;`**dVb!votIruLn8$F6TA#?22-iC_{oKXru?x+oPPlBZF$Xjc z`Ix!#rKoaIBv%N_s~VFQ)<)^-uiDp*wk&Z@6X}nMI=kWV51tOg6Sg{AjCd#UCG2au z2st?P$Dx=$4p!dG6O#@~`zxMioo`piDZjVw?@PnxwQ5N_AADWDV>)+}-w~#%+q<-? zBqABN{D1s+_jHNVrzc3aKAPmj11d^4ZsiWNPFe85cGL2Sj8{H7^r=V8ve~n{k(=0a~#(rd_`Dc zFKFIvsqpFE-1Yz=p%Y!RdW9uEG*+B;Xp3Gi*I=#qh)yNc^sY)9vU;LR8O&p6Hhd*Io;<^Bf3RvO7tRSL_NpL^f% zMI>Ct`Of2yf6isIt(Q6SYe%v5gsRCKT=;couJ?D|#VVnEOj7cKbV<5@Tyn)fk<6KV zZVUdpb25YW=k5n@sBmdwQeB{49&fNf|L`F(J#hPDJKxLKiDIV~{FT=~__|PV-o$1x zt=$*CZEZ+%ahSSrOOHgC=?QV(CKU(A)<@|pvcBw9GT5phb%m4h;_vyfNhd5!Iv;-e zs|=b}&QNn`6BqFdYuGhR4wknqarCpYGSQYgx^{u&M0xpmqXT+k zEuM=$J3jmKr(@?HuG;k+88bz<8L;O%{r~Vt@7b?Ho!-}TM5Nm^iycnu6+G2w;q7^# z;=Dbdc|L&4C_=_caU5-+*$|TIaZ`qbE9M$tTG2PpG;fV(9jq zc_-@;2Nnk||0{D^E?7T*ki`Z*-mgeFBf0ALw3!L4q5CGJDi!muP4w8toyf4VF*mBd z=ABg-d&3+K@X<>XUc1Z)PWzt6CV#VgjilXY#t@bFeGz8g3)G)2yTxDr&hSOLa$39G zn*%XY-FFflw>_8pP`B)RzaV>)js^cs?$#G?g#3~@>>aPHyHUiN!Jtyqo1ql*HZ~(N6gf8Xh_%zJzV>+4i^;#dd8S*`(Jk0zC;e z%oZJGR#zmhd|)hfDJXSvn9K9!>@x-D4flRFJ~`q3{hiSX?c}%??p+B2PwWk~&pchX zzW;smnK}hlp%Y6Lo+rP(U~nKs(t{1!fr_}UfAcKEEJa7NE2(}w7JJ|N#hqc8^_QX4 zDIm?Uq3iyg$^!+p$Lk;12~_iZKeB$t5r#?bd6!?fJDM-lXP&o%EvAok7N=l93(top zE4ePeSrX6g+-KKxPuwiGp|2}X>`}&#)0dwm^Y*_lw>KzQ$;PCh5SIo}(Y=ISh3{2Mf=a569c!t9!XbgH z;Cf(5bJK;MIehc>AKND)bA1W3a#R)T%wJp;%lWEiGWdNzP+gX=vtL!gzBTdi5zB(` z1}k}~d1XB2+vJlvwzv9R*06#b$ZzF*!Zowy&|7=Rc?!}CYgBmR5E9bN4^s{HE zxfqH}igXkgZkp4*C;Z9l$KgC`xtcr+->FL2Sr$kYs;IxJ<9AueB2<38X^m)Gj-NZ< z_WwK!W?ww`+hJCKe-C4+OTtvfPx}NS9x_6XB-(U1Zb7Ntgr{%zJU*CMT)>^utF{8P zcdQ}ZX~A63-H1nG*blEy_j8ic1r71fRa9^llH!TULUz8o_JF(mSx#YSx4R20X);^YCULyR7>mKMzupdti{(kr8W7BO3|uh z)+zB%RagzJ&MNHYo8!3mJ`-rqGBXRLEy%vbQg&}5`!315wRx-6|7`{_^i z!5V?y$O#UI9zW}B=XoVIWA=sDwrLA87|&K5a1sdr%J(Xv!Q|j4jx~_6Km}=@U2kRf z+PB1NmmpzM)k42YSCb{R_>cNV{!fOerLD;@9Zo2&8uFu z@q*VxKjFG??8~jn&j)_nM@>@LoOih)YZGiyv?H6s`|k}$4Oe_t%zf4VsN~C+_Ve*4 zUP>%^cYF46kOf7vb}+n|AhVanGE-owk$WBw<74*P`|M|UI{yBbbeJxbwEB)?5@<;C zcX7aJ#u>G{x5*xT$=k!m7B!Q}NPg#LM(_Uy+ZEcc_iRn&kvurz@p8vE-suXPd3JQE zgD!hySNhGL`i)tq^Dg%SZnpP#{_@APE$v##ASZL<@|${_r|JvOv7On(>n+fJts%`> z?w(`xQO2{?_Zz$yIn3oPac|1EPd`#3@6j?*Fg#A#mjBS3)}!)8dlYXspZWLYf$q6a zZHz*R39ruHbwA*DLb2zA`}>*(kq=%RMm2RG<)*DU=*oLy_JWxLpy6I8(00nExM@yz z4lvxm!2D{$f^ruJW2O7~`<+Xi7OZpGmm#3TV)EyB>={S?FME~D)&}xiVLEcc3L!r@y;j&oD2syu{^g%AwEv0p=C+ z*`umjmzqwHd9lc8!s>_w@Aw4ejt?Fw2?+}Qw)o-^;}pJ2?@ z^!I`7H|6s8_Q$vCO`h1u_`XQA<7V(QrD;hIW_@JnY|gW@Pwu(#Vtd|M!3Zgq?b|OK zDNNscX4XdD!_iArW`P#xZ-`v*^73Pe3)2%1`W;Vl$eYSgTEqIToT1cdf-LK;8F}lo z+Mdk&Z*k*B5|inlIEMG!jHONz5)u!xTOH^2ZTTgz#B@!-=fth-7kV}3@7nU`fBYBNN~Uyi>Yhn_di?Qod5M&zEP+~D z0neS4xvs`|NtMYreg`cNIPo(v$S8?RYMPwSo-Gn(>zYkC9LyI$PDN+^`~-ByXPDQD zfs_9xlakqon?f>rC3!3`w zv>r9@aPwyejTbR}R`#j;{qbeN^966dJ7|4(eDun0g0M<>n^L|{TFQ+LDMHM447*JK zKHc1YVWvRKDf9UXr&+z9>oD^Rm8iQXNid(bURpfexZ&wUA*D0x7woo^xFCJ_zy?Oy z%iZ_V7)osE6!?E7zp#xPPzjXo$zJs_*}756|7*p&F{#xR59N z+IqIt?RS1R-gmrl%XYzOPRWfXD=IGP>FDg{zxleV{Jv=0)|18(54<-eaEiMzpLKef z^I)ZY;<~^8=TF&l%t1gwe>an++c)`~Z_Fv`XQFP{D*9!vy(?$)&g5mh>~Zz&)0Lk=%L6X>bQq=lRA2E~@x{81#0$UYPN=nj zl>Hz0*eA^|Jj?Z9)?bFm79IA>{&nU;cVC`(Ydz!n#LIl&$}Dth-`ZAkrQd3t%Fi!v zlVnlwK!Dk7wz*tvllj}mJl}fGIkJMx=UO%hcrAU=DYx@elOH7`1A>eTQm5q7`boC zZ>WG>Xe)Qc(s6x_`P;ocrW$|dluF7mp8v^yzU2Yun*Q(e4LLLv`vP6dtl#(v6ue3~ zQpeA^Lb&PPhUT+%2e?Wm?Af?njrqqr{tVS0Y+I(Vi#@Zrbmz7HdC4Oc3Uhs~%whQ` zP?Rium)F4j@SeW4hRv6Lv=$|lnq=%0E!uFUFwFeukipoxbb?IMHICW!4&prj*!fnSj!wSc^6w*O zMgwQ{y5?3@!(P4|QCp244&a-Mi*_8!S)Qd_!Z*3Mh()*_wU;s*WrzOr6m;R3LH6b@8Rp!2VZaB+jB{BSFpn3ZTH+JJZ*Acw?1*hMV>^4 zm4Z*3Wwa8Wyy=_5p`gg(_4y z?{r5G$=rNp<+Q&)zkal3%aOJG(AwH_t@6RGmcBY6 zu{Cd)bhkV8NjzB^u3*2&n)S+0hfWWjy6W2BjA8p5^>ti=`X?@zpRn@rlfSnuOc(0yX3}(CqIqGTK!=+P&w*2A?8UVeo2H0} zCPi$kv}fMq*UERd;SSF%PRH-oD?SJE*=%50wr}<3en-Va95(O%B|NokTeT;vZJXy> zP}3%(Q)~}&Q<6a6pOYQeBpm#0dLpEP75tl~#WrSKSsK3JKm$w1oG^{Ui?dfhWVFoJ zPT4H8#xjP}cILub&No}+JD454*Gx#abdcqb+4%AC!)P|X%EUF7P8|Q#w1+{vI^iYX z-nbiPPX)kj@Sl=f3~M8KpX@mBB20dR?Cs@pX&=sPO9l5MU>@?2B)m3#1^1Y~bb>IqNntNdB!MUXy zE{0?rV%YVO^+%A?7bhX1WCcsk3lrNt7}*kSyn{@$4|(KmZ)jwUKAiH; z_rzRnk5u+M=UZ0GyL>nhQ~Lf$5Swau2HT$oANxPtp`NpXKKVGu4 zSxTPR6_zvg>*KW>E_*3_Tr4yBKtcIQrX{ui1%5kbO77guxOzdtPpP|a(%L=RZZV&h zobbIe=azLp;~maQzL{a|x_ftR(o^lIYRO!>-@NPW+XIUq zI?ffi;KL#Qr7bbwxwFe%uEVYQc~0;0n$A`=yyNNI+OAU{I#D2^_{;Ax~FHe@&?eA^~|oeMUpKd`{U=|IUaeg`N@H~6aN3d z*wggm?ZM~$Jk<-9M=jjVdyVs;THk4T&;VR#xI*QHm*FoyGVPMA^~|(z_A!5T_T>iN zmkGra|9q3G&{W*kC+fkY!v3!1&+%C9|LO~y+F0M8zTO`&nc)i01)h#9i6=@|Z?85p zYOq$>z%*T=`@$!c3N{w4vL$JjUK1XHTDOPu?2d2y2s$ftSv}9;XT2+o*%w$lOwfg_ zb92`_J+Hy)mc+x>C@s*D%Cnna)HJvl?)GQ*i(}C)-*O?n;v3hb{t2N6Z=8@7c=Cxe zIY1)J!g#^DRZLGa3)oc@^k*hMR5{|Qx!|unPX$B9{^N^WC)}=ctahHD9d{#6u;3{7 z+6OU@cS$-dk2hT4ThpB9W?tacbbrA;#dlo8u8;T8L~k2Z(2CDzDo zvixh$Ty&g8g>jbPPsW(TCl)r`;(Rzk{Lri58=JIes8s!yxN?x;-i-I8X~q< z$?bc>xYP9SQQ;Fl905-kSFe|FNE5%pYT%P`>%ak3l`|jS%0{Vo^aQ2feZ7;%anXcS zt`j*PG6oI(kJlRTBp*mK0WCE=|DUnqEGbv_(6GEHRlVSY<)%e^ z`8%4vbvNkg-PywYwMp+n&xymw-#5+`h&ev%AA6aFm{Eh3oQABu3jd)`A1*)tzTuke z0&Z@}i$;u9&zWz2+~BlIB~O@nTkv{5o!Ou}$Q#m}euyga)&@LxK6g_>nMdxeEw@(>xB&2V_NhE~K)^AMVzFc(CtHtHjs&j5FPqsJpRUImfop{==e= zfq#0Y@L&Ai^+Kx3D8_F8T*keQ8{XdWVFS(P<{$X<;##q>goCm2k4vCSNZv;u*-%g{ z@9d+pL@s*MABzuHv}!k)6=o{7nR0(KZm?2(pc>_H@pSsTN5+#L9^PHe({$*R#!F5y zchFYSNfLAU_bmIDe&Fg)hD_#@oScof7$$t-xLr~A|8sQD&YFPd%C`)eYz{2dS$N{Y zo;}Pt#Ucf6m68Q+mWPfvBp#g>3p#9q*^oh^+eiO#fbtWh+o`VVrn4A(5Gj z|AG(45rH#S?KimDK3X!_o_WtS{cy9DqJr%OCAP)ROsg!mg?)eYRr<%ZFVWvYjeZ*~ zNA;w}PjeR;r~T#t%~|X<*Z6wn*4p5Jbo&cu;?m_Cw3tpgi||x6S;;@zrN(oGX@eh! zMa@EH)&T{oL-pZ&Q`wM8NX5$U+l{2iSIY{lO z^NY*)*d5pTu&?gQIWFcMpe1e!XF(?{{n@r+_SFfuv>&ka<=$tvn8+ZixBBKOhF2AT z+*jEq_VzBl8V!o%6M8M*c^VVX@!ok4N=8Ba;AWMjtVTxa)RPAoVmE9_zg+^_VN;?g ze@6GjL-rtc$fkoUjYkyc3S4PBP@l7wVT%vf>lzlfXu~z}RXvWUg^cFbzx`pj|`2{Dm~yT7whuu|dwoPYJL2d^;wR{Qe&KyvlP=;Isu*w-jC zc~0kakIeHDr!oSYprWq3k|+NA>gCVQHE<{NG&~67;NuFI_b_}4xYwP@ z+6n4)KNZ}yaRHNH_CoeASI$Kqm-xUKp#Fq+gRnZ&-q}nk*FXMV;ohqB{=37v1&)sv z2(Nc|1{zdf&MzQc;(p=H60x=`l`Fn$ANW?Qusn1Ec)N8D_|T)>TLj*zFHk(56)kx{ zmjB5Y&fW{jrn;a3gf9jRcNrf=$DY}+bL;ej>$bKy3RFz~c&sBvBz3yk+H{T0j(aaN zY*l7IsVgs+Xg`&+C{a<#eXiwJzU+`Y%x(4>|K{izPM_ZJt^Q8^A4b*Ri~Bws8h{ox zOZV*g!j)pJ?AFX2^sn)WO5M5p(dXRR*RqrK8t2Z>Oq=A-UN#cmcRla- zyqBPsZ-tr**Q5M^=gy}jO5=r;r}c2|GFH*x3jA+ZU)B8Z^m20#Po}MfT&Jhsuu@FO zPg=b`k(D9nz@jDjD=fS&INas3E)qY&>si2377)Ph=U}Y#{{Edr0nk>VFb=N8^JTuu z--&eeG>LfJBv`TA^4(s4g})1|o$oQS?^iHZkH)L^Z+U9sJ(hVh-GOSzWL57@3&70?+@N4oaqap)_H^EmV_IM?21 zo8tE4l;e^}HlM3)zHisIRWi-;l)p3whI$?2}oWEVcR9mGLh-x*+iF&Mx%@V`{?U|$W zT!TOpG5Y(NI{&(_f40z(Q-r@`Q_77EJVwDxv+h<@h#OsQG~k-}=>oS-py-yFk}Kk& zVOeIpV{>cRt2sAICoa^j5^A2uoRanb65|yvK9k>#Ic&T79oIR(%Q;{qSLBv{fJve- z%s^o7g2!cv>T!zM{~OnSZd}@QJni{sYY$_$h&Sz$%tf=;h&=P*Ncq;>$T+?JnO=6< z0d^ai#S-&ucAo~_>=pL?-Q{35MY~L%wHv;)=6+*dCowDL|Kths4|r`7ezD5#sbi)~%-Y65)!7Dp*IQ#vIE|< zn}^B~5~;k*&MV4fy1s8Xda-`VCdLv?#j1S`KZT1D6(5Bx%e3>B+_Y_hUV4kAAY`&_ z2J@v==8Jc*R_XR%uD<1gA{opX)3@}}sC zjVBgQ-*B`4KhOV%rz5wYo7Z*Oe?_U(ETbi#-aHLHVx$oe!*bmEkoANGHz#R77Xvj9 z7R(f2RPBWYi<9)EUzko&!8MXBKWH71}T z(S#4S7Ze=%Re4eu{FQ&e`@*A6IAj{bbHNKiIv45$QhXOk3g*le_~OT@G5uhkhx@hu zec?wA@l;g*%6>9=$3NqaF0LfmYwRcPx!J+GDbsTonGSe_)%l zAxyxLOH z(ho3Bm>%1>SWt5zs70FC9wXSqU6(U+DxjM6KduZ9*=g#>@Bd$d`VP9g3!`qw#hnUhH)$h4@SW}@-t6%2) zh7Sy@EcQPZi;?x<^x)dOup>smu<3i1H4SFVo3%9cJU!VikKxFO9Z7c&s7K>0T{MnbQwNR@)5w6VLWekUZnCJZj2}y8oP~ zHDh{a7^fUr5?dK~g^M|4n@!zc2HoyI=?zPLpD0&9?Aov-zoz%h@BDcN8l6sNFAp7( zbUXZxg>h!@J+Cls9~7T^>{Q;h|phq6J*jRwSla7?v8{)42TQbNY`D zFBF+m)L1ND{rSfiB(fl^L_xhF%_+ezbADZm;yu~YZEx+pRvnrjbz$|b-Tw29KwBJR zH|$_2^|#FkG(976l`$4b$;RgCQu2-n@&-!HgU`~CcMj$i|Z>B1Y%aa2h%yjM_q>9$=; zHJ9P-(eSQzmxY4S4+IJ-F3bp zu5FWnK;VidE5QxcwimSHE==6L;Y{1=N31X1*H0}REH=VSFF~#jYkMXkSo6jv<*<6jHI~Y|*6ZFWzqsTm8F}I!XT*d9 z88_xCeBk)QzuH8RR|d4Yhh0H`FHiM&+Ioa(HCmfx2Aa&{Si_>P=RoBgaXcAS&wvsj1 zCB868+iM2+(2=Sm3pn1k98gIV=RNd8;lE8qvn4~*zVIW;96@=Fiv+H49=!IGVJ4># zd#RJbW9}^FqDEE|9?+1&Lk;is4WC~8{POqmbDjsO5m#*sa#yd{bNXnV;r8U-@7p|G zOe^LJ1UzRpS={*Md%OJmg)iRT3OUa3vcbB@5Np8E6(7iZMtHx&Z+i#n z3ls0weZQ>D_GAO&M#t^*t0U4DM7X~@AaZ6x>FHI0XPoc7Z?v)I5MrNO!5YMKYtBFU z%y_j9-d&Qm_ZGG$CTgebd@z-}{ope-hVS(cR);1OmOoWm)L2vT-BrZ==B`)9dl=4j zb$Bbj-Q6N~<;XO~1%50UYRowX)2c*lelt#TS$}xLwM>EMYpV(v&v1mBu#~%n#Wu+# z1Z{f4=CE?wrw2&be=qdNSi>>h^U;E2=UL?%XSDcC9kUmqEh~9>(j=v3u}c(PS)jN_fZIX}fRV9L6i0Ke=Rj97>!dKAbyt@K*GP-F6A< z+NMYHtXO??K_`z2@2)8V(V&fjlZ08~3VLK*K710Kaj`OWi6rO}+tLMo938yxIuxc) zzp$n0(#-}*mTqI6mpoSlK@;T#VyAd`c38;VixcttpeI zBtj>novjoLcnh2z%jH&Om1vEz!PTbRf?zMo7^6BItx@jp2y2DvDPH>239 zNRcV2InPZ$ZsLIp(i<6$CabMI$&(azOJW}D+y4yt4(?qyp7Ji`naF$h0iQ?OvpN@b z7WaTgJ&8a6pV&7y@;vih1YSs(-72~9)iWl)&$ZRPJ3e@;o|yUY!mhaySDOwoZrLak z`{}~NSPduscY9J8N}V=HGOfSSF!QHm-#PXZOCNA^ryhNH`Srt7Wg5p8io01fvBfNt z-L+*JqdddiS^xNMaUNXCcZKudl;7tYR)1y;;-2*Q0sGkkhnm{23`-WOFU;)Sn8TnN z&un>dZ61&JYQ@uM9DX}bn4aosxqFc%>&~4Y<~NFbc>A*$)Ip2n&j@4LyXJ5Io!QN5 zs*VpJ$7e(;6h^4C+_hc6&F0v;a}M{jV|Ew*_46OtZU4d4%kf#GmFfaNj+zunO@^;` zWF`CF-)YLy4f$tz>1EQ1O7Sb4jyX=#6K2$InGR~^oo&(Ra$s|Cn9Hy3%iZ(fZn|BM+}xyfJs@M7m2Pq@Ji(TExDD&EzwqF@wqP#!dH`S2nUjvN5;S-!4YozG7&CZ1#DbXu6QrKBb?$AF?)uMf*YKov zLe!HFEl1^7d~RIBxQs1DH-l5G$fj9OD`p4l);El2JMJ)@OF3YrXs~&LzEsQ3k8;zb zFJ1iJ)i5og(QNVjo!=W6pW6wr9a+QnVn^(a&hQie7)t#vT-MOg-6p|mctxh^O?9Rj zSIP?8?Q&~;r^Jh?-szC!X~}L_c31pBt^DzZ-v`fxT$skas8mPd1H+f6-3xv@fo_nH zaFQ0{HoFcwihV~9qwY$klPB3*j6R%jmU(5`P`=0R^ zYxKQyt1Aye@2Y)#&z6nP)pdh$#<$iX42@XbE^%GhAik_-%QxEj9?h$5sGv$u$ z{^^PvD)bI-iu15zEVXlZ*7$pr>(WeSQ){ykEz? z4CYspneWZw<8D759d=-D-=!wTng8YY<{V#hJW;72JK&3fkpOc-)P&Cli-bWZnm9~! zJiMvv;T5J6Ivwj)nH_$5dj)gif|QOsKN;TgTW%GYB<_$iL1w+ms|4{AXWOHjW2oEzS#Gm3D-XkmwJ&>a9Ok}P`QJb4FIVyVdbW_- z1?SpJA|#l_4RY_ldy`VI+h%&=^gN^H<$Zz`N@=&B7W1h4#ilZpI>jk(J?}7=-zDiM z|5tY94Z=!?!Q+P9LhU6^0xMsO7Cd9U!>Ku^S@2sA&yLGH>kcxP{BPuGUHX37nUJj*@ZJz-Uw5qFE60s#cGWZEn^carS^XC!FYQ>~f1>Yc@k&x%QJdLCXdPge{+ z0xH+kN-tH?y5wDN_;T@(}`uAUHBXKyx_y4KG*!~;R-pT1 zhuK#hXJ2#l-jeX{z>OBZGf%kF)*TmL!m}Xy@_f6xlM1|hO=V+0HlNp*5c#Q)-6q(o zzHB0BF+iTc44yR)oR&Ent1a+5@%y}f;V#Y+6a7^x%7-6M{_z)d429~SYb6uvICWoS zXiaP4i`&L1xqy#7C)w&uTukcy@&`+s=S*NBBIkjcwUjtkClEW3!;u>P1A{g*yHmzC$Z48st1XGSVV8EE03J zTyvxLuVj_Thk6f2{-XXxD|o=`xCFq<;qC;q|76@7c+SJ6dVyiRTyvPst+l&POmti! z)N=itfPNkHJiZD8^E|dPj~t;z5))3Z`(7@8$okm-PMNDrr5+A*1yc4aZ&uWE_-b;Z za>3KEA3_2vjG2tmA6}dL0KCaEVmY(R?%7G_cD=RXommQ**4emSFTtXsgz1My+=N<# z={D^5c$r?cB)ZDg zY+L+Kv24z(Ei02}{&6FA3Cri7m!;P@vb}OS@a{{)(sBvj-NG!7%H7zWv@xwQX1c`R zoj+sG5{)Nz5>qNt9j>Sp{hQF8{r~^*xyL6SmcIG$f8mn&0CkpS@BY1w<(VCR1a$WG zfu|u0&au6)o4|cxw}ZoP`v9h7`INbq6)#0E)ZCb>D6SXlpm8`T@W7*wwi%Bt1LUrK zWXN_ZQvY!xHX>%hQ~fKdZvQ1ey;5-h(41y(@Xh;A`xMRocXwI&E;*)2h~_A4e!$-s z$t0dM2CK#oD!kY8m~DPM3JUsR=&SWDeR>&wjU}Pj1-- z3&xX;){6iC8(&~$xciTHSICF2jwg7OzP)g(xO7Ow=tRwx1hCU?p)lS^xl%~g3gJ(=?DBeL|(ZWsCw#1 zA3l(H-lMSU$IlnChmRlb=#CK(KtR3d|uYVt)?HBRwUE#D(gQrt5>Ip^I_EH~pYeRD#WA;7J80p~-_51-s`Jo^&ME_Pr# zw^EVN6|)TI$M%AvLRFFi9;O#h9 z;LF75FWubyin^zrtcJQOCZMSujmu?+Q_s6`vE6*sQ!{!`%L|>tCGoy-DUL z*QJd~rwc&^bdH#be)Ey3ji)z)4*PfoI*|56{gOTUx|s~UJ{{5%9!r=AAL>v#-Eb+m z{pau7v)v=yeH_Kbl-hY$98N4>-S%)o6nFE=W&Arf_UEPu$oV@QdoIo|;V_r?%a`8V z&p)T1&zBGh^^x?u>lmxYF-x%W>q|lAHNs5B+;jPhPT%&Qahmnw_pUW>E&UC4EB=-~ za_yXcD#O_(h3ldxJ~re%_`Q9B(bo@VDua4A5rRRF7)mWBm@1Xq1@Ihs zR-3e!-N&9ko9`hn*N3$)x8Da9Pdh@4CI$a|xKS+YPWXer;ja$-4&UbZKK>%J+_a*X zOc`bp@p?%O=Nk+ra3ox1`SE1!e~((p1(u5(r&(NIedyBhzsJELJ7MbrTSWz_BkZMq z7hZE;c*E`?S0t!t!Vqs))3mWqJ}z@Y&_^eCMb7X`6DEXl_a#MaER)sw9m$T-aloG33;K#8>!9B0zz@49>HS8Qm^1iHT(bZQD z=TbPGxQ_4S{4*ckv1ZJYRoYaP$`9I`40bf=P%3xLGrR2)J}GQfcwZV9!Fn%3PlbJ_ z$JAzY*m(o-_$J&TG%!8-rKi^Oj+Q^?(^x{RZAC9_WSmGQYzZb zOu1jx+(_|BtoZ(ci`hdijPsuTwmwJQ>vJDodoq`2-@6G*Yl<$gy}Pn=x1_^dffGI) zOD;3Ms^O4UoMvIE)83P{$F`j9joFPg$M33gOLl368`#uWNyo_PL`N_$yLv~t;k&4Y zQ2?)ks(r+*9~JK8bJJqpxK1oqikcPj8OK_Ske>n&I@_;DT&VN{E%h zdpp*7n^b$33N!6W`0)RKHqWzfH_R6{=ef+k++MZX60|;R?d}dgjw^FFbhABtDrnGH zzo&ht3~TLr@R=0tPXc`PoiiqIHZN-8a1OuE$Htp%+$No_xcTvd0#@0R+_$bX8vV~Y zm%V7x;oh?ol)dN17#|e9ss7>~$CEv^&qQ8r@?h2Xo|7hgouw(GeY&H>GDRVUp096g zGfbulUXEL0Bv7KMxGpeff=q_6#=2eof~Vc`bBv2L=JMJw2T#~?26W5A4V#)pJk!tT zGM9r|7Z-fmIOJ1yDy;atP_ftYbx||prWgV6LHH`mq%L_(4+%&EdQ9^Ftqp)5dT&N4Zw}&5J=J_LU{# zn|>vHe_PCx{Y*D;#?5=|VbkLpBl`b8`RB~$qTa&T%6seg!3JiVy}XgNOuOF7lpItz zq5aP7hWWz#tn0iE#-3~Z#G%Z*@`2n3rla5I+X-Cx_KEjPl4FD_&t@*mQy;e+wr4h9 z{NMiDe8)?tM3%>b+LaY?jGU=#jtci|4Er3_88__@b6_><;Jg*X_parR~I1mClsoOv21+P7uk#=0l{XKO>a~X@?=qY`?7sb6Y;^9-BfM%r)!cDtB zGa7!p`1$yQiC)>tXPiX0{C{lt!N_LHHJ)jIn0C#Xz_?bCB|G}fjb^LI3|4L8kY2zF z2eUQJR`P9fGk)uwd%uIPOaz%+v~NNVBq%^P+w%Wmhk{>XJx zFW@=L61K8@ju#wpA2cJlr#DVdZA^CxQIK^GckSxD&SR&-GIs&haSxma}Q$TeRS5{)GFE(&sOJuS?+em=XVYQh@)*>Q54%|H+=- zRwAN&?|ucxv;P&J1@Ec4^Ob*^)gPuheZz01`lHt24wuKTa&{4(an)6NS_tXC8pBfIuplu_a1Qor$!UqF7#cjjgP zI7*VOGS;6s%)46f^zQ{fIhTm<+}wDt!;!Pv?UM8Xg}>$Y36a~_Ou4ry$}V|#$?giD zea8M1)(--oJn-X~=ECp_bcNUnR&yh1-}95%`5UEAElkxcs$?qVUh$dn64R}Ua}9d@ zPnxY1ANX+w{1tw|&|Ec#m3hC>lH8(Ib=+0<9g62Ti?)mC#5eWbZk=1v`o<>UdCSCv zA4%&MPdvM`y)60nZ~ym_1x!m`xa_W&pM*A8m(d|vRZhEXrNzVHptveJl0 zPyTYBxoMh{$-C#HjK;@*=Zg2t<)0B3pw3*o+0ujW_FVab-wzIU&DxjhgxSVgD zWk-ROL7#)MvQtwK5BsRb`43*cylA^7H%iq~l`ZEbC&N#s6}Ihn{w6UnFfe$!`njxgN@xNAh{8!o From 75ae4d347a58673977000104ccd1b9124deaa6dd Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 14 Nov 2025 16:34:56 +0100 Subject: [PATCH 089/189] REXM: RENAMED: Reports moved to reports directory --- .../{examples_report_issues.md => reports/examples_issues.md} | 0 tools/rexm/{examples_report.md => reports/examples_validation.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tools/rexm/{examples_report_issues.md => reports/examples_issues.md} (100%) rename tools/rexm/{examples_report.md => reports/examples_validation.md} (100%) diff --git a/tools/rexm/examples_report_issues.md b/tools/rexm/reports/examples_issues.md similarity index 100% rename from tools/rexm/examples_report_issues.md rename to tools/rexm/reports/examples_issues.md diff --git a/tools/rexm/examples_report.md b/tools/rexm/reports/examples_validation.md similarity index 100% rename from tools/rexm/examples_report.md rename to tools/rexm/reports/examples_validation.md From d29112fb1f5f00e91150d9a56c1861f491b6574d Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 14 Nov 2025 16:36:00 +0100 Subject: [PATCH 090/189] Create examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tools/rexm/reports/examples_testing_windows.md diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md new file mode 100644 index 000000000..dca13478f --- /dev/null +++ b/tools/rexm/reports/examples_testing_windows.md @@ -0,0 +1,18 @@ +# EXAMPLES COLLECTION - TESTING REPORT + +## Tested Platform: Windows + +``` +Example automated testing elements validated: + + - [WARN] : WARNING messages count + - [INIT] : Initialization + - [CLOSE] : Closing + - [ASSETS] : Assets loading + - [OTHER] : Other types of warnings + - [RESULT] : Ending program result (0) + +``` +| **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [OTHER] | [RESULT] | +|:---------------------------------|:------:|:------:|:-------:|:--------:|:-------:|:--------:| +| core_highdpi_testbed | 2 | ✔ | ✔ | ✔ | ✔ | ✔ | From 74f7112614e74cd243af8a2941839fb33cf275d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Fri, 14 Nov 2025 11:09:30 -0500 Subject: [PATCH 091/189] [examples] Added: `shapes_rlgl_triangle` example (#5353) * [examples] Added: `shapes_rlgl_triangle` example * correct name * formatting --- examples/shapes/shapes_rlgl_triangle.c | 189 +++++++++++++++++++++++ examples/shapes/shapes_rlgl_triangle.png | Bin 0 -> 22402 bytes 2 files changed, 189 insertions(+) create mode 100644 examples/shapes/shapes_rlgl_triangle.c create mode 100644 examples/shapes/shapes_rlgl_triangle.png diff --git a/examples/shapes/shapes_rlgl_triangle.c b/examples/shapes/shapes_rlgl_triangle.c new file mode 100644 index 000000000..9174110e4 --- /dev/null +++ b/examples/shapes/shapes_rlgl_triangle.c @@ -0,0 +1,189 @@ +/******************************************************************************************* +* +* raylib [shapes] example - rlgl triangle +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev +* +* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025-2025 Robin (@RobinsAviary) +* +********************************************************************************************/ + +#include "raylib.h" +#include "rlgl.h" +#include "raymath.h" + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rlgl triangle"); + + // Starting postions and rendered triangle positions + Vector2 startingPositions[] = {{ 400.0f, 150.0f }, { 300.0f, 300.0f }, { 500.0f, 300.0f }}; + Vector2 trianglePositions[] = { startingPositions[0], startingPositions[1], startingPositions[2] }; + + // Currently selected vertex, -1 means none + int triangleIndex = -1; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Reset index on release + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) + { + triangleIndex = -1; + } + + // If the user has selected a vertex, offset it by the mouse's delta this frame + if (triangleIndex != -1) + { + Vector2 *position = &trianglePositions[triangleIndex]; + + Vector2 mouseDelta = GetMouseDelta(); + position->x += mouseDelta.x; + position->y += mouseDelta.y; + } + + // Enable/disable backface culling (2-sided triangles, slower to render) + if (IsKeyPressed(KEY_LEFT)) + { + rlEnableBackfaceCulling(); + } + + if (IsKeyPressed(KEY_RIGHT)) + { + rlDisableBackfaceCulling(); + } + + // Reset triangle vertices to starting positions and reset backface culling + if (IsKeyPressed(KEY_R)) + { + trianglePositions[0] = startingPositions[0]; + trianglePositions[1] = startingPositions[1]; + trianglePositions[2] = startingPositions[2]; + + rlEnableBackfaceCulling(); + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (IsKeyDown(KEY_SPACE)) + { + // Draw triangle with lines + rlBegin(RL_LINES); + // Three lines, six points + // Define color for next vertex + rlColor4ub(255, 0, 0, 255); + // Define vertex + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + rlColor4ub(255, 0, 0, 255); + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlEnd(); + } + else + { + // Draw triangle as a triangle + rlBegin(RL_TRIANGLES); + // One triangle, three points + // Define color for next vertex + rlColor4ub(255, 0, 0, 255); + // Define vertex + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + rlEnd(); + } + + // Render the vertex handles, reacting to mouse movement/input + for (unsigned int i = 0; i < 3; i++) + { + Vector2 position = trianglePositions[i]; + + float size = 4.0f; + + Vector2 mousePosition = GetMousePosition(); + + // If the cursor is within the handle circle + if (Vector2Distance(mousePosition, position) < size) + { + float fillAlpha = 0.0f; + if (triangleIndex == -1) + { + fillAlpha = 0.5f; + } + + // If handle selected/clicked + if (i == triangleIndex) + { + fillAlpha = 1.0f; + } + + // If clicked, set selected index to handle index + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) + { + triangleIndex = i; + } + + // If visible, draw DARKGRAY circle with varying alpha. + if (fillAlpha > 0.0f) + { + Color fillColor = ColorAlpha(DARKGRAY, fillAlpha); + + DrawCircleV(position, size, fillColor); + } + } + + // Draw handle outline + DrawCircleLinesV(position, size, BLACK); + } + + // Draw controls + DrawText("space for lines\nleft for backface culling\nright for no backface culling\nclick and drag points\nr to reset", 10, 10, 20, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/shapes/shapes_rlgl_triangle.png b/examples/shapes/shapes_rlgl_triangle.png new file mode 100644 index 0000000000000000000000000000000000000000..9fec558ff1e337157e488886e18238018cf4907c GIT binary patch literal 22402 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 literal 0 HcmV?d00001 From 470a3265882968b624f475f3c9f349be962adc43 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 15 Nov 2025 16:47:11 +0100 Subject: [PATCH 092/189] Update shapes_rlgl_triangle.c --- examples/shapes/shapes_rlgl_triangle.c | 172 +++++++++++-------------- 1 file changed, 77 insertions(+), 95 deletions(-) diff --git a/examples/shapes/shapes_rlgl_triangle.c b/examples/shapes/shapes_rlgl_triangle.c index 9174110e4..695e6a00b 100644 --- a/examples/shapes/shapes_rlgl_triangle.c +++ b/examples/shapes/shapes_rlgl_triangle.c @@ -16,6 +16,7 @@ ********************************************************************************************/ #include "raylib.h" + #include "rlgl.h" #include "raymath.h" @@ -33,11 +34,13 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rlgl triangle"); // Starting postions and rendered triangle positions - Vector2 startingPositions[] = {{ 400.0f, 150.0f }, { 300.0f, 300.0f }, { 500.0f, 300.0f }}; - Vector2 trianglePositions[] = { startingPositions[0], startingPositions[1], startingPositions[2] }; + Vector2 startingPositions[3] = {{ 400.0f, 150.0f }, { 300.0f, 300.0f }, { 500.0f, 300.0f }}; + Vector2 trianglePositions[3] = { startingPositions[0], startingPositions[1], startingPositions[2] }; // Currently selected vertex, -1 means none int triangleIndex = -1; + bool linesMode = false; + float handleRadius = 8.0f; SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -47,11 +50,7 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // Reset index on release - if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) - { - triangleIndex = -1; - } + if (IsKeyPressed(KEY_SPACE)) linesMode = !linesMode; // If the user has selected a vertex, offset it by the mouse's delta this frame if (triangleIndex != -1) @@ -62,17 +61,13 @@ int main(void) position->x += mouseDelta.x; position->y += mouseDelta.y; } + + // Reset index on release + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) triangleIndex = -1; // Enable/disable backface culling (2-sided triangles, slower to render) - if (IsKeyPressed(KEY_LEFT)) - { - rlEnableBackfaceCulling(); - } - - if (IsKeyPressed(KEY_RIGHT)) - { - rlDisableBackfaceCulling(); - } + if (IsKeyPressed(KEY_LEFT)) rlEnableBackfaceCulling(); + if (IsKeyPressed(KEY_RIGHT)) rlDisableBackfaceCulling(); // Reset triangle vertices to starting positions and reset backface culling if (IsKeyPressed(KEY_R)) @@ -89,92 +84,79 @@ int main(void) //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(RAYWHITE); + ClearBackground(RAYWHITE); - if (IsKeyDown(KEY_SPACE)) - { - // Draw triangle with lines - rlBegin(RL_LINES); - // Three lines, six points - // Define color for next vertex - rlColor4ub(255, 0, 0, 255); - // Define vertex - rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); - rlColor4ub(0, 255, 0, 255); - rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); - - rlColor4ub(0, 255, 0, 255); - rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); - rlColor4ub(0, 0, 255, 255); - rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); - - rlColor4ub(0, 0, 255, 255); - rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); - rlColor4ub(255, 0, 0, 255); - rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); - rlEnd(); - } - else - { - // Draw triangle as a triangle - rlBegin(RL_TRIANGLES); - // One triangle, three points - // Define color for next vertex - rlColor4ub(255, 0, 0, 255); - // Define vertex - rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); - rlColor4ub(0, 255, 0, 255); - rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); - rlColor4ub(0, 0, 255, 255); - rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); - rlEnd(); - } - - // Render the vertex handles, reacting to mouse movement/input - for (unsigned int i = 0; i < 3; i++) - { - Vector2 position = trianglePositions[i]; - - float size = 4.0f; - - Vector2 mousePosition = GetMousePosition(); - - // If the cursor is within the handle circle - if (Vector2Distance(mousePosition, position) < size) + if (linesMode) { - float fillAlpha = 0.0f; - if (triangleIndex == -1) - { - fillAlpha = 0.5f; - } + // Draw triangle with lines + rlBegin(RL_LINES); + // Three lines, six points + // Define color for next vertex + rlColor4ub(255, 0, 0, 255); + // Define vertex + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); - // If handle selected/clicked - if (i == triangleIndex) - { - fillAlpha = 1.0f; - } + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); - // If clicked, set selected index to handle index - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) - { - triangleIndex = i; - } - - // If visible, draw DARKGRAY circle with varying alpha. - if (fillAlpha > 0.0f) - { - Color fillColor = ColorAlpha(DARKGRAY, fillAlpha); - - DrawCircleV(position, size, fillColor); - } + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + rlColor4ub(255, 0, 0, 255); + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlEnd(); + } + else + { + // Draw triangle as a triangle + rlBegin(RL_TRIANGLES); + // One triangle, three points + // Define color for next vertex + rlColor4ub(255, 0, 0, 255); + // Define vertex + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + rlEnd(); } - // Draw handle outline - DrawCircleLinesV(position, size, BLACK); - } + // Render the vertex handles, reacting to mouse movement/input + // TODO: Vertex selection can be moved to update logic + for (unsigned int i = 0; i < 3; i++) + { + Vector2 position = trianglePositions[i]; + Vector2 mousePosition = GetMousePosition(); - // Draw controls - DrawText("space for lines\nleft for backface culling\nright for no backface culling\nclick and drag points\nr to reset", 10, 10, 20, DARKGRAY); + // If the cursor is within the handle circle + if (Vector2Distance(mousePosition, position) < handleRadius) + { + float fillAlpha = 0.0f; + if (triangleIndex == -1) fillAlpha = 0.5f; + + // If handle selected/clicked + if (i == triangleIndex) fillAlpha = 1.0f; + + // If clicked, set selected index to handle index + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) triangleIndex = i; + + // If visible, draw DARKGRAY circle with varying alpha. + if (fillAlpha > 0.0f) DrawCircleV(position, handleRadius, ColorAlpha(DARKGRAY, fillAlpha)); + } + + // Draw handle outline + DrawCircleLinesV(position, handleRadius, BLACK); + } + + // Draw controls + DrawText("SPACE: Toggle lines mode", 10, 10, 20, DARKGRAY); + DrawText("LEFT-RIGHT: Toggle backface culling", 10, 40, 20, DARKGRAY); + DrawText("MOUSE: Click and drag vertex points", 10, 70, 20, DARKGRAY); + DrawText("R: Reset triangle to start positions", 10, 100, 20, DARKGRAY); EndDrawing(); //---------------------------------------------------------------------------------- From 5c2747e3a81ee269015f7a0512b7ec53aee05469 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 16 Nov 2025 19:13:01 +0100 Subject: [PATCH 093/189] Update shapes_rlgl_triangle.c --- examples/shapes/shapes_rlgl_triangle.c | 42 ++++++++++++-------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/examples/shapes/shapes_rlgl_triangle.c b/examples/shapes/shapes_rlgl_triangle.c index 695e6a00b..1ce8e7949 100644 --- a/examples/shapes/shapes_rlgl_triangle.c +++ b/examples/shapes/shapes_rlgl_triangle.c @@ -18,7 +18,6 @@ #include "raylib.h" #include "rlgl.h" -#include "raymath.h" //------------------------------------------------------------------------------------ // Program main entry point @@ -51,6 +50,18 @@ int main(void) // Update //---------------------------------------------------------------------------------- if (IsKeyPressed(KEY_SPACE)) linesMode = !linesMode; + + // Check selected vertex + for (unsigned int i = 0; i < 3; i++) + { + // If the mouse is within the handle circle + if (CheckCollisionPointCircle(GetMousePosition(), trianglePositions[i], handleRadius) && + IsMouseButtonDown(MOUSE_BUTTON_LEFT)) + { + triangleIndex = i; + break; + } + } // If the user has selected a vertex, offset it by the mouse's delta this frame if (triangleIndex != -1) @@ -126,30 +137,17 @@ int main(void) } // Render the vertex handles, reacting to mouse movement/input - // TODO: Vertex selection can be moved to update logic for (unsigned int i = 0; i < 3; i++) { - Vector2 position = trianglePositions[i]; - Vector2 mousePosition = GetMousePosition(); - - // If the cursor is within the handle circle - if (Vector2Distance(mousePosition, position) < handleRadius) - { - float fillAlpha = 0.0f; - if (triangleIndex == -1) fillAlpha = 0.5f; - - // If handle selected/clicked - if (i == triangleIndex) fillAlpha = 1.0f; - - // If clicked, set selected index to handle index - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) triangleIndex = i; - - // If visible, draw DARKGRAY circle with varying alpha. - if (fillAlpha > 0.0f) DrawCircleV(position, handleRadius, ColorAlpha(DARKGRAY, fillAlpha)); - } - + // Draw handle fill focused by mouse + if (CheckCollisionPointCircle(GetMousePosition(), trianglePositions[i], handleRadius)) + DrawCircleV(trianglePositions[i], handleRadius, ColorAlpha(DARKGRAY, 0.5f)); + + // Draw handle fill selected + if (i == triangleIndex) DrawCircleV(trianglePositions[i], handleRadius, DARKGRAY); + // Draw handle outline - DrawCircleLinesV(position, handleRadius, BLACK); + DrawCircleLinesV(trianglePositions[i], handleRadius, BLACK); } // Draw controls From 596d3bcb7e658a82218c84fdb437310a960bc0dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agnis=20Aldi=C5=86=C5=A1=20=22NeZv=C4=93rs?= Date: Sun, 16 Nov 2025 20:40:49 +0200 Subject: [PATCH 094/189] [examples] Added: `textures_screen_buffer` (#5357) * Example textures_screen_buffer * remove resource preload for web makefile * update description * code formatting --- examples/Makefile | 1 + examples/Makefile.Web | 4 + examples/README.md | 5 +- examples/examples_list.txt | 1 + examples/textures/textures_screen_buffer.c | 161 +++++ examples/textures/textures_screen_buffer.png | Bin 0 -> 31532 bytes .../examples/textures_screen_buffer.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 27 + 8 files changed, 766 insertions(+), 2 deletions(-) create mode 100644 examples/textures/textures_screen_buffer.c create mode 100644 examples/textures/textures_screen_buffer.png create mode 100644 projects/VS2022/examples/textures_screen_buffer.vcxproj diff --git a/examples/Makefile b/examples/Makefile index f36b89bc2..ccd24bf28 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -619,6 +619,7 @@ TEXTURES = \ textures/textures_sprite_button \ textures/textures_sprite_explosion \ textures/textures_srcrec_dstrec \ + textures/textures_screen_buffer \ textures/textures_textured_curve \ textures/textures_tiled_drawing \ textures/textures_to_image diff --git a/examples/Makefile.Web b/examples/Makefile.Web index d2336e7df..01426d7f5 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -607,6 +607,7 @@ TEXTURES = \ textures/textures_sprite_button \ textures/textures_sprite_explosion \ textures/textures_srcrec_dstrec \ + textures/textures_screen_buffer \ textures/textures_textured_curve \ textures/textures_tiled_drawing \ textures/textures_to_image @@ -1058,6 +1059,9 @@ textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/scarfy.png@resources/scarfy.png +textures/textures_screen_buffer: textures/textures_screen_buffer.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + textures/textures_textured_curve: textures/textures_textured_curve.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/road.png@resources/road.png diff --git a/examples/README.md b/examples/README.md index 82a91e60b..bdf50cb82 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: 194] +## EXAMPLES COLLECTION [TOTAL: 195] ### category: core [47] @@ -114,7 +114,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | shapes_lines_drawing | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) | | [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | shapes_math_angle_rotation | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) | -### category: textures [26] +### category: textures [27] Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. @@ -145,6 +145,7 @@ Examples using raylib textures functionality, including image/textures loading/g | [textures_image_kernel](textures/textures_image_kernel.c) | textures_image_kernel | ⭐⭐⭐⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) | | [textures_image_channel](textures/textures_image_channel.c) | textures_image_channel | ⭐⭐☆☆ | 5.5 | 5.5 | [Bruno Cabral](https://github.com/brccabral) | | [textures_image_rotate](textures/textures_image_rotate.c) | textures_image_rotate | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) | +| [textures_screen_buffer](textures/textures_screen_buffer.c) | textures_screen_buffer | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) | | [textures_textured_curve](textures/textures_textured_curve.c) | textures_textured_curve | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) | ### category: text [15] diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 7ce5cf2dd..4e7130d7d 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -113,6 +113,7 @@ textures;textures_gif_player;★★★☆;4.2;4.2;2021;2025;"Ramon Santamaria";@ textures;textures_image_kernel;★★★★;1.3;1.3;2015;2025;"Karim Salem";@kimo-s textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@brccabral textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 +textures;textures_screen_buffer;★★☆☆;5.5;5.5;2014;2025;"Agnis Aldins";@nezvers textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501 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 diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c new file mode 100644 index 000000000..f5e67f20c --- /dev/null +++ b/examples/textures/textures_screen_buffer.c @@ -0,0 +1,161 @@ +/******************************************************************************************* +* +* raylib [textures] example - screen buffer / update Image as screen buffer and display with texture +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.5, last time updated with raylib 5.6 +* +* Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 Agnis Aldiņš (@nezvers) +* +********************************************************************************************/ + +#include "raylib.h" + +#define MAX_COLORS 256 +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 450 +#define SCALE_FACTOR 2 +// buffer size at least for screenImage pixel count +#define INDEX_BUFFER_SIZE ((SCREEN_WIDTH * SCREEN_HEIGHT) / SCALE_FACTOR) +#define FLAME_WIDTH (SCREEN_WIDTH / SCALE_FACTOR) + +static void GeneretePalette(Color *palette); +static void ClearIndexBuffer(unsigned char *buffer, int count); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = SCREEN_WIDTH; + const int screenHeight = SCREEN_HEIGHT; + const int pixelScale = SCALE_FACTOR; + const int imageWidth = screenWidth / pixelScale; + const int imageHeight = screenHeight / pixelScale; + InitWindow(screenWidth, screenHeight, "raylib [] example - "); + + Color palette[MAX_COLORS] = {0}; + unsigned char indexBuffer[INDEX_BUFFER_SIZE] = {0}; + unsigned char flameRootBuffer[FLAME_WIDTH] = {0}; + + Image screenImage = GenImageColor(imageWidth, imageHeight, BLACK); + Texture screenTexture = LoadTextureFromImage(screenImage); + GeneretePalette(palette); + ClearIndexBuffer(indexBuffer, INDEX_BUFFER_SIZE); + ClearIndexBuffer(flameRootBuffer, FLAME_WIDTH); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Grow flameRoot + for (int x = 2; x < FLAME_WIDTH; ++x) + { + unsigned short flame = flameRootBuffer[x]; + if (flame == 255) continue; + flame += GetRandomValue(0, 2); + if (flame > 255) flame = 255; + flameRootBuffer[x] = flame; + } + + // transfer flameRoot to indexBuffer + for (int x = 0; x < FLAME_WIDTH; ++x) + { + int i = x + (imageHeight - 1) * imageWidth; + indexBuffer[i] = flameRootBuffer[x]; + } + + // 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; + } + + // Skip top row, it is already cleared + for (int y = 1; y < imageHeight; ++y) + { + for (int x = 0; x < imageWidth; ++x) + { + unsigned 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 i_above = i - imageWidth + moveX; + int decay = GetRandomValue(0, 3); + colorIndex -= (decay < colorIndex) ? decay : colorIndex; + indexBuffer[i_above] = colorIndex; + } + } + + // Update screenImage with palette colors + for (int y = 1; y < imageHeight; ++y) + { + for (int x = 0; x < imageWidth; ++x) + { + unsigned i = x + y * imageWidth; + unsigned char colorIndex = indexBuffer[i]; + Color col = palette[colorIndex]; + ImageDrawPixel(&screenImage, x, y, col); + } + } + + UpdateTexture(screenTexture, screenImage.data); + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + const Vector2 origin = (Vector2){0, 0}; + const float rotation = 0.f; + DrawTextureEx(screenTexture, origin, rotation, pixelScale, WHITE); + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + + UnloadTexture(screenTexture); + UnloadImage(screenImage); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +static void GeneretePalette(Color *palette) +{ + for (int i = 0; i < MAX_COLORS; ++i) + { + float t = (float)i/(float)(MAX_COLORS - 1); + float hue = t * t; + float saturation = t; + float value = t; + palette[i] = ColorFromHSV(250.f + 150.f * hue, saturation, value); + } +} + +static void ClearIndexBuffer(unsigned char *buffer, int count) +{ + // Use memset to set to ZERO, but for demonstration a plain for loop is used + for (int i = 0; i < count; ++i) + { + buffer[i] = 0; + } +} \ No newline at end of file diff --git a/examples/textures/textures_screen_buffer.png b/examples/textures/textures_screen_buffer.png new file mode 100644 index 0000000000000000000000000000000000000000..b93bba9896a0075208067de806b479e01f1b43d2 GIT binary patch literal 31532 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ#K6EXgVAa}0|NtNage(c!@6@aFBupZ zSkfJR9T^xl_H+M9WMyDr;4JWnEM{O3Qw3p0&mff#3=CBVJzX3_D&pSmE&pSGH}aaM zqNoRl=L*dwlj1z)O;Pv%xiCY7N1;nZbJ2n(rbS8OiH?p-IZp06T6$e~-MZ*I_p0CT z{a(8IcD4SyAG`a`zpmO-e1E6k?DIAI_rLyYRexsY`7ui>oc8RqagX6KiR4jY z@Pxrm5&fEn-F+97j>SxRZuh;?Jwq_L$MD&&h=iH1lN(dd zzz8LF&p6pV4W3urB4&8(PPX0G;Q7@cro?7`Zk=Q~S)C0%hR@C=OrQJl()4|ApoT0? zZk(D3we}su{C_X!7q*BQKAZS3RloYEVAK(bL9&=>THCY9pAU)edjYb=a_;#bJ>v2U zUEhiPi|MXR*?7Qcz6`fca$Yy$TW}OsDT;uG?zyf?r)K`OMm@#|_}e)-{$luzzt^w4V=ZRZ z+0e67J|ZDj*#9jT$cne#6Q0}8c;kB2{&eiFpKtsfr9QtXTrPH^=jBnR*Z-0lQ+swA ziA6kfd$aFk&VlrOPnNo82!1|M{7?0u*1F9(OZ4AYt<0Y1|9gwSy;HYO@mq1(cjnV( zt0y&<@`**XZ9FjRIMZt%oel4}`x_2iifuOh-nsilMEs9K;_Qpm^JOz)F~V&Fch^3s`pNzx>X1=k`C%m&NlwuXN84G;WOdwV1zK z+rK!Yv>oq=| z4eQ!iui1!2l#6q(`Q6KUP5Jn$)@{@GJTdOSpd?&#F1`MqVAPSE#pR48^4nvhdVeHK zKHpH?Sw>qWgow9wtM{)(`8PA_x}>CMUzfO8>-{#p zt229x|It#tyvBP;yPpT&kK36Xk+9b5xs1++ciLhR6E|+G>=n#yH0@&zJGPSP_1XNY z=YmmBnC`r4TYG3GvxE&-H*5Gjk=N`$&&EE~`}SD$SgZIZdD(Z@vbFWAZ)*2lPzpcB zQM5W^-$e z{N2@m&)>B9|5M+>sXJz#`@<$N8>>q{L)X{56^wdvDk5R+0VeOGOsAP%uS;zF`aG$z z)K_Oi-kEvQZJYT{od19R!ta9bcZ>S0XGCte_i@FuK9l(WyUgVmx_Vvnvk%{$u)DkF z-}Ak%ICPahyzp6F{@rz&apYIQ$*XHw)E_&YULY3nou7M6oX!Rb?lr3uL50K8gvPD1 zcQf~WF}8orp(0y9IwAIjFY={b!3O7DEFGJ5eZKt5@NZz*Hr3kc&8*5@hq}Z64F+Fv6}O^^_th5)rOxRUaqZs&lQ(+{L|iZ zvC|8m@7YwAzwtnl&V~}54I*Il43u&Y%sR;QTIJlH%GCv{&;R{dSl0?Ih0F^6wKBe# zYmm0g_SsSWx|4!YDVp2oGQDqiU|Id^msQQX=QaNXqn<3gvwvId&(rq5Idp?I<-gIs z6E@GzDI$T9TZfffXG2!fh6B6ozWcL8B)mP$bh<|9+#ij9xxH_=UN9SNdX@O(Ufd3C zea`d7n*}yJ-n=wBo@vJZ9hc&7NFc2xfjhnx@K!p?!1{#AN<_^ zT*^D~ZF|wW{TFt=3i`ta$t{hc$&IC{Ives@S;dkYmlm|MhMk@IKeFn6@`l%Pi);>; zu6yL0U-26hOuOwHH%4ov?)fw|zM@5Jr;69DKz$vA=KZ&aU43qj<4;Vqvi@yT{7B^mKXsyG_&MjOYGbJoV?vPd?Xl#ont*&;IV2X83#AgkM3q zayF0V#?HB8e~qg<^i0od+3Cl#e=aiL_n1R>6XV~bJ6>vU_J}0r8_3t$Os_&rCORu}*nEvnTotf-@2YaT(oc<&9!P0xX z@$|&KXM84qY!cIv>M$7}m#7rJ)b6<7I{^7F;U*P=^zf8sjYSLs-PWZ(72wzKq? z=^SP{&9qt^E7 z(NoFWK6AUR-tkuc(3fvlB6h!>JXO;A&b8$Cbp@b=pm(aT^4!L^ce@+7_KI_E|8zcl z-wes$0iRd(C&lu~PYBfMZcFKs+sH zr$+Od)t=Nh`gXzObW^chXy2Z%-S>)H#CA%&ulmj2-|+Ts*v2fYJ-3v8*xYn4&rUd> zZYO1bc$KSati%1Rs3=xDkx9Bay$kDu(!aBFr@ff!vUlEdNV%RO{igao`)a!zCCSg! z58VyUY-7E4b;E&OOkxpMViCsReArvK>VQ=BmmPJblFsW~%@*ryZ^DD^YEuRPw~e?e*Pmw&ov?B;!*<8SNKeMd0vLzB4NLRYbkUe~UF zXuTt`eO6w&T<`qEtBYSxyyx8)w{u(n)}&wa>Q`N1@;=CvEe9?&?{aak5wjHJ*5O`b zeX?ivyu|w{_TMxfX+5*g`gLymzW*G$MV=K6Z)fC`#Qj}$U3Q_X)y}@ds{-Zh_g{7L zd|&iU`u>M)%3DsbY?o60_4LlqH$P_Zy{N57h@0|4esxIJ-)H7~UvubQ>eTc6zP0|C z-AD8Df0)&8E*E~LFXVTWDO*=8B0Z^*RcFJwgCIA(2Gx!d+haK{w>R4TDM_<4u{yl3 zraFIbpY1&R^S8uyT;)wqy>Z{`(%RZP|H9VKGuV6R*VpycpFxG{oXsK}=jMOPF0+x? z(5%fdJybt>j_3QQ*ZA_PtDjCzXuPVVzDYlxdyO%;*`mYBy~Yq+NK}ah`n?oNHxD=X z7y*TbybinPjawibdnzhD2v zwSCu(9ipe4{@Z-!E}j@2ThaXMlE=<9dnLspvNs-xYGu7eX*zOWty!!gNgR5M>Y3qn< z&C!ghdKm7OwqvSlv%9;&TG3_Yufv@FRxXo0vxR^Eugwu%kqL%k5nRSEqZ7U+HI}N0 zMeN>qKSv3XvUPW}pO2c{d*%=4yV&%c#>M*#qc=b9pZwV6-tQU3`m5tk$j`pD z{zFC4U(QF`-ePlW#o5X~PD*}zTEOa~@WIt-Et2+Thi}YZd-i|p>DcKzw^zApK3>AE zrL*Ck9=OF3nQ%6tacMFr{^SB1w=TYQ%ILo6GRd^7Xa8{AKXd1-W&h#%H_HR-)+$A> zd;9cle&v0^s1)P(6|a-sGbXye*>SM$nR;Kj&7aeAo^<#>{QLgrO!th5ymKtYls+px z%i0`t?CKFO{jbfoyWPL61lNyqjennG>fU&uD4N9~=%^SgPdXQ=wxioSVeb{ax;F8BA6(rtCRV%0eA;bv zGk#Ob8SgDT-#+Y)4~{NTwT^)CgZQl!D<#04d$@ZD$sz1v>@f z^iTYEZhP$mj@;`4Ub6Y8`=0Ks{{;+ZDrV|P9+ z{2MJT81ecSeVb==Qe%3Dq- zHLwoJ39>Ye?6Zr_1?<(^yT!rIUly!iWc85bhK8R^<6jT?c+H|^ID^0 z1w?%qk)L1BAo()8M^twi8LsW|9^Xu=neHXE3 z{N466_rF%kyt|h+$8Fg)XW^7D)4px%Ud8qNe%*C>wYlk6S6tUmK4y1jN7vm=Z+>}K zB&*sKH_7aFG&uJA{$Ex1jEU`cUJ0)`bF2H(R{aBO|1Nm_^YPQ#_f@|*bc@u)A|$~9 z{~6r&$zIa}E*`e_&*s!I*neUZ^WEC!TK>zLY!{<%%?f3!y`Gwvl4~8`YrI@?t}J(A zc=8$cd7ryF?G)F}UE(-J*?NWetj8<%uT6hEU9_y3|6R=6^{dx?mQh92Nyz3@!wx%sel4r>p8m@5dv_@ntPyH_w=gAKkS7_uoh5c7-isH;>&4-@U%) zU0=Ew*VjyoMSnJ4UAw}5=8pG*celp;ESBis|6SQVW1`}vn!m7*K zwyos+)9I|!npm$z>1;64*)XG6O`3bn?WD$|bCN$#jJ|ovRwN>Oc2Qi7M$FrVhe97r zu38;;V4c0$#nXR|Yl=K9;%^!v49>DT>)jJ+30CVwkFmvn*ei@W~0nS75I zUw*#FEkOU<%RBo|{yx)x@ZPK9_2qKlZXl>bDF|-bv+8UxlFMxT3Mu`ItlrmN4+hoe zvchp|zRpZ~QRFtE;9T>o@CO^q?JbB^;L9nIhO zeLe|lqGWAMmj4~6^Z!D1{W-xX7lrJ@uQw;J3U1*pzU^Q8Zl2of)7$ROsoYp{PAMnF zonLGI!g)V6Jk7--4lu2DeP;n`E$J#HG#-rrmC3s+RamAS3hw{=M|q3K$-eM?_Fs;I z+WbX^Q{LIkH(q+Ur$KJA?C)te$_(y{%U7H~Z{^fIB_`eQ%b)$H(vD3#koD+Lz>@F< zXEr?6FEpxpy)-(UE(yn-jeb}B`YUhi z)SaXJy8EZ=USoY8rS!U@N0DEowzGzH`+#eN&}2~l0uBE(ik|#+i0Sp@4ey_&Kk>Hv z5DG4{-lx4hbM}K_mHLMMnitvq7nEjq8f9Efxlnz({%z7(t?TOrjtVT+zqUSgAL}~f ziSAkJE1n&Fa^uV9Z$Y`wCY#Gw{(0SZL23DhtcNS7o%r1U`F(|=!+xKr-(1)G1P%Xd z997+LAgUYG=P>POz4j9v8-k!T@j7yi(ZQa6yN_qxGbSol#jm?}+*CeleP?s}efMuw z7oR?e@(lU>Bssng)abLGbNx^6-?#|1b3H4I|B0-gzV+?O{VMYEem4~VuD7|m_LuUk zpY9xG`;T3$_FQ@4b##^fv+o<`W>;`qvTmL%Y!rGOl1ML zuZqe|li2*Hc#ZfG?xV7ECVRWYp9_w#zE{3s+dgw>CuFs&AGj5jZJsKRtrK8Klsyr;h@j!wX!yQ)@<;)G*@}YO#c1vpUW+DH8Z$ov`e`1(MEl1r|vsb zW?tu87u;?5iu>a4v(xK7fJTAxPQ5#7dO-eJ#P7`JT6wP-^&x3FmE}G)uisR>QG6`( zI;w&78V{_=6V`2$6p@fvEyukkPR_D1^!|^l^1Jrbf6<#iH`7X?>!M*q#oOk)bI#p} zluYjbWB>QxdJ9lL+^1=MY3r_lb2i6rbvMe!uW6ypsJ9Fl?`#-nw%Pe%2TNEEM z=Vaf0w|f(pz3YDV_w$XjtsD7U=Ts^?&zG%x_c*@3Ma*(?RYz39){X|&u(LBlq^v=0 z`@`V+t1O{WbmIZ5&;;9m_xfcPx^64n_uxgT`SXHS_m`zvw`a_EiHEdq^$zcIoot+2 z^sn{v3CnjyS2wLUdOF{d@r}al8R5FO=KY^^@ch3E*JT#EdZn=>rL^Znoql&*F|A|% zq`sb;Pb`16T-4WBJ-4y}RKzFgZ1@K1CSFw%2A4@|iX(J3l$2byZ?Am5qbxC1G+X>o zS@G7T(`L5jEPZ;uusD1}K z>s^=juh}7Ty5?v5{*N5GMd_92t?g=B#3Y?2mamR`a;t;&nq^F4(bb)|OmZ5xc7ePn+>g?F`wUeW|jr{QZ>q zUG@8__MmTDAKG2yyteJbzUdpQ^mVFd#-G|hIU?aM7p$g};9euCvq5LW0bB8i4$ zWwU|GvusgtbH6JhVe5(B9V-sJO1&ClyP2iIbCIi9;lH=P?nSScuYDBVcR@*gk^KP+ z``p+4im$t6uRjmFJT)osxz5$I^&SR~vrgZ+DS!RTq0?KRf4Nw?f|VuU$?3kzl%B1& zD{MBc-ID0`UisnP;@36V2_i_SP@|F{9RqAa&Qx(eAd_Lp7$ne-S<1+tg)-8Vd{o3BslD}Nb+o!TyHYT65+-F6$ zxcj;dS4@wcxiP2m$3vfQwH0M=9_lsM^Zo2Ia*`D>t(!J-^ z9LsA}wGXs@2i{QhufDlg;>vD|Qtd~N9@t&8TXV^~*81_R&7U{#=v%YX&r4ssXuc;VxT8W%sY0lQVw*c5(E^vcll>`$4DAFirS(aLU~?Th9M!{_|VzrrrG8r>2}(b^g`4 z`g_G`OAJ;&o4&s8)9tq~ z;fde2KG6!>dttG$S=lSq2ccj5T6RzGxqhwc*`&08j;*2Q?pb9q+unYN+8ux8H%kP# zzY7`Y+a)Cy(Zd?n2I{apVq;qUEUY_5GX39L-}PT?>ZNwy@_kl&#rwd`q8m1+f?jGp z+!}qrwX9!l-NhS=K3mEwoLHf*{&caZux!!+m&0N_j`*-bU5sMJy){&Jn%Wf9{HTW)V zJaDU>RV*1)yG5N5wTdeb+Ut^D`!9K|Wc=?d-i- zlkeBHh*{3PcU#zMFTdy-p^snRw!IO0H1QbI>#zvWD1hij&|qa(M8ewxOs~%^;9nbE z`1tsRlt;%;J(CxSt$ti`H9_L>ww>2C-qt+3-_~Qx_kUh_%?}P;rOjoJBEKHcpD}Zu z@xEs(<11UlW;%SFbN|Da^_EWEb3ER^wzf*1wo-WS-+jkJjs+~adfoo(>i!E#-$kAp z#VrpviuFue@UB`!Mk6`AcwicLnD|v53zR33m;znZ4e9|KCF8EhnC?w7*S2WzP@y^S>7UtTp9mldRJoxBtz3q1+~4+f&jbzB24Pw9nh?sbh!nTNS;I z^LtVz^zN3O|1CM7~$wM;# zh9_5)x=-Y-u7i{;FQ3ejUSjoo+Lko7h?<7-w~IRzq7TUKp1W@GeiMWLRgP!(wRfD4 zl(~O=yUpLd?imx8eqeQY5-tDdm-3bqX3tm;+SxCQIp=zF3giE6?}ZBgeeB7v{!r_l zF)`TUzf*?jO=aHns@d^>A8ZE=DObguU%Y3^20`$UT2#x11GAp{OyAB7Dy4K1z++On zMbTw<$}T@WWN!Z#)Z8~u%Gs%SYL?`tg9Uc?KR(zlv(Poq>zli$u}22-Su9v z_oX)Xtmg*GiI1}xcQ38){gm-%)zM|OlUAgyJ#e?SamvEq_jc{`-~WHH`+;vg9g$xf zdi7qX+p)^boPKfdnLG1t^s!C@WsIfCjiBPuP-jCLD8ob@2)F%tdLC!)b){?fT;|TN zo8s<%J!pT}TK`vHd(Up&9y+yb-uv##bMw{0w|?#mf3!LJUG~j~sxu^acR6M0>X?g8 z+%nDZ_U!m0ET@isyTyIFC%@*`ZqQI{%=0EjhZjAS&9eNT?|AjOKWn|%I*n<5VEF0S z<)D!pJDm*@ph4CSkfT8JBAmyj*_R}g=@uzpyC?P3pLx#VpFu&1bzCvpH;=!V`|4c% zAG1l34{q7#Ti!o+z3!e_^8HI}++lx$G2J_VaFwUg*R8 zwP8+tNYvH{17+LlrJaXnPTTP9V(f;nQ|=<3R{623cdR{Zn?BJyF>Pf@+NaykZ)b|bzf!;AGhr*1X4{xO!9d(CI?tO2;I#SNYU0`f)|q#$A#-InEqLa0ar66wXKwS|o!MTQZkKi8^!l0)v->Y7UDnvP>s4y$+|Wa- z>rDQg>9lvAALIDU{(0-sRosWP7u3H?Jj3=a((nDHhjwXp-g1$uFSaK%E(Hzm&IXSQ zu00Aamk%;!&#PA5Q1`R>enE@a&c|2^%}o6j)ce>HVM@N{ck=oDeqMo`}qR0x4aw&ge*mu^UAd^(5IN6}7a zCU3*;(`TBuOf)<>>Edplvl{)S&Bo&XQ^jQu+?vMXZ};sfXaF?kxb57XHc}UDZ}gq4 zdwcZKKJVZKF*a+a{`CgH(#ytYw!hl5b^WfMooj2;zU<13?R&56 z_a|FFzFgDm^Jpu04r(hGc!VJfTnqCUy|4RV z4eGfI$e*73o^_tx^P7q;X)i>(jsJA9?|;dmyJ^afnmykx%SnE&KXdhT-b~YPpKkuF z7c;rfSN@N4RUEj4Hv*F)Ivc_g8%_H`JuR=BhG+J@KA3Os)GhFNzU7L1&H4HYGYo(3 zD0?LTSmrx>*v=)g{XE|{C0o6zy{7Nz>|OTegbrNH$zO{nyja`Sl;9`!6U- z2iz+Do|?dztjmo@(yTkijP0Ge!BzCd5+-1%G9Hwr&)W942G3ZAsN8j)}| zxpCOL* z_?B)se@?Vydb#PVmw)D*mfQ1X-RbY#J0BnTZuk0?~CmA;L*$6vtQ=eb!n`dxx6xV+5J^+3E!JHp1Lo;HfqzwpSk>X z-vy(dl;mywVN@(=bU4?RO<(3XKi8RA*DiR*dNTLucTZ3yWTvwrZO2p@ z@N5HUm|P7!lT|D9?0-|a{KvLeKi5r*)UMr7aZyQJ!TA2&+QSA2`zF8a~xb5PE)Tj&2zDDADAxNP&Oa>HaN;nN+U zwnATA1M9SNx6W+_%}z>+MHqj%wU#xkI|e)xtG%hL@7=TO_CF3PZ#mKV#cFru_bt^1 zM~;8EUbOo5S1#*Q+jiT|{BiK`tkt$@`@$;jzWO@R;_BNO21Zp+uiSVZQN8?g<-*Ie zAJ2?=sQ7DZ{e+@_>MAqh9vW@_u=YM*gzCkx*hPOHG~cgo5xWU#@XxP&W1X>b0RUFMk#KY2EewD{Djj@>D4N|McmK->9dj8%ITekFXeOt`8cl*lMsXK~! zzRbDDk{tZ|57UIAn+E!V*FNo*`*TAuO66gg-WzlK9}ktccsN8#MVRg?_t|*n>YfXI z-h8euT9?amdw*AD&F5IRa(cY+CTYgK-i@mR^ya-jKKa}gIoUO`yTl^G!Ce9G<4n*g zRYRQ(2V7aF`PuTipR3$3<)!XJzJ31>_RB4FZM&gp`sk2*?wY+13ZEG-Z#3M#scYl4 z+Z$Qd`&jP2`SItzH;g}{dq4h4K5Db`Rloe2q_nK}vYU5jFSqY9czo~~>m#4puU&Rt zuKu_tChbenvib3^jb9(lc72k&D?=lNrS&rR`tn}C{b}(DkWQL@{9tkV``{lda zdNv-<|L*&Tt2FwhckfN+ou8AsU)J)bPEEPPuBTr2{<3{#%eL%}t#5gbO=A+hR@YZF zuX6t7*FV>Pu4vY?D%a>WEVKDHf79Yy;Ca%m9_nHdxgJiK%hr2w_ns97`R_jWY@M`8!_qA+D7!j1v0YnUxvTlEd~eDZ&m^~V z*O*?Mdf`{le&>9{f=t1gq3iW~Dz}AB-ndC*#rE@mN>X*gmoPrn;x&`oI0Y2e!A~{rFRuU#DQ|?|JFVR93f4Id}C< z?%MLCu#-n*ztjaJw=*#9{kGvTlTMt}OZ~ZL_RqU?x>x^)?uG+@SU@c`Z}6(a?wOjM ztkXbqRbj`J)i-3FtJIi1GxFc-xjmJeZrXm-P%4`5llbTZL%QCPFHQGueh*lC$a21t zO!9GV$pv!a+uu%{Rjl?V?&Q>yyJu?de787sj=kwOqs=;Bll}kyQ{K|Sv;E}0qiTQo z--O39Xw=H~N2a#d9}EV0il=bv=}98sD*SB2J@AUIu84%St}{#WyFs0X9mY)DFZ7eo zFW!ChXWk9R^(SU8oOkchlIp+HFG>F0_Gi`6n;lBsTgS&F$vCr*aGaKfG$Q z`riuo^s61`%bt+E^p=n)lUY?v>Al^|zF5d2R%5-5mut+e5)~`k-ZE zTz4E2Ub@}4HvGQG#$o!$_IaRUGsXC;@26iApXZ!f`7-v^tFx{X1NN>rJrnFb;a1|? z39GgW@BFm*o#|&Lt8Yj9T%Sw+7l>4ynkH6Tc6#fHzUiNjuQ>kRCVbwf^#ze z&Fq`r+=-IPI}TcU1X^qfS`s9wv*8#>omhnRjkiyaJ#(Khw>r7;=$jeSvZhFve4Wqu zenRap-4`=i&;Hu@{pbF|yS(;AySu7(-AbQte0j;aeYY>}UcS0gq;cK$^Q*X5%@qG} z{olX?@4KMXZE<|n!I}CWU#t;gvH$qRUv{A@%am#IyE!f%KN0`s%5hLHWR1|8 z)nd8jF^6)$F9OAc_d%xB;&&~-C4q*#K&!DNmOj(a z&8%TZn7SR~z^$#9R~|>bv<6S`itaqjv^wqhqT8!XHft7Ky>jA={h!kt8dlh|tlE4& z)Uf`;Nzn4IWs=f2xRNJd{`qFZ)%_n991-X36Hed&za@|^!Xpzz7owa&Q; zj=-&T|K`M<1`kazm8bUoU|A!(jw`vh)KB=k*NR^g%Xp58dER(_t(@oFtb2A+#p|<| zN9=Y&WiwKYB8)S2F*mwQ%kcP^B|#;r4!T7ePrZB4H{&cmb!#yUqiv z{BL|*RS=W$V z^X$KuynlY!dgZL-{1$s>eC*X!Lp9}NC;k+_cfOxcXLg@A@4E(5c>Ix+XYq-VJz%RNOf4fpy(iYZ zsrumg>q{FCoZ6wzJxk+0|*&_CM;JZ{^gjGUt7u^4`Zu&&-a0xB2l8RFHqRd$pu}A~>SX zm9vA!l|hr6$>4HP6jUC!E5CF7x#nS>xhj=ZrsYut&`Ab%HN*>UWL9jBH^vVxpU$|5x<&eO5|)b zGLCVyah>8QcX9d2t&{(jzL>kDT&MfXv_!WpuGf~C8Cw|%UfXT5r)&S4lk@GIx>?dx zlFc$xUHZ3&DZGn&GkfF49HTI|v+@5Ag61J6O70ff`D~AYzTLkIljW^J3oo`FSatN& zu4P`=2XG2z+TRUXPUEtJ;jR%5STzgrk9oj1tk*whw zbM@w~&u{lK&fuI|EcT;Hoz0*ujLoIEdk#lW>6r`1SG2l@2_0SZZ2Cn}?)ilgtA8x+ z|9?apiqY__jz5fgmjEC1!!gjt5%@}K7zpZ59evcDy~ChEzuGd{h$V&1*o zy8jP20!xH!kIk6yHZ{lR<&}LU?(cT%x3dMx9G@|}L*p|4i_$*O6p?~2#(31Ypo?gwl)fyYh%x4-^GWX-n+D^$zA3%zq+2Oe6*(tG1 zOm5b-y+`bl`p;Bf>8Y~WB)hKGCzb8#7Bi%3C}R&A7a?iTUh5=+x;u!88wA;C+!F#=!-~-8Ra_@J)Jp1=g**&{`W$6N!w}UnaM5Sno zMM!Qvy&1f)Sot+8c#Q0up~b#Ut}CKDXP?RZcUB(M%{(Dse0ZzbotaZMpR`Dh-@j(o zw~}K;Z~iWDICkT?M@3fT)-#6l&z)Hmw|Byl8_zA*{hSk%m8CvAmTB#y{67cY+c|aH zEV*8ta;9QKT$27A|ReX_Cj!O!lEzZR8G&F|6JwoCu}yRyxo`IuXctYS0# zA)TOS8xKTfpA?IjSiAH5_UPoR7tTr;bF=;}Jym;mL$goR+1(AHwT1sgEaE?HoUR^L zD9hb)o&eZas5l#Xg3BY2wet?>D`&Ndz-5?U*-Qg@ZQR)+h=q2 zxzH8zGaK6Dx7r*RUu`_+{b6yNKY5L%raBvxKC5mA4cCB&g|(9!O%E$;ZTPqCc-;fg zc;CI30g*>$&QF^8Yg@Yhsk3K(e)_C(*V^T)^t|MEr9CrUTcUmKzdj0Vvtx8W9=`jK z$F)^^UoyB}JFgRy)}#BT$^P39P#Z?*+ONq!#RH6<{WoKO@$!zB*4ZyVv>xqYIKT7o zq4O$n56=Gn`B{H+vToKC@5T2_tT!CUnwSahCw93=UeWFWP2VetMR19MmSf)z)S6Jb zM9Hh{g0`=caqOm3vDaQKv$sEUpeFy{R{39`Nst!9LSr`n1E05cFG_b)(0c6Wm|2|W zv&it~YO^zYP6xAy75@tf+`eR=!qR?@zl~h7u3cyK-O|N*o*RGu*e4lQ`BLhyQp`?^ z$kLOB|1aI<`8=;4GN=j}+Jp?PevU|BZH|@lVzi|Hglu~ zoxdP%J;lD8_3I*rf9E#4iY=V+?9V1YUp0;LC%dzluBkJ)Z8!fX^E4ukt4rbZl1ekz zw;O^2rkDA=(@2?~@<-|7jOo#;mk;jA2$=D4=9xb3qGxlSE}wbrgx&GEhGzedx!(A( z@^)y-q&)e(VO!2mk4mUzN^5Jk`x_0~$pV>$GX>SxVjB)5efxRIvBK$A`C|Wa|GoY1 z&P}j2sy}z3_l(Yjm(5xCi_YKw^-tc$sawZ&`iAV8@`4xtuAMYBIcQV(GKJ}~r&Uie zUzr(te#=8X{pJ2kllxZ}|30o6zq6yOXYY!_z7ySF^vbWT*~F+iccWx(yZ+qz(4_B+ znH*-ar$0LtoM^uH)EiJ*GImRD+}iw85VFxJxiJ+qSRH0=ygl(NyKeQ|BHwK)hHi5X zIMf!`y-9ncwS)Crr_eIFC%gW{y1sXi6&AMI`!q89FxO3^X?)9$ZCv@ZKQGQeb~1F@B{ueKGcC&3ziQohk?YvGP`zmm z-*%j^iB1aw)iENS>SNY0r5oV9x%Z-_-4XD7zo{ zHgnzN&!H<)kLQ)$e-gs-&c9@~Kj_Ztm2Ux$`StEq$_4JoS}o>0hTj z(Y@j=Uo~z#RNa)RHkmc~$fWuA#U*F(ou4W4eEPAHR~tWk-}BuZ)YmdPeW%cKO-1R` zNh|XjdHyE7xfGFLXdSb>57aCSI|3R>8kI2j)UD_XU(cp2&@uV4%TgyX zVRu>O>KhNO9G^LqRz1Dm6El0K>00mJH&dBfw+j0oyZ`UTdmE?jDH`HhT))aA&pPAW4JFsJb_bVK-2F9mZcmg$!@Vihe>?NSBTwz#>%}6z`m=I* z=*h=#*&-hAxpQ*H&YGYAy|lDENuEvBNgEC@Rar+T819Z;2pLil125BfEhrixxskc5 z@$=f{-zr}nT=pc+{8x{ocI-N1v)1?XelWT$tYfYbHP&4-C2Xc&)lc^OfA4~t5k}%S zm5h>=L-v2%mnD+Yea^-yU2IwQt5goRiQHXpzgEfB8qNwVni*-g+SPdRmfKp-(#_MZ zvi2v5I{fFzJvL)~$BV~{*3JFYaKWZjvdsHHx?z5kSj6gOVhN3+GcyyHZh?*7_OMRt zOAqXQ5ey{ronw#5pG1}UrMND(%PXX-)jVr}6$#sE`-`Bm* zw`AJ(|J?V#-;@(}FOw^pa94K|$2^9T_IZYC77lNBlt=ut|1dAUx$Jy}vQD1O)arQv6;0k$o(yYVNnrH`Nx~!&6=``K7yEGW>sH zcimON4STnl8yi}=**^WQXLWts#>a*X24-K+bwvGD<^S6x`DI(>UI}xz^+(ett(ZQ! z<n~*WC&Ezw(HbH72k-08gI1(WxpL0K@aaA2L&-%cX)9h|Ih|$Q62jKsw5# zZ_hi))7LK^b+^?&6K!g&>{I?lvm<$VTDyJ97w(=H+oyW34-L{$Exxe&LhmIe??Ush zU*shxYl=nO=zCM3VSL%gtWI}B)DuOq2;EH`KTQmGrR&5W2k&u}+-lgk@!9I-D~vBL zpLt@&-Xw>i}cc%)=%ZjzZ&l4b6vQNF;$Us+xDyv-@onN z6d*nGe?fLz5u9TV{E31}psGF_W0ZXH9*0X<- z<-T&;ntq*cy;kb0RWkRiy&srA8Ltgr{NwZ8%|XtEyFrVt7F&o+DBTPiwwvaZzdt&m z(U9N3`F#a=Z`r902dp~pN%#MG@I*_b@}vKr$DkE>vja~pzHfE!VBa0l=h2I|L?7e3 z$gIFFx;(!4-xcY`*+1Ox|J3fgP$n2Dea`3P-YdbbQ=Ub}R!M&L{{Q4QXsPF>Mh)TP zdhw!3x0`bQ+t}2eTO4E2dr@1gaHHVfn>`w5suFe17C#A0x!3JB#e1cc>%4obj_Pc% zWAv)j*`VaLI~6=%nHrIBbQ|lw6yiYR~H@s>!LEo7-5IDzO~DGtH@Xbv%2}N>`z4T*~hzhQ2jcUg;Ps zTFNC&!sj z4#;Lb)$?C+_T5b~<#!Bzu|y=KrpOwbmFR-@ZO#G@1%f)i%+n7tai94y-&$dV$n$ew z%g-IW-sYT(173_3vYO&1=D^CBjFuufCXW zQgd>8tl9S}xxY($4S&C34XV4(dL~Nxw(T#g5a0a3s{ZYum5;8+qAr0_=4!R#kIC~A z%QG86Jz>z6iy3jDm(Sjs-7@iv%+%g)+pO0A>gRY> zcTqM#x8%#c>$&^Fr=2~qW7f>VDDEV;iIaYr7^rPE-1o)E_}6hB<4qe^M!bwlx7{CL zeeIv1UZ>ruv*=KDaQ)6 zQ-n9OhIMnKyjvz_o4xY$CQuvv%ng?Qk4vY|+;|}A*e&}c&?5cN!^Y3}wsEY{2zbV> z60qd_4Tcw~&yE$T%>MH%-?2H$?5kewtEH>#OAngw6-`qsT9(&4>qhV?fvzJ)YgXOW zs(NkuKdI4ay>o~S+vRNO)h(y@r3!AySGxFjtzN@3`C}L4bKa-wq&{uz-Pj%U<;@Ld zMajL3+b-(cS5^OTW!~Iix!F8b`6cOk$#2?z?*HNnS_t=2MY`qJhu_cdeVPgyaa+IT)UEjPP5;kC z?|;Uj8x+)?@YG0o^<2I6U#q?{SuV9cBCGl`)`02j($f+b&y{*!>3+1b>S*4R`SqvW z`!6Up-rMP>zB<-6t}3-xFZGy>nX#H_N!qU@p9^QMXzX6`LbOKkt}*|m+ZV(ldLC_) zsC`g)D*5nLrq!-YViBfQd#k{MlVKCDo@3HZUZ$_JLChdu$#n18yVep_k*{xk(X=VP zlbs*CN%Cz()TP(lizdAFRa{&?>BZK=k`HHW%z6~~Bs?Yb-NYG1YIBvXmxMlBHuG*B zn+A7>SEh0@fBS}~J-Xtr#ILTN@jW@x*EoL3?UXsbBKC`~WZchSz4`R`j1{vSBfCP^ z_`Tm6yz#&+$LZW+5ev*)dAQezO}zPhQ}QYB!0xQ;98PTt>To}bp|)xm8&H`+wc9bH1ODsqc`?_>OU*xljgd|!~B_IDdXDT8)y9z zg^2 z-jC=u1Wiio$a3qXoypgjw%N-vrSfXsvgz;kr8%#eS$_7;S>wsqZm9+LEJ({?IN#xY zbf(sk%(OV4hWc-7<7->Q1TQSL3Ap3it8`1k)$NE$b@9sM$?MnttA=>#fHOH;L>u{~$=HgSU*=$x= z&kJO`&9n8)-9)j-)8Drh{FxGStS{<_yL;r4SJNevT^w!F)D2|~rb*p$u{3}Edd>24 zf*L%(m13E+t}HUR6{`Q$VwJv1n%<=u8&8Y6>M{TIFbI-j84H*9JPd$HE-nu%D%8NSCSqV{cX z1=r`vWkQ!3lUFYEol?Ac-?^$&Oy0}o+`lf#041tZ0e#yKL|wJ+{izsb&5^e6#n#8y zQUxaaMx|e}cKmitgiMV|Gw?=VV?2oOk9H|_xVY*8jBid$a*1N4qS^wyI zu+v|`6ULIC{gRbu{npsLZq`=sYGbp*8o4WefAC22KE=X0W!Aa#vNLs79DE_Yx&6eA z_D$94?5%MZS9;Gh2J>&wsPnWxO#F#T5Av5w4RkvfxOf{(bJoOP0^JMh*)rqyoZEMgH{Rn^y0-d?tT z1fH;58Zi9=(`hE|Bat~X51i`BIrBq7d5UMayq0lr>!(K=v#Q&p&s=&V8ZBty=&F_` z{DjBr{@SRvju+11FN5#$&8)Z|gk0E^C-Rxcz=6Vm5d;H|wUDv|Eag=W*y*=tz{`-r8Z&A|hfQa{ou@ve1D0 zc5@f%DPGQ=b(7`u`G$lcv(wK0 z8Ku%#6?0@|>c7C?xf?U>tS&@!ho)$L@7w2*KeN0dYFYV`Kho>#zY9h!nQZ@a9_Wx5 z8y9h2$*%HK4KE}=i>_W0;r491Xj;y)eKyI9&Y#!&Sv7N_7gzGrp0Z7@X$v2h^Hg)M z5z~BG`thd2R?tW&Xn%^X(uTvAjrJ;oSLsA1-sR+Y zCEs9OzxDq;xj7H-*S^i}yP(9m+x`2DBPaDtjepMA`l@HGmTqvr$OY|6geleL@wQSx;mEeek#vHG02bc=2?gUzM>*Vw=^bniS`_Aw>n+|B2@6y})HK|Hf zeGSp;zwJtnNMN+}eYS|n`}~gZJ1<@cJEt5sv3Jw)EK8o&*|&9i71#W7x8&1_J$aU1 z-G;__>%@v9S6}msEKHZ|nsWX^>?A$DFyG|l18GytF0S=nS#3Kjt7>gH``^{yjecy8 z`wm(gd=|JH_rX}uB3?ml%&S3T@gY@7e*u)dV#8Ohw@M{&@@E=@858Ge-{xyn1MIjc=>OqgzMWTe6LgFP{=DX~WfZ z<+Z`q_Agdj4Mm=>+pSxBDC|U4fV`=s*Z%9@Hm}byEnO+`cd?3biqYQdx2jLN{k^ra zuhT5}`O^OTHc(GEekL^ZoYd=(9X+>9d$u;SPGb$zkK})~Sk3w6_gi(}rmkJ4 zCz{;2by|jTY22?Ly|t^pZ(^#x9#^IAt-5~Ad!tv^IxM3S7;W#*=3KMpXV}KuoY%Z9 zeM+W$RNKjPJ>z~#aQVYC4na$Vf@dp8L>~*y3f#R)^7Y#M;OlQTyjl~V#Jy(j9Hosa zrTPY+bwA7RfB(6^Avg9&%H-NDXM7B(YUoaV$v@089%3O1f5v33DimYS~Tgvti<^Xjkoe#lHR+0%icbH z>wRS%dnYfwbhB#q3)@ffd!B-J13So^*}L|5!j1Dhk6+}?xMz0$#HEYuD)-akS--p9 zy(ujnO2L}_Ph>We=iKwSVz^nGnr}i_D_KlsY2?- zA0>@tZ)$H=GGwiN@b`Cq)mOnNm$WmE|JCJx>;Ww-lwaXsS+_5@QHi@GtMS}|Kc^U0 zKV9axUf`tK)DuzRQ$0N=?ELggNABy_iIQHgUutR>IerZJ`p9nb&)$vKI<6##t<=BJ zpCZzKP~)C*Ronj;vFkxwG6U`1Y@NfDV}H3ky2C#E&DWV;yRSah{=9nY^OI{9ZT};9 z_x$y5YkEHFe%bXV;^CPGRjX4#jZ4-qjqRVJ6I@?u-Uls}VCp)aAo5<&wwYBdXVdlc zsD!N^4w8>=Ctm*`zwhr<_XB1xa@Y76e7(2m%mcmfIYth$uODxoWL%p4BKT{bx%o7^ zWs~p8r7x;kbK6DIqpDJ5`#tZsNk$buS6{sRd_!jP%e`-dqc8Sd3wvWGcUe1WN{mvW zp+@ojF7?DI{rziHrOP9GUx~f@DzRE;xg2X(sK&GjOM~rg44#=A1+>j<7dV#3zUGx? zkF2ff-9?X9-1)fTn23#JM8Z}Nr@K;O5f`6ECR}~-GCHBL!pDp?O=G9aBJJ%5nD)vg zPknl2vBO5Lqe7cXbT*V2lzq8U(%rSVsQbVx*-Je}dtQHe-S+s)@m)LB%r^Sj@`x}l z-?Ar3@2iqR14GtCmZfKSPOayVUEuF`=l!lPArAf8O3v~tF7|5KM&Is#7a+33HaXL{ zNurVR^MF`Qm?FYSKk%Rwru9kG`IN~o3Ct|ejs~O z&DVwh=GUKm4qD0i;_bP(hZ4&t+!K*F%6i5p%J6R$gZ9&xuKvN>h3DS-nj)NNyJ)lA z_2YA$_DEcqtH1qcPp#V*qZi7B#|~vzy}tL_w!!WuL#>O3hH;bMoTSZi@3(%t_xSbA zfR$VCoh!W=cJ@7k*~)qWiQ~#!VpX?_TvHWU9AVKN7(2sj%_|1bHkT7;z6f7lukNwb zX77v4D9~{TpTAt&d%c>0Tc`EjW8Do5eeM~%z20>mxFqY#a=4<-s1_I+8x`U3=2TJZ6X68}lH zD^-%=D_7dNU%9e3-Z-Cmt9h7>=;TUFn5H>@0Q8Fsx4W|I_LFA93g! zwb*S*yVclvnA6!rZ}Ar+d)B5I=W6(iUc0K_yWOAj<#V6%C-wWES=|q8yYzmhsB7VZ z9m!kl=Sx?sC`SqYul>YxN6qJ1L(*NzrLqp|1ww+}mG(u-I*MF&c)xYlE>-2Oqi!M( zqqj4^&|S;-{NC${N%E=x%zi!3(B0S?_5cEKm$F(taO&X=XHY(|%A}uFEO>T@pHKQe_MKmKHbki~zCHi^nB2*Zu#`s8 zm!;DqWgA(=E=Nbnp4)p}IWl4E3FjSgfP-56iNzkKG>_17n!d=ls~eN|V) z#p7#~Bpq{{mz6Imet+eNx7yydKVni%Gz(_^$`ML${Qtsb+^M5H{YIhX4;NE zFaNV!))wWhKX7R+_n9+=JloZ`FZ6Tw4Hva?HqT3Y16uXob8n9Xx6aY8SKcnZQnjxY zoN0}AlxID1S-M?x{^}kzR=?o+zB(I>rW9MJ9Ct2x&176GbNKDa+!dcavsQ_e+?!$a zCGUl(?I{%z-YXRDpvuHSDy`luD(Np@CkD!H*y zt0%J6@7kn@sJF6fciebUTHqkR-!$^wYPsgKdl)bE@4UWkmSI^~ny!cLZ_{mmBH~kC z_D}qp-23Qu_Wg+KvSRm?ICrtIY(3F&kLSwPj@pS!ng3mJk1K2un|QPQ=E^U2uU1rq zq_VB=3|n}Eb&K(+upl%(ypi)p4hi-CJe9?b@Fc=(({g?vcvEo+CGy_U`kj|GI1Y*H`;GzNSt& z$+KYJ-m-N!w1Q7F1zazmH*+J;E4iL)a%;I$rb%92e>}hCuXEbTn{{({ea|kO78uPj zedgYFqhrc@-RZmboqEOz8U+a6Du=&*loB zJ({z8=j?S>TDDlaw@9VMuX{>?ciK5Wd7F*#X)+nMbFUQizgRm_a{D}|UOQH!o2(9L zSG{(BjQIV2|5sJ_17*Hx|9gshj4l~JY7yy7R*6b$vzwNzcXP^wgG(=cUVAdDYr0cZ z%LzRx$tk+m!rPwRaKvaf4S!vx3Rv|;M%5XGScFbH8TZ+ z!_?0C2)G-CNB{QJbADSXv2A`8(~8E{o?hP%_iHbw%Pn+GDX0|C7fOgN?M{8MHQ<-Y zG{@~MYEi95ixO97^ltNZke}N1G`(PD5DOkB_bhJVf~p*t%Nm^35*b%<+*hhTz7hTIfCu3(2NYx zQypz<7n$DDW2_C)nl}I7(k@$$A2Zg3cv&}C6dkk`iMUf>I^)R{uHso$7yr**|8tG< z7LJ7$EAO$bYF~FrHSj{pWO;8}f$uJxk~hW7$XWHc>gzU%6GhKucFLEsAG}iJ#TYhg ztFv2JRPC&kFE1GnxN7~KE%_lJ6CHst76Izw61WRcBm~90={Y zvY)Be!DyyM@}_s`oANrAb{%HkI=is4=TeyD#kDWqS!;*hiC-?M{y--+@8m7TPaoD* z?~(J1y!~z4&ZIzwr-5SeCF+x=noaA*e1WB;En1p^S%Cz z(?WKLeLj-uBf0;h&a&-s3*`EFPMbztnK9Skt47!@mIL25?bNw_{>oqJXwR8PAMJQ- z>$P%`{mR=*t-e-ErJumn6#HcmbkA$5%WjWc~`DL0~@!|#lL^YO4u3R3y zV8@IckK;i{729t`CNx^;Y@V`HHTk5ZTv}=W^>vonx9^!i$-j9bbqwqsr2bNQMn5Or(6lXIAdXf zdLn~{o6N}=(HPxr$+b7%EIN73Tg4`)WIDUi;}^1KD@w!4mxO(f@(t79#=G?X=3hoH zYFoBxA9x!qKhtu`iT{80&aY$n`=duAY*Srgl`gwR`q57=KW4;PcP`f4%%ZpU(b*}t zKJMuI>uzT>ax{KGG5r!S59p1I}Kj`nJs*Ng9!y^algHt*3VmqoFRXCCYolRJ4Sd_{1b z*ym+AjjeAZ;^&1uX4rh-)T`7+(av`Yuf>;LFKQ^7_GliOgO0wOw(&sHBGoI&>dn#4 zFWuGpTH~s_ZRM)lZ^wVM?73GSd8%~2+v>jR9mhA@y~;J`UL#`hH^Z&;*u^Q?Q)VC2 zsj9M`v66k;r3HrHHCT+3yqU~OjwYsF@tfc2tS!{vsk9)^Ux3$ko5b#(HB)D-S=Kdq z)oZ!e5zS%=v-`iT-xAdJuB@@B#`ecW>%FP(WT)=^+GTrg@zlT0zFYKesNYU`Ht}D3 zKIo8{mJVCKta_!L2}-xtPIA)y8t}c!<;sGm)$Y89w>E@cNlp7wlfC{>YJg7sM)PeN ztgc4a7W-5_*eWn?V+kR&J_tH-NV&(Gm$1T$ZlJ_qJYS?cd5T%xfa8vN6@@x_sx_!0T3Aj#svnG1@#$*?Qtzx{J8L=>ThA zRd*j(T_u6FR@vuwslsU+a_y`SQ1 zd%xxE7J6j3u`KfR^|uV0?wwh2`He4c%G37nkSNX+Ii8fA9xuO_8C>W-7m@JNW%-=a z&8%V_sVnZTo1}bNyfx!$Wc4>c&YK@&oMa|n^vG&8>P{Ea%4=5xdtseO<;7 znV)tg^V>4EO`i^HYprE5;%D0w^X1EY)?G1$T!JO_>n}3wnDPJZ@A!(AZQg3d{u(D& zwe?*weahH5?O<73kxy^XGmqDb<3k|S1-yMa*Ic>-e$|!{;-tzhN0i7$=Ia_9dmQQYHtAi)`5p6D)~D)h_<_Un zO$Q!*+HgH7sdrOY*OhBWk0>v;)mWLj^~Hnwziaian6@ReUza@M)O<^4#tdcV=Tm1U zpRtvaSu7zCJYDxtaHj9GDHrp)4jvWjt4^}o$ZDXl(f*%Q=gyRrmAx}_a&E7gn#5`R zoAK*<8>@z(e`|7X{_{wyu6n&N?&8d(9*s*ZM`WfJzn*yF!<2yUt}#ZdS>>aom##ft zbZyn0cndY_P2zI0GsSz4e0%uM_2!o=4r>DMuJXx|&$<4D8B|{g0)Nh*bFN zFmGo#{BPB_nH#qnpXW^CthBjSS@`pH+&Q--ndXf)7sK6OSuw5i{-R#!?_>Ne{LW;- z*P?-XQ92ufUTty}Im`rFXd-;uEPH9hp)++3f3r)Dc>UbGDfPGV%(pMswpT?aEZp)n z;#}0!-`vMj+`k=Kto(V=#2a>E5j}C=E!H{uG=4u~RKRWUW_{Lt$!P1(a}=gcIG#LL zeER-(PjghF5)3CDNZOQk_Ke0N5$>r^OkRKa|6RW7pkS1Wqr8DbX2!dOd+SbmFZy}6mYvG$W;&phkfLD#l@ z?O=%1Es1^_vuRSw0@*K7*S}5Ms`V;pdT*|NpWQj}uYc|9-&DFEkYl~OZDRPEZlk9S z7K@Z)=FJFyc33h`_#RtTt>c#M5n2Jud*b?@b{71y@l*bPyx-CSB|v4ZW|h{Abk4dS}TvR zj2X$@Q&P?zUodG-+T4AtVu#&ieB%uZ7g!ht%+_HuxSrY;p~bzXXN}mdwMBZ7o<9)@fO;Db$ zsBHc0|F4yxbNl3&ey?1s@lPsOc~MW~l*zYspRr1xxFxoKkwXUy=s z%eQg)2KCPprCDB_uQv(@MzI|)h&AFqXt;4sq~07giR{J<=`Nk*9W8~8Mt=7qEjRA} zw$~?zam(6!{ik+x+~aZCKSefj^4z0aU-(*PH}04ptq>*kKWe(->);7D<=)FriOFGE zAtyfT;j5Q!Vc|Uw8)KKt^NMfqOx>EWDS3wqC|Ei&nYM5)JHM^F?7n=Ze#lBlA`Kc12olp4P8= z^3=4cT2UO|3SKknMdxzP2@jjMt5s5ub9vjR4O`s<&P5zw6C$|IbiU|q^{VEcGtvs{ zXBaid>{l^@(O4!9qozhHYb@2QzvMWavD^v+{t3ytM%XglFE zr(1$ui)-%FrYX@a4<2vMQr16OvPrLJf!;>VWXVm>o?S~w;=ZEV?g*a8*8MbLO-|&> zMXd?^+vOf?x;pJZW$M$F(K8-SD#+5{kFI8U+EaSQOY~vX=g5tNhjNy!tcS_P8s4bK=c9Zg%F#ot?|}raH%QTMn%1OgqIUxUyZfBh%>4?2W7+wB?zTWRpD$ z!b%<)nzHRrOHF$o6y3xsb|OnEd*V%F2P?y^5&t6Q?P}qPR>)^QXPccE@Lb~fCQ!Y~ z8Zi9~bFq~|cKXsBL({h4w0z-*-?ks00@ED@RU0i>=ZNlZ>^|r6 zxi_@y`L%a;lb)Vipc2`frpB~s^A6jIOht*BGX-zkUsJMjd~(QE=;7u9n{AR;G=7^- z<5hTSRo-^_x&D76=rsB% zS6)88p25FWnQcx{PH0;{%Z9ESUN`P5seWZ)SfqO7OW>y*`)$cTC9g1PKJfS!bwfT| z>Y+^Xe&xAhoG-o!+*bK!cUX1(X#vOH9bb3!HPrVmkbPvh!gY>pz#$#qKc{kUXFul& z>RucE{cA+uiPf$gdFOBGUp-RyFs$pywEl#aMNe`{BTseNhrH?#N$Pc&W_@brRqp*s zv!8Pad{3#FbkE&5)%U>E=UFMo-9dq(J!fZgglC?J!1=8Qm@djp)L)LQ<=kGpB5R# zMEOY`KVJ6W@#FOkpHrnz_qosN3T4n^4u1bUi18h3!=<8`${%$OY<2cly7JZO<|`S; zxqj2cFXc~UIVbxvK{~_>sq( ztBxvPl!`f*VL78}=Us=i?S|8NWF(7OE*?(NWebp7()l*xSw`%O;GE-+CH45HFR{~Z z+H^E`nV+z(*y}?Isq17r%p#XxKHwNxm~6H&xSBn>+eRh3FGEQoOmmt*X3lzvZ)S=Q(%kR{O(SM-@Y^Z~rH{@}a~!{pph*UMf0e zVYiK0UcR1nj{fb4GMh^wYnTcoXH?lw=PJ-=m@@6OOlLadI@u_ph3mvmg+1qZRkCT% zgt~5(f_EP5w;8G*)m;hqoZtUY=$Kq*!M?qA@~T&gdz2?WESaI>yG__mO>X{GZMn{C z4~pDQZ#=*hBd6zC8^)5_ecNZQT9nSUR>xB@)&jYogqJMl>3JiOr&hwY&GC)Xx-1>N zzT^L9BPhb=#uJwJ5YLhY7k&PI+)4~s7v z#iZ#m3um8FD3@uzV&U8Ny6Miwv%hEN*gMo3OFQ_!776&YX3LMQu5v=(4etE2nDpIX zPV$+#r(?F;Y){N-ugJT$zoEZ>*~`pD`?xHs?M3b5V%ldXD+51$ozwM9#8U?J6e}+?T19 z{?YJeg0uF~Vo5VoZk;#hz51qDvgS43;GP*8k?@g5UKWeEe+b>QvyBLX?-isQYh2Ct|!O;=%3DCk6fQ0Q!fW@V~kQOlm1q$ zpTNJo!S;q*>;~RPa%%s&_EgwEKlhGjxb!3Z9^0Pw+w33Y?2M){KBzb+yWq*jsT<^PNA{`^<|rTD zSs?$>Ea=d+_U!A_hn4($mn_(U6gW|wL z8M+GdPNyKt>n+>TG%V_E8Yw{~QveHK6GT4`ar&Nb|HM6jOv{MIQOc^}F7=`K67vheMuc}yo- zgS&q=%}BoDJx4t1P2^h{|Bg;3?lm513mEnnS)DR-IDMq=c-=eJHxETNu-{(6z0L8? z;Un=A#os@_BYE$<>hnztzwzvw3s<4_q^VuE*;7&-YIQe6sT}wjm9SNwDZ_cn{$(h@2!&+|Jb z7fv=j(XjIJ6U7$gjlJ)Vm^CNwxb@M)L~Qx71u8Lhev_rGmNi@|TF&G*`SfAUBb#@K z@yr*^W>3m$xGj9-(}FE~*l#zyZnC|j#&fFwz|IFhW*9k~I>EZ|ufu_^q*FXm3b&*` z`+V#Z`25ILL-+cu?ZyRS&o9++D45!{RST5%SRUK#u!j5a@#0w-tJl~j>(%JhJ+)=f zZFn1@konsQos5cU;a-@?KBz@qZkBjtAuQ zEWa__Yo3%a`=H?*Et(o;%{S$>kYQF-Ipvj-nYtaGyw@;$TCP=j;&{L4pn?vcOEu(bE?;mo2+i`ELU z>rD?gC%tv>;Vr0cijbQ!?R$cBLF|V1+bxbi1uev7`jA^qJ|%?NXgQ zPxGE&QrsT)rB9-VrP zVBH|=eKhmfl?}2Fl`ndESZZ5-E3Q^z^=mJFQuIjT9`l8;6|sLr3o0#S&vo}F7N{^y zpVRr<@~MT^*P7@jiYqi7YLoSDG#76?`*QKS8*Coz$5Zwn`+MWC=Hc0e?{3H+G~~E( zSoOHvf$9LE9Ak^N;v;778BesHKC^&5Suci7pg5(X-lpv>%hQ8q@1MWD@oA2A-;sIW zj0Mjhowq}N>$7POO_FsP-ajwi$vcs6Ia`5V)Pi~JJ543du^zEqq1i8`Htkj9gC`M& zB6GhpryOp5kUOU}x8Y4-WnNQ7${FtGk360oFM7&Ob#nI^j`TPanJ2^abH6)!wEt6V~>+7e^k72kDFutptw@n zebK%f%p26-^=m$s&|_YH{x_pn2g4)78_jzjt&jW_bF0EfCtZh`X*qL%keyt0fyx`+ z=iBDXH^mEXU{8POk)!M@!(8ofa&hj5ofd7(^3Azz-hCn!v(G=ON#2{Z@<+G~e}M9z zQ>rX`+Rrmta4&tNys`beviP4z+BT9Dh#sc(U})1Zhp>BY$tWS$QZfJNz?= ze?E6XSkC_)y&_Rh6g_y4KM1#DyB*ngkzjEby#?@ddV)tPLRD7UGT7jr}fGHnV>GNcXd6I(3bYOTkyBbCU51 z*8N5AB4>Fho)v6$UUZ{*Ng>mFb`QSe3HBMp16t7Wz=#SfzjPDS2L&hluy?C80H{rRW$bF70Ne^H*J zyj(c=*u)IsJl-b~#Rui=gsOM6c+4+8Xn2F|#PsjQTntMOnFT#gu8`I}Z^`7xsNgOm z+28;4;p2_+m4)vb&OgnS>HL+%e_-AY`(-`JJ9y^Uy=T`@Wa>Dc!2hXhf7;99%*Tcs z=WOKRn8WAb`J>{^!HFBp=iIKVCb)A zl)I!y;Cr(4ONG`Me9yaWYxE98Zv6Y$EGT1QyMn1qbNo+Ej9f?0=-ryT)0t zJx{Xldt!Uuzso4pHn;2GnHCR+|My|CQ1Jm3|Jar_=ju5SMfT`1*$L$-Do45O@Mkpp3^8>>vC+FY@^ON$%SglP({rYfvuK zn}2j=A=e)E#_tc-=;+(AefZeW?^wB^ow<&6Pw(T6?fo^+jwq*O9xE11I>nHBtS;yC z#~aVCY>?_ z_VvF^=I?uMYr(ei<41<$$@YE6>)srUym4N$K(9vS{qeGCYVz{I2O{_Mihy!zALAUp z`K`Hsx)=)dn7$p~Y+=eG)1Uk2RAv%?{^v*wA;#Yu&+ccs*Icrp{os0z8k_eIl`Ew| zl8Zxbu+8Cnki4m60yjIGd(nfK4eYn~$p5q}J|&oR%3|L4#~yEoCf3+IFiMbaJkPq3=SFjK(y#M#>R8xb zCR{lQZ-Ef|M*0?JAC6{aDNoukn6{I{CIMO^zp|Y zA|k&x_QpS+*zo;B-M!{wL5tcyTov})Zu9dy>irO9tQIKX`Nn+jzmMU+IeRwrDqH%# zVYd)^{wZ>f)baz>0u}t{PJMcm%plMILt+YhwZ((*1Gg>Ys(+kF_p@=DmS!WaxQr(t z?agsB`Tkr#-rtPp4w>~ia&g=^+<4G%Pw#=9DYp&p&#-%cd?$y6cqQY#V;>oQ7m9r= z$hz@t(t{r}?7lsyxYwLKK}w##z~pETD{@y?}_h?m&+(F>v>#h-*=?Wj{CL+ zTlEi#C#|*(^-mj$CEq;1^vUps+X2Hp^BwzYc!CbsHRQ6$oIK8~$GlDOM~uMf23rfY zW&h8-bWfOIw{7!ghHszc^q9XDXWe*qrNCxB>kkRPgNR#`XPo}zmfT}_Ok(o{^L-!x ZvuA$4dF#pV9?-qm44$rjF6*2UngDKxo6G + + + + 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 + textures_screen_buffer + 10.0 + textures_screen_buffer + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 34c696ffe..c3fbb6d2b 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -409,6 +409,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_viewport_scaling", "ex 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", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5079,6 +5081,30 @@ Global {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 + {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 @@ -5285,6 +5311,7 @@ Global {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} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From 06589d33505b86bb4b515d4ea6fc3887bfb4347b Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 00:14:08 +0100 Subject: [PATCH 095/189] Update core_2d_camera_mouse_zoom.c --- examples/core/core_2d_camera_mouse_zoom.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/core/core_2d_camera_mouse_zoom.c b/examples/core/core_2d_camera_mouse_zoom.c index 6cb6dcfa2..9006afbe1 100644 --- a/examples/core/core_2d_camera_mouse_zoom.c +++ b/examples/core/core_2d_camera_mouse_zoom.c @@ -23,7 +23,7 @@ //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ -int main () +int main(void) { // Initialization //-------------------------------------------------------------------------------------- @@ -35,9 +35,9 @@ int main () Camera2D camera = { 0 }; camera.zoom = 1.0f; - int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move + int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop @@ -93,6 +93,7 @@ int main () // under the cursor to the screen space point under the cursor at any zoom camera.target = mouseWorldPos; } + if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) { // Zoom increment @@ -110,7 +111,6 @@ int main () ClearBackground(RAYWHITE); BeginMode2D(camera); - // Draw the 3d grid, rotated 90 degrees and centered around 0,0 // just so we have something in the XY plane rlPushMatrix(); @@ -121,7 +121,6 @@ int main () // Draw a reference circle DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 50, MAROON); - EndMode2D(); // Draw mouse reference @@ -142,5 +141,6 @@ int main () //-------------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- + return 0; } From 6756e9d3d72c962ee6f70ac0832abe681ce8e6e8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 00:16:47 +0100 Subject: [PATCH 096/189] Update core_input_gestures_testbed.c --- examples/core/core_input_gestures_testbed.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/core/core_input_gestures_testbed.c b/examples/core/core_input_gestures_testbed.c index dc47136c2..f1cdfdbc5 100644 --- a/examples/core/core_input_gestures_testbed.c +++ b/examples/core/core_input_gestures_testbed.c @@ -69,7 +69,6 @@ int main(void) float angleLength = 90.0f; float currentAngleDegrees = 0.0f; Vector2 finalVector = { 0.0f, 0.0f }; - char currentAngleStr[7] = ""; Vector2 protractorPosition = { 266.0f, 315.0f }; SetTargetFPS(60); // Set our game to run at 60 frames-per-second From d26b17f320faa8e3bbf94a94adf4c46d3dd2dfee Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 00:27:33 +0100 Subject: [PATCH 097/189] Some comment tweaks --- tools/rexm/rexm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 1e7865db1..1133fbfdd 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* rexm [raylib examples manager] - A simple command-line tool to manage raylib examples +* rexm [raylib examples manager] - A simple and easy-to-use raylib examples collection manager * * Supported processes: * - create @@ -8,8 +8,9 @@ * - rename * - remove * - build -* - validate -* - update +* - test +* - validate // All examples +* - update // All examples * * Files involved in the processes: * - raylib/examples//_example_name.c @@ -86,7 +87,7 @@ typedef struct { char author[64]; // Example author char authorGitHub[64]; // Example author, GitHub user name - int status; // Example validation status info + int status; // Example validation status flags int resCount; // Example resources counter char **resPaths; // Example resources paths (MAX: 256) } rlExampleInfo; @@ -119,9 +120,9 @@ typedef enum { OP_RENAME = 3, // Rename existing example OP_REMOVE = 4, // Remove existing example OP_VALIDATE = 5, // Validate examples, using [examples_list.txt] as main source by default - OP_UPDATE = 6, // Validate and update required examples (as far as possible) - OP_BUILD = 7, // Build example for desktop and web, copy web output - OP_TEST = 8, // Test example: check output LOG WARNINGS + OP_UPDATE = 6, // Validate and update required examples (as far as possible): ALL + OP_BUILD = 7, // Build example(s) for desktop and web, copy web output - Multiple examples supported + OP_TEST = 8, // Test example(s), checking output log "WARNING" - Multiplee examples supported } rlExampleOperation; static const char *exCategories[REXM_MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio", "others" }; From 9fe3f7ca1491938a744174ab311f61261d16a72a Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 00:29:54 +0100 Subject: [PATCH 098/189] REXM: ADDED: Automated-testing system Elements tested: ``` TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" TESTING_FAIL_CLOSE = 1 << 1, // Closing (CloseWindow()) -> "INFO: Window closed successfully" TESTING_FAIL_ASSETS = 1 << 2, // Assets loading (WARNING: FILE:) -> "WARNING: FILEIO:" TESTING_FAIL_RLGL = 1 << 3, // OpenGL-wrapped initialization -> "INFO: RLGL: Default OpenGL state initialized successfully" TESTING_FAIL_PLATFORM = 1 << 4, // Platform initialization -> "INFO: PLATFORM: DESKTOP (GLFW - Win32): Initialized successfully" TESTING_FAIL_FONT = 1 << 5, // Font default initialization -> "INFO: FONT: Default font loaded successfully (224 glyphs)" TESTING_FAIL_TIMER = 1 << 6, // Timer initialization -> "INFO: TIMER: Target time per frame: 16.667 milliseconds" ``` --- .../rexm/reports/examples_testing_windows.md | 16 +- tools/rexm/rexm.c | 527 +++++++++--------- 2 files changed, 287 insertions(+), 256 deletions(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index dca13478f..c9ac48a9f 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -4,15 +4,17 @@ ``` Example automated testing elements validated: - - [WARN] : WARNING messages count - [INIT] : Initialization - [CLOSE] : Closing - [ASSETS] : Assets loading - - [OTHER] : Other types of warnings - - [RESULT] : Ending program result (0) - + - [RLGL] : OpenGL-wrapped initialization + - [PLAT] : Platform initialization + - [FONT] : Font default initialization + - [TIMER] : Timer initialization ``` -| **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [OTHER] | [RESULT] | -|:---------------------------------|:------:|:------:|:-------:|:--------:|:-------:|:--------:| -| core_highdpi_testbed | 2 | ✔ | ✔ | ✔ | ✔ | ✔ | +| **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | +|:---------------------------------|:------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| core_custom_logging | 0 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | +| core_custom_frame_control | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | + diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 1133fbfdd..8b0053c20 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -92,6 +92,12 @@ typedef struct { char **resPaths; // Example resources paths (MAX: 256) } rlExampleInfo; +// Automated testing data +typedef struct { + int warnings; // Warnings counter + int status; // Testing status result flags +} rlExampleTesting; + // Validation status for a single example typedef enum { VALID_OK = 0, // All required files and entries are present @@ -112,6 +118,18 @@ typedef enum { VALID_UNKNOWN_ERROR = 1 << 14 // Unknown failure case (fallback) } rlExampleValidationStatus; +typedef enum { + TESTING_OK = 0, // All automated testing ok + TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" + TESTING_FAIL_CLOSE = 1 << 1, // Closing (CloseWindow()) -> "INFO: Window closed successfully" + TESTING_FAIL_ASSETS = 1 << 2, // Assets loading (WARNING: FILE:) -> "WARNING: FILEIO:" + TESTING_FAIL_RLGL = 1 << 3, // OpenGL-wrapped initialization -> "INFO: RLGL: Default OpenGL state initialized successfully" + TESTING_FAIL_PLATFORM = 1 << 4, // Platform initialization -> "INFO: PLATFORM: DESKTOP (GLFW - Win32): Initialized successfully" + TESTING_FAIL_FONT = 1 << 5, // Font deefault initialization -> "INFO: FONT: Default font loaded successfully (224 glyphs)" + TESTING_FAIL_TIMER = 1 << 6, // Timer initialization -> "INFO: TIMER: Target time per frame: 16.667 milliseconds" + TESTING_FAIL_OTHER = 1 << 7, // Other types of warnings (WARNING:) +} rlExampleTestingStatus; + // Example management operations typedef enum { OP_NONE = 0, // No process to do @@ -146,8 +164,8 @@ static int UpdateRequiredFiles(void); // Load examples collection information // NOTE 1: Load by category: "ALL", "core", "shapes", "textures", "text", "models", "shaders", others" // NOTE 2: Sort examples list on request flag -static rlExampleInfo *LoadExamplesData(const char *fileName, const char *category, bool sort, int *exCount); -static void UnloadExamplesData(rlExampleInfo *exInfo); +static rlExampleInfo *LoadExampleData(const char *filter, bool sort, int *exCount); +static void UnloadExampleData(rlExampleInfo *exInfo); // Load example info from file header static rlExampleInfo *LoadExampleInfo(const char *exFileName); @@ -162,10 +180,10 @@ static int ParseExampleInfoLine(const char *line, rlExampleInfo *entry); static void SortExampleByName(rlExampleInfo *items, int count); // Scan resource paths in example file -static char **ScanExampleResources(const char *filePath, int *resPathCount); +static char **LoadExampleResourcePaths(const char *filePath, int *resPathCount); // Clear resource paths scanned -static void ClearExampleResources(char **resPaths); +static void UnloadExampleResourcePaths(char **resPaths); // Add/remove VS project (.vcxproj) tofrom existing VS solution (.sln) static int AddVSProjectToSolution(const char *slnFile, const char *projFile, const char *category); @@ -223,7 +241,8 @@ int main(int argc, char *argv[]) char exRecategory[32] = { 0 }; // Example re-name category: shapes char exRename[64] = { 0 }; // Example re-name, without extension - char exRebuildRequested[16] = { 0 }; // Example category/full rebuild request + char *exBuildList[256] = { 0 }; // Example build list for: ALL, , single-example + int exBuildListCount = 0; // Example build list file count int opCode = OP_NONE; // Operation code: 0-None(Help), 1-Create, 2-Add, 3-Rename, 4-Remove bool showUsage = false; // Flag to show usage help @@ -383,80 +402,38 @@ int main(int argc, char *argv[]) opCode = OP_UPDATE; } - else if (strcmp(argv[1], "build") == 0) + else if ((strcmp(argv[1], "build") == 0) || (strcmp(argv[1], "test") == 0)) { - // Build example for PLATFORM_DESKTOP and PLATFORM_WEB + // Build/Test example(s) for PLATFORM_DESKTOP and PLATFORM_WEB // NOTE: Build outputs to default directory, usually where the .c file is located, // to avoid issues with copying resources (at least on Desktop) // Web build files (.html, .wasm, .js, .data) are copied to raylib.com/examples repo // Check for valid upcoming argument - if (argc == 2) LOG("WARNING: No example name provided to build\n"); + if (argc == 2) LOG("WARNING: No example name/category provided\n"); else if (argc > 3) LOG("WARNING: Too many arguments provided\n"); else { - // Support building not only individual examples but categories and "ALL" - if ((strcmp(argv[2], "ALL") == 0) || TextInList(argv[2], exCategories, REXM_MAX_EXAMPLE_CATEGORIES)) + // Support building/testing not only individual examples but multiple: ALL/ + rlExampleInfo *exBuildListInfo = LoadExampleData(argv[2], false, &exBuildListCount); + + for (int i = 0; i < exBuildListCount; i++) { - // Category/ALL rebuilt requested - strcpy(exRebuildRequested, argv[2]); - } - else - { - // Verify example exists in collection to be removed - char *exColInfo = LoadFileText(exCollectionFilePath); - if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection - { - strcpy(exName, argv[2]); // Register example name - strncpy(exCategory, exName, TextFindIndex(exName, "_")); - opCode = OP_BUILD; - } - else LOG("WARNING: BUILD: Example requested not available in the collection\n"); - UnloadFileText(exColInfo); - } - } - } - else if (strcmp(argv[1], "test") == 0) - { - // Build and test example for PLATFORM_DESKTOP - // NOTE: Build outputs to default directory, usually where the .c file is located, - // to avoid issues with copying resources (at least on Desktop) - if (argc == 2) LOG("WARNING: No example name provided to test\n"); - else if (argc > 3) LOG("WARNING: Too many arguments provided\n"); - else - { - // Support building not only individual examples but categories and "ALL" - if ((strcmp(argv[2], "ALL") == 0) || TextInList(argv[2], exCategories, REXM_MAX_EXAMPLE_CATEGORIES)) - { - // Category/ALL rebuilt requested - strcpy(exRebuildRequested, argv[2]); - } - else - { - // Verify example exists in collection to be removed - char *exColInfo = LoadFileText(exCollectionFilePath); - if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection - { - strcpy(exName, argv[2]); // Register example name - strncpy(exCategory, exName, TextFindIndex(exName, "_")); - opCode = OP_TEST; - } - else LOG("WARNING: TEST: Example requested not available in the collection\n"); - UnloadFileText(exColInfo); + exBuildList[i] = (char *)RL_CALLOC(256, sizeof(char)); + strcpy(exBuildList[i], exBuildListInfo[i].name); } + + UnloadExampleData(exBuildListInfo); + + if (exBuildListCount == 0) LOG("WARNING: BUILD: Example requested not available in the collection\n"); + else opCode = OP_TEST; } } // Process command line options arguments for (int i = 1; i < argc; i++) { - if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) - { - showUsage = true; - } - else if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--verbose") == 0)) - { - verbose = true; - } + if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) showUsage = true; + else if ((strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--verbose") == 0)) verbose = true; } } @@ -513,7 +490,7 @@ int main(int argc, char *argv[]) // NOTE: resources path will be relative to example source file directory int resPathCount = 0; LOG("INFO: [%s] Scanning file for resources...\n", GetFileName(inFileName)); - char **resPaths = ScanExampleResources(TextFormat("%s/%s.c", GetDirectoryPath(inFileName), exName), &resPathCount); + char **resPaths = LoadExampleResourcePaths(TextFormat("%s/%s.c", GetDirectoryPath(inFileName), exName), &resPathCount); if (resPathCount > 0) { @@ -571,7 +548,7 @@ int main(int argc, char *argv[]) } } - ClearExampleResources(resPaths); + UnloadExampleResourcePaths(resPaths); // ----------------------------------------------------------------------------------------- // Add example to the collection list, if not already there @@ -727,13 +704,13 @@ int main(int argc, char *argv[]) // Edit: Update example source code metadata int exListCount = 0; - rlExampleInfo *exList = LoadExamplesData(exCollectionFilePath, exCategory, false, &exListCount); + rlExampleInfo *exList = LoadExampleData(exCategory, false, &exListCount); for (int i = 0; i < exListCount; i++) { if (strcmp(exList[i].name, exRename) == 0) UpdateSourceMetadata(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exRename), &exList[i]); } - UnloadExamplesData(exList); + UnloadExampleData(exList); // NOTE: Example resource files do not need to be changed... // unless the example is moved from one caegory to another @@ -919,79 +896,24 @@ int main(int argc, char *argv[]) case OP_BUILD: { LOG("INFO: Command requested: BUILD\n"); - LOG("INFO: Example to be built: %s\n", exName); + LOG("INFO: Example(s) to be built: %i [%s]\n", exBuildListCount, (exBuildListCount == 1)? exBuildList[0] : argv[2]); - if ((exRebuildRequested[0] != '\0') && - (strcmp(exRebuildRequested, "others") != 0) && - (strcmp(exCategory, "others") != 0)) // Skipping "others" category for rebuild: Special needs +#if defined(_WIN32) + // Set required environment variables + //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + //putenv("MAKE=mingw32-make"); + //ChangeDirectory(exBasePath); +#endif + for (int i = 0; i < exBuildListCount; i++) { - // TODO: Support building full categories: exRebuildRequested + // Get example name and category + memset(exName, 0, 64); + strcpy(exName, exBuildList[i]); + memset(exCategory, 0, 32); + strncpy(exCategory, exName, TextFindIndex(exName, "_")); - int exRebuildCount = 0; - rlExampleInfo *exRebuildList = LoadExamplesData(exCollectionFilePath, exRebuildRequested, false, &exRebuildCount); - - // Build: raylib.com/examples//_example_name.html - // Build: raylib.com/examples//_example_name.data - // Build: raylib.com/examples//_example_name.wasm - // Build: raylib.com/examples//_example_name.js -#if defined(_WIN32) - // Set required environment variables - //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); - _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); - //putenv("MAKE=mingw32-make"); - //ChangeDirectory(exBasePath); -#endif - for (int i = 0; i < exRebuildCount; i++) - { - // Build example for PLATFORM_DESKTOP -#if defined(_WIN32) - LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); -#else - LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); - system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); -#endif - - // Build example for PLATFORM_WEB -#if defined(_WIN32) - LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); -#else - LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); - system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); -#endif - // Update generated .html metadata - LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exRebuildList[i].name)); - UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name), - TextFormat("%s/%s/%s.c", exBasePath, exRebuildList[i].category, exRebuildList[i].name)); - - // Copy results to web side - LOG("INFO: [%s] Copy example build to raylib.com\n", exRebuildList[i].name); - FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exRebuildList[i].category, exRebuildList[i].name), - TextFormat("%s/%s/%s.html", exWebPath, exRebuildList[i].category, exRebuildList[i].name)); - FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exRebuildList[i].category, exRebuildList[i].name), - TextFormat("%s/%s/%s.data", exWebPath, exRebuildList[i].category, exRebuildList[i].name)); - FileCopy(TextFormat("%s/%s/%s.wasm", exBasePath, exRebuildList[i].category, exRebuildList[i].name), - TextFormat("%s/%s/%s.wasm", exWebPath, exRebuildList[i].category, exRebuildList[i].name)); - FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exRebuildList[i].category, exRebuildList[i].name), - TextFormat("%s/%s/%s.js", exWebPath, exRebuildList[i].category, exRebuildList[i].name)); - } - - UnloadExamplesData(exRebuildList); - } - else // Build a single example - { - // Build: raylib.com/examples//_example_name.html - // Build: raylib.com/examples//_example_name.data - // Build: raylib.com/examples//_example_name.wasm - // Build: raylib.com/examples//_example_name.js -#if defined(_WIN32) - // Set required environment variables - //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); - _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); - //putenv("MAKE=mingw32-make"); - //ChangeDirectory(exBasePath); -#endif + LOG("INFO: [%i/%i] Building example: [%s]\n", i + 1, exBuildListCount, exName); // Build example for PLATFORM_DESKTOP #if defined(_WIN32) @@ -1003,6 +925,10 @@ int main(int argc, char *argv[]) #endif // Build example for PLATFORM_WEB + // Build: raylib.com/examples//_example_name.html + // Build: raylib.com/examples//_example_name.data + // Build: raylib.com/examples//_example_name.wasm + // Build: raylib.com/examples//_example_name.js #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); @@ -1025,8 +951,10 @@ int main(int argc, char *argv[]) TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName)); FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName), TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName)); + + // Once example processed, free memory from list + RL_FREE(exBuildList[i]); } - //LOG("WARNING: [others] category examples should be build manually, they could have specific build requirements\n"); } break; case OP_VALIDATE: // Validate: report and actions @@ -1129,7 +1057,7 @@ int main(int argc, char *argv[]) // Check all examples in collection [examples_list.txt] -> Source of truth! LOG("INFO: Validating examples in collection...\n"); int exCollectionCount = 0; - rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, "ALL", false, &exCollectionCount); + rlExampleInfo *exCollection = LoadExampleData("ALL", false, &exCollectionCount); // Set status information for all examples, using "status" field in the struct for (int i = 0; i < exCollectionCount; i++) @@ -1174,7 +1102,7 @@ int main(int argc, char *argv[]) // Validate: raylib/examples//resources/.. -> Example resources available? // Scan resources used in example to check for missing resource files // WARNING: Some paths could be for files to save, not files to load, verify it - char **resPaths = ScanExampleResources(TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name), &exInfo->resCount); + char **resPaths = LoadExampleResourcePaths(TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name), &exInfo->resCount); if (exInfo->resCount > 0) { for (int r = 0; r < exInfo->resCount; r++) @@ -1207,7 +1135,7 @@ int main(int argc, char *argv[]) } } } - ClearExampleResources(resPaths); + UnloadExampleResourcePaths(resPaths); // Validate: raylib.com/examples//_example_name.html -> File exists? // Validate: raylib.com/examples//_example_name.data -> File exists? @@ -1337,8 +1265,8 @@ int main(int argc, char *argv[]) _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name)); #else - LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->name); - system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name)); + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->filter); + system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->filter)); #endif // Update generated .html metadata @@ -1411,7 +1339,7 @@ int main(int argc, char *argv[]) | shapes_colors_palette | ✘ | ✔ | ✘ | ✔ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_format_text | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ | */ - LOG("INFO: [examples_report.md] Generating examples validation report...\n"); + LOG("INFO: [examples_validation.md] Generating examples validation report...\n"); char *report = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); @@ -1457,13 +1385,13 @@ int main(int argc, char *argv[]) (exCollection[i].status & VALID_MISSING_WEB_METADATA)? "❌" : "✔"); } - SaveFileText(TextFormat("%s/../tools/rexm/%s", exBasePath, "examples_report.md"), report); + SaveFileText(TextFormat("%s/../tools/rexm/reports/%s", exBasePath, "examples_validation.md"), report); RL_FREE(report); //----------------------------------------------------------------------------------------------------- // Generate a report with only the examples missing some elements //----------------------------------------------------------------------------------------------------- - LOG("INFO: [examples_report_issues.md] Generating examples issues report...\n"); + LOG("INFO: [examples_issues.md] Generating examples issues report...\n"); char *reportIssues = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); @@ -1512,100 +1440,193 @@ int main(int argc, char *argv[]) } } - SaveFileText(TextFormat("%s/../tools/rexm/%s", exBasePath, "examples_report_issues.md"), reportIssues); + SaveFileText(TextFormat("%s/../tools/rexm/reports/%s", exBasePath, "examples_issues.md"), reportIssues); RL_FREE(reportIssues); //----------------------------------------------------------------------------------------------------- - UnloadExamplesData(exCollection); + UnloadExampleData(exCollection); //------------------------------------------------------------------------------------------------ } break; case OP_TEST: { LOG("INFO: Command requested: TEST\n"); - LOG("INFO: Example to be built and tested: %s\n", exName); + LOG("INFO: Example(s) to be build and tested: %i [%s]\n", exBuildListCount, (exBuildListCount == 1)? exBuildList[0] : argv[2]); - // Steps to follow - // STEP 1: Load example.c and replace required code to inject basic testing code: frames to run - // OPTION 1: Code injection required multiple changes for testing but it does not require raylib changes! - // OPTION 2: Support testing on raylib side: Args processing and events injection: SUPPORT_AUTOMATD_TESTING_SYSTEM, EVENTS_TESTING_MODE - // STEP 2: Build example (PLATFORM_DESKTOP) - // STEP 3: Run example with arguments: --frames 2 > .out.log - // STEP 4: Load .out.log and check "WARNING:" messages -> Some could maybe be ignored - // STEP 5: Generate report with results + rlExampleTesting *testing = (rlExampleTesting *)RL_CALLOC(exBuildListCount, sizeof(rlExampleTesting)); - // STEP 1: Load example and inject required code - // PROBLEM: As we need to modify the example source code for building, we need to keep a copy or something - // WARNING: If we make a copy and something fails, it could not be restored at the end - // PROBLEM: Trying to build a copy won't work because Makefile is setup to look for specific example on specific path -> No output dir config - // IDEA: Create directory for testing data -> It implies moving files and set working dir... - // SOLUTION: Make a copy of original file -> Modify original -> Build -> Rename to .test.exe - FileCopy(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), - TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); - char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); - - static const char *mainReplaceText = - "#include \n" - "#include \n" - "int main(int argc, char *argv[])\n{\n" - " int requestedTestFrames = 0;\n" - " int testFramesCount = 0;\n" - " if ((argc > 1) && (argc == 3) && (strcmp(argv[1], \"--frames\") != 0)) requestedTestFrames = atoi(argv[2]);\n"; - - char *srcTextUpdated[3] = { 0 }; - srcTextUpdated[0] = TextReplace(srcText, "int main(void)\n{", mainReplaceText); - srcTextUpdated[1] = TextReplace(srcTextUpdated[0], "WindowShouldClose()", "WindowShouldClose() && (testFramesCount < requestedTestFrames)"); - srcTextUpdated[2] = TextReplace(srcTextUpdated[1], "EndDrawing();", "EndDrawing(); testFramesCount++;"); - UnloadFileText(srcText); - - SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[2]); - for (int i = 0; i < 3; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } - - // STEP 2: Build example for DESKTOP platform -#if defined(_WIN32) - // Set required environment variables - //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); - _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); - //putenv("MAKE=mingw32-make"); - //ChangeDirectory(exBasePath); -#endif - // Build example for PLATFORM_DESKTOP -#if defined(_WIN32) - LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); -#else - LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); - system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); -#endif - // Restore original source code before continue - FileCopy(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName), - TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); - FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); - - // STEP 3: Run example with required arguments - ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); - system(TextFormat("%s --frames 2 > %s.log", exName, exName)); - - // STEP 4: Load and validate log -> WARNINGS - char *exTestLog = LoadFileText(TextFormat("%s/%s/%s.log", exBasePath, exCategory, exName)); - int exTestLogLinesCount = 0; - char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); - UnloadFileText(exTestLog); - - int issueCounter = false; - for (int i = 0; i < exTestLogLinesCount; i++) + for (int i = 0; i < exBuildListCount; i++) { - if (TextFindIndex(exTestLogLines[i], "WARNING") >= 0) + // Get example name and category + memset(exName, 0, 64); + strcpy(exName, exBuildList[i]); + memset(exCategory, 0, 32); + strncpy(exCategory, exName, TextFindIndex(exName, "_")); + + LOG("INFO: [%i/%i] Testing example: [%s]\n", i + 1, exBuildListCount, exName); + + // Steps to follow + // STEP 1: Load example.c and replace required code to inject basic testing code: frames to run + // OPTION 1: Code injection required multiple changes for testing but it does not require raylib changes! + // OPTION 2: Support testing on raylib side: Args processing and events injection: SUPPORT_AUTOMATD_TESTING_SYSTEM, EVENTS_TESTING_MODE + // STEP 2: Build example (PLATFORM_DESKTOP) + // STEP 3: Run example with arguments: --frames 2 > .out.log + // STEP 4: Load .out.log and check "WARNING:" messages -> Some could maybe be ignored + // STEP 5: Generate report with results + + // STEP 1: Load example and inject required code + // PROBLEM: As we need to modify the example source code for building, we need to keep a copy or something + // WARNING: If we make a copy and something fails, it could not be restored at the end + // PROBLEM: Trying to build a copy won't work because Makefile is setup to look for specific example on specific path -> No output dir config + // IDEA: Create directory for testing data -> It implies moving files and set working dir... + // SOLUTION: Make a copy of original file -> Modify original -> Build -> Rename to .test.exe + FileCopy(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); + char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + + static const char *mainReplaceText = + "#include \n" + "#include \n" + "int main(int argc, char *argv[])\n{\n" + " int requestedTestFrames = 0;\n" + " int testFramesCount = 0;\n" + " if ((argc > 1) && (argc == 3) && (strcmp(argv[1], \"--frames\") != 0)) requestedTestFrames = atoi(argv[2]);\n"; + + char *srcTextUpdated[3] = { 0 }; + srcTextUpdated[0] = TextReplace(srcText, "int main(void)\n{", mainReplaceText); + srcTextUpdated[1] = TextReplace(srcTextUpdated[0], "WindowShouldClose()", "WindowShouldClose() && (testFramesCount < requestedTestFrames)"); + srcTextUpdated[2] = TextReplace(srcTextUpdated[1], "EndDrawing();", "EndDrawing(); testFramesCount++;"); + UnloadFileText(srcText); + + SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[2]); + for (int i = 0; i < 3; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } + + // STEP 2: Build example for DESKTOP platform +#if defined(_WIN32) + // Set required environment variables + //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + //putenv("MAKE=mingw32-make"); + //ChangeDirectory(exBasePath); +#endif + // Build example for PLATFORM_DESKTOP +#if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); + system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#else + LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#endif + // Restore original source code before continue + FileCopy(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); + + // STEP 3: Run example with required arguments + // NOTE: Not easy to retrieve process return value from system(), it's platform dependant + ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); + system(TextFormat("%s --frames 2 > %s.log", exName, exName)); + + // STEP 4: Load and validate log info + char *exTestLog = LoadFileText(TextFormat("%s/%s/%s.log", exBasePath, exCategory, exName)); + int exTestLogLinesCount = 0; + char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); + + /* + TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" + TESTING_FAIL_CLOSE = 1 << 1, // Closing (CloseWindow()) -> "INFO: Window closed successfully" + TESTING_FAIL_ASSETS = 1 << 2, // Assets loading (WARNING: FILE:) -> "WARNING: FILEIO:" + TESTING_FAIL_RLGL = 1 << 3, // OpenGL-wrapped initialization -> "INFO: RLGL: Default OpenGL state initialized successfully" + TESTING_FAIL_PLATFORM = 1 << 4, // Platform initialization -> "INFO: PLATFORM: DESKTOP (GLFW - Win32): Initialized successfully" + TESTING_FAIL_FONT = 1 << 5, // Font default initialization -> "INFO: FONT: Default font loaded successfully (224 glyphs)" + TESTING_FAIL_TIMER = 1 << 6, // Timer initialization -> "INFO: TIMER: Target time per frame: 16.667 milliseconds" + */ + + if (TextFindIndex(exTestLog, "INFO: DISPLAY: Device initialized successfully") == -1) testing[i].status |= TESTING_FAIL_INIT; + if (TextFindIndex(exTestLog, "INFO: Window closed successfully") == -1) testing[i].status |= TESTING_FAIL_CLOSE; + if (TextFindIndex(exTestLog, "WARNING: FILEIO:") >= 0) testing[i].status |= TESTING_FAIL_ASSETS; + if (TextFindIndex(exTestLog, "INFO: RLGL: Default OpenGL state initialized successfully") == -1) testing[i].status |= TESTING_FAIL_RLGL; + if (TextFindIndex(exTestLog, "INFO: PLATFORM:") == -1) testing[i].status |= TESTING_FAIL_PLATFORM; + if (TextFindIndex(exTestLog, "INFO: FONT: Default font loaded successfully") == -1) testing[i].status |= TESTING_FAIL_FONT; + if (TextFindIndex(exTestLog, "INFO: TIMER: Target time per frame:") == -1) testing[i].status |= TESTING_FAIL_TIMER; + + for (int k = 0, index = 0; k < exTestLogLinesCount; k++) { - LOG("TEST: [%s] %s\n", exName, exTestLogLines[i]); - issueCounter++; + if (TextFindIndex(exTestLogLines[k], "WARNING") >= 0) testing[i].warnings++; + } + + UnloadTextLines(exTestLogLines, exTestLogLinesCount); + UnloadFileText(exTestLog); + } + + // STEP 5: Generate testing report/table with results (.md) + //----------------------------------------------------------------------------------------------------- + /* + Columns: + - [WARN] : WARNING messages count + - [INIT] : Initialization + - [CLOSE] : Closing + - [ASSETS] : Assets loading + - [RLGL] : OpenGL-wrapped initialization + - [PLAT] : Platform initialization + - [FONT] : Font default initialization + - [TIMER] : Timer initialization + + | **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | + |:---------------------------------|:------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| + | core_basic window | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | + */ + LOG("INFO: [examples_testing.md] Generating examples testing report...\n"); + + char *report = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); + + int repIndex = 0; + repIndex += sprintf(report + repIndex, "# EXAMPLES COLLECTION - TESTING REPORT\n\n"); + repIndex += sprintf(report + repIndex, "## Tested Platform: Windows\n\n"); + + repIndex += sprintf(report + repIndex, "```\nExample automated testing elements validated:\n"); + repIndex += sprintf(report + repIndex, " - [WARN] : WARNING messages count\n"); + repIndex += sprintf(report + repIndex, " - [INIT] : Initialization\n"); + repIndex += sprintf(report + repIndex, " - [CLOSE] : Closing\n"); + repIndex += sprintf(report + repIndex, " - [ASSETS] : Assets loading\n"); + repIndex += sprintf(report + repIndex, " - [RLGL] : OpenGL-wrapped initialization\n"); + repIndex += sprintf(report + repIndex, " - [PLAT] : Platform initialization\n"); + repIndex += sprintf(report + repIndex, " - [FONT] : Font default initialization\n"); + repIndex += sprintf(report + repIndex, " - [TIMER] : Timer initialization\n```\n"); + + repIndex += sprintf(report + repIndex, "| **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] |\n"); + repIndex += sprintf(report + repIndex, "|:---------------------------------|:------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:|\n"); + + /* + TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" + TESTING_FAIL_CLOSE = 1 << 1, // Closing (CloseWindow()) -> "INFO: Window closed successfully" + TESTING_FAIL_ASSETS = 1 << 2, // Assets loading (WARNING: FILE:) -> "WARNING: FILEIO:" + TESTING_FAIL_RLGL = 1 << 3, // OpenGL-wrapped initialization -> "INFO: RLGL: Default OpenGL state initialized successfully" + TESTING_FAIL_PLATFORM = 1 << 4, // Platform initialization -> "INFO: PLATFORM: DESKTOP (GLFW - Win32): Initialized successfully" + TESTING_FAIL_FONT = 1 << 5, // Font default initialization -> "INFO: FONT: Default font loaded successfully (224 glyphs)" + TESTING_FAIL_TIMER = 1 << 6, // Timer initialization -> "INFO: TIMER: Target time per frame: 16.667 milliseconds" + */ + for (int i = 0; i < exBuildListCount; i++) + { + if (testing[i].status > 0) + { + repIndex += sprintf(report + repIndex, "| %-32s | %i | %s | %s | %s | %s | %s | %s | %s |\n", + exBuildList[i], testing[i].warnings, + (testing[i].status & TESTING_FAIL_INIT)? "✔" : "❌", + (testing[i].status & TESTING_FAIL_CLOSE)? "✔" : "❌", + (testing[i].status & TESTING_FAIL_ASSETS)? "✔" : "❌", + (testing[i].status & TESTING_FAIL_RLGL)? "✔" : "❌", + (testing[i].status & TESTING_FAIL_PLATFORM)? "✔" : "❌", + (testing[i].status & TESTING_FAIL_FONT)? "✔" : "❌", + (testing[i].status & TESTING_FAIL_TIMER)? "✔" : "❌"); } } - UnloadTextLines(exTestLogLines, exTestLogLinesCount); + repIndex += sprintf(report + repIndex, "\n"); - // STEP 5: Generate auto-test report - //if (issueCounter > 0) + SaveFileText(TextFormat("%s/../tools/rexm/reports/%s", exBasePath, "examples_testing_windows.md"), report); + RL_FREE(report); + //----------------------------------------------------------------------------------------------------- } break; default: // Help @@ -1668,13 +1689,13 @@ static int UpdateRequiredFiles(void) //------------------------------------------------------------------------------------------------ LOG("INFO: Updating all examples metadata...\n"); int exListCount = 0; - rlExampleInfo *exList = LoadExamplesData(exCollectionFilePath, "ALL", true, &exListCount); + rlExampleInfo *exList = LoadExampleData("ALL", true, &exListCount); for (int i = 0; i < exListCount; i++) { rlExampleInfo *info = &exList[i]; UpdateSourceMetadata(TextFormat("%s/%s/%s.c", exBasePath, info->category, info->name), info); } - UnloadExamplesData(exList); + UnloadExampleData(exList); //------------------------------------------------------------------------------------------------ // Edit: raylib/examples/Makefile --> Update from collection @@ -1695,12 +1716,12 @@ static int UpdateRequiredFiles(void) mkIndex += sprintf(mkTextUpdated + mkListStartIndex + mkIndex, TextFormat("%s = \\\n", TextToUpper(exCategories[i]))); int exCollectionCount = 0; - rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], true, &exCollectionCount); + rlExampleInfo *exCollection = LoadExampleData(exCategories[i], true, &exCollectionCount); for (int x = 0; x < exCollectionCount - 1; x++) mkIndex += sprintf(mkTextUpdated + mkListStartIndex + mkIndex, TextFormat(" %s/%s \\\n", exCollection[x].category, exCollection[x].name)); mkIndex += sprintf(mkTextUpdated + mkListStartIndex + mkIndex, TextFormat(" %s/%s\n\n", exCollection[exCollectionCount - 1].category, exCollection[exCollectionCount - 1].name)); - UnloadExamplesData(exCollection); + UnloadExampleData(exCollection); } // Add the remaining part of the original file @@ -1732,12 +1753,12 @@ static int UpdateRequiredFiles(void) mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat("%s = \\\n", TextToUpper(exCategories[i]))); int exCollectionCount = 0; - rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], true, &exCollectionCount); + rlExampleInfo *exCollection = LoadExampleData(exCategories[i], true, &exCollectionCount); for (int x = 0; x < exCollectionCount - 1; x++) mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat(" %s/%s \\\n", exCollection[x].category, exCollection[x].name)); mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat(" %s/%s\n\n", exCollection[exCollectionCount - 1].category, exCollection[exCollectionCount - 1].name)); - UnloadExamplesData(exCollection); + UnloadExampleData(exCollection); } // Add examples individual targets, considering every example resources @@ -1758,13 +1779,13 @@ static int UpdateRequiredFiles(void) mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, TextFormat("# Compile %s examples\n", TextToUpper(exCategories[i]))); int exCollectionCount = 0; - rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], true, &exCollectionCount); + rlExampleInfo *exCollection = LoadExampleData(exCategories[i], true, &exCollectionCount); for (int x = 0; x < exCollectionCount; x++) { // Scan resources used in example to list int resPathCount = 0; - char **resPaths = ScanExampleResources(TextFormat("%s/%s/%s.c", exBasePath, exCollection[x].category, exCollection[x].name), &resPathCount); + char **resPaths = LoadExampleResourcePaths(TextFormat("%s/%s/%s.c", exBasePath, exCollection[x].category, exCollection[x].name), &resPathCount); if (resPathCount > 0) { @@ -1817,10 +1838,10 @@ static int UpdateRequiredFiles(void) mkwIndex += sprintf(mkwTextUpdated + mkwListStartIndex + mkwIndex, " $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)\n\n"); } - ClearExampleResources(resPaths); + UnloadExampleResourcePaths(resPaths); } - UnloadExamplesData(exCollection); + UnloadExampleData(exCollection); } // Add the remaining part of the original file @@ -1846,8 +1867,8 @@ static int UpdateRequiredFiles(void) memcpy(mdTextUpdated, mdText, mdListStartIndex); int exCollectionFullCount = 0; - rlExampleInfo *exCollectionFull = LoadExamplesData(exCollectionFilePath, "ALL", false, &exCollectionFullCount); - UnloadExamplesData(exCollectionFull); + rlExampleInfo *exCollectionFull = LoadExampleData("ALL", false, &exCollectionFullCount); + UnloadExampleData(exCollectionFull); mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, TextFormat("## EXAMPLES COLLECTION [TOTAL: %i]\n", exCollectionFullCount)); @@ -1855,7 +1876,7 @@ static int UpdateRequiredFiles(void) for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { int exCollectionCount = 0; - rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], false, &exCollectionCount); + rlExampleInfo *exCollection = LoadExampleData(exCategories[i], false, &exCollectionCount); // Every category includes some introductory text, as it is quite short, just copying it here if (i == 0) // "core" @@ -1926,7 +1947,7 @@ static int UpdateRequiredFiles(void) starsText, exCollection[x].verCreated, exCollection[x].verUpdated, exCollection[x].author, exCollection[x].authorGitHub)); } - UnloadExamplesData(exCollection); + UnloadExampleData(exCollection); } mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, @@ -1972,7 +1993,7 @@ static int UpdateRequiredFiles(void) for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES - 1; i++) { int exCollectionCount = 0; - rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, exCategories[i], false, &exCollectionCount); + rlExampleInfo *exCollection = LoadExampleData(exCategories[i], false, &exCollectionCount); for (int x = 0; x < exCollectionCount; x++) { for (int s = 0; s < 4; s++) @@ -1994,7 +2015,7 @@ static int UpdateRequiredFiles(void) } } - UnloadExamplesData(exCollection); + UnloadExampleData(exCollection); } // Add the remaining part of the original file @@ -2011,8 +2032,8 @@ static int UpdateRequiredFiles(void) return result; } -// Load examples collection information -static rlExampleInfo *LoadExamplesData(const char *fileName, const char *category, bool sort, int *exCount) +// Load examples information from collection data +static rlExampleInfo *LoadExampleData(const char *filter, bool sort, int *exCount) { #define MAX_EXAMPLES_INFO 256 @@ -2020,7 +2041,8 @@ static rlExampleInfo *LoadExamplesData(const char *fileName, const char *categor int exCounter = 0; *exCount = 0; - char *text = LoadFileText(fileName); + // Load main collection list file: "raylib/examples/examples_list.txt" + char *text = LoadFileText(exCollectionFilePath); if (text != NULL) { @@ -2042,18 +2064,25 @@ static rlExampleInfo *LoadExamplesData(const char *fileName, const char *categor int result = ParseExampleInfoLine(lines[i], &info); if (result == 1) // Success on parsing { - if (strcmp(category, "ALL") == 0) + if (strcmp(filter, "ALL") == 0) { // Add all examples to the list memcpy(&exInfo[exCounter], &info, sizeof(rlExampleInfo)); exCounter++; } - else if (strcmp(info.category, category) == 0) + else if (strcmp(info.category, filter) == 0) { // Get only specific category examples memcpy(&exInfo[exCounter], &info, sizeof(rlExampleInfo)); exCounter++; } + else if (strcmp(info.name, filter) == 0) + { + // Get only requested example + memcpy(&exInfo[exCounter], &info, sizeof(rlExampleInfo)); + exCounter++; + break; + } } } } @@ -2070,7 +2099,7 @@ static rlExampleInfo *LoadExamplesData(const char *fileName, const char *categor } // Unload examples collection data -static void UnloadExamplesData(rlExampleInfo *exInfo) +static void UnloadExampleData(rlExampleInfo *exInfo) { RL_FREE(exInfo); } @@ -2160,7 +2189,7 @@ static rlExampleInfo *LoadExampleInfo(const char *exFileName) UnloadFileText(exText); - exInfo->resPaths = ScanExampleResources(exFileName, &exInfo->resCount); + exInfo->resPaths = LoadExampleResourcePaths(exFileName, &exInfo->resCount); } return exInfo; @@ -2169,7 +2198,7 @@ static rlExampleInfo *LoadExampleInfo(const char *exFileName) // Unload example information static void UnloadExampleInfo(rlExampleInfo *exInfo) { - ClearExampleResources(exInfo->resPaths); + UnloadExampleResourcePaths(exInfo->resPaths); RL_FREE(exInfo); } @@ -2245,7 +2274,7 @@ static void SortExampleByName(rlExampleInfo *items, int count) // but new examples could require other file extensions to be added, // maybe it should look for '.xxx")' patterns instead // TODO: WARNING: Some resources could require linked resources: .fnt --> .png, .mtl --> .png, .gltf --> .png, ... -static char **ScanExampleResources(const char *filePath, int *resPathCount) +static char **LoadExampleResourcePaths(const char *filePath, int *resPathCount) { #define REXM_MAX_RESOURCE_PATH_LEN 256 @@ -2327,7 +2356,7 @@ static char **ScanExampleResources(const char *filePath, int *resPathCount) } // Clear resource paths scanned -static void ClearExampleResources(char **resPaths) +static void UnloadExampleResourcePaths(char **resPaths) { for (int i = 0; i < REXM_MAX_RESOURCE_PATHS; i++) RL_FREE(resPaths[i]); From ab463ac89b441deb56ce0a8fcfebd264a1bd69f0 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 09:39:59 +0100 Subject: [PATCH 099/189] Create raylib.vcxproj.filters --- .../rexm/VS2022/raylib/raylib.vcxproj.filters | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tools/rexm/VS2022/raylib/raylib.vcxproj.filters diff --git a/tools/rexm/VS2022/raylib/raylib.vcxproj.filters b/tools/rexm/VS2022/raylib/raylib.vcxproj.filters new file mode 100644 index 000000000..b5f5536dc --- /dev/null +++ b/tools/rexm/VS2022/raylib/raylib.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + external + + + external + + + external + + + external + + + external + + + external + + + external + + + external + + + external + + + external + + + external + + + + + {7c380c65-acd0-428f-83d9-70ef06f69b6d} + + + \ No newline at end of file From a235cd6a18b05e9bdabe79461541e12a7aa98f06 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 19:20:12 +0100 Subject: [PATCH 100/189] Update raygui.h --- examples/core/raygui.h | 139 ++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 72 deletions(-) diff --git a/examples/core/raygui.h b/examples/core/raygui.h index 17ced6ef5..2bd65e478 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -77,7 +77,7 @@ * * static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)]; * -* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB +* 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 @@ -141,7 +141,7 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 5.0-dev (2025) Current dev version... +* 5.0 (xx-Nov-2025) 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 @@ -271,7 +271,7 @@ * 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria * * DEPENDENCIES: -* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing +* 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 @@ -1010,28 +1010,28 @@ typedef enum { ICON_SLICING = 231, ICON_MANUAL_CONTROL = 232, ICON_COLLISION = 233, - ICON_234 = 234, - ICON_235 = 235, - ICON_236 = 236, - ICON_237 = 237, - ICON_238 = 238, - ICON_239 = 239, - ICON_240 = 240, - ICON_241 = 241, - ICON_242 = 242, - ICON_243 = 243, - ICON_244 = 244, - ICON_245 = 245, - ICON_246 = 246, - ICON_247 = 247, - ICON_248 = 248, - ICON_249 = 249, + ICON_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, + ICON_255 = 255 } GuiIconName; #endif @@ -1078,7 +1078,7 @@ typedef enum { // Check if two rectangles are equal, used to validate a slider bounds as an id #ifndef CHECK_BOUNDS_ID - #define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height)) + #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) @@ -1341,22 +1341,22 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = 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 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249 + 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 @@ -1743,7 +1743,7 @@ int GuiPanel(Rectangle bounds, const char *text) // NOTE: Using GuiToggle() for the TABS int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) { - #define RAYGUI_TABBAR_ITEM_WIDTH 160 + #define RAYGUI_TABBAR_ITEM_WIDTH 148 int result = -1; //GuiState state = guiState; @@ -1776,12 +1776,12 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) if (i == (*active)) { toggle = true; - GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + GuiToggle(tabBounds, text[i], &toggle); } else { toggle = false; - GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + GuiToggle(tabBounds, text[i], &toggle); if (toggle) *active = i; } @@ -2590,7 +2590,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int pasteLength = 0; int pasteCodepoint; int pasteCodepointSize; - + // Count how many codepoints to copy, stopping at the first unwanted control character while (true) { @@ -2599,7 +2599,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (!(multiline && (pasteCodepoint == (int)'\n')) && !(pasteCodepoint >= 32)) break; pasteLength += pasteCodepointSize; } - + if (pasteLength > 0) { // Move forward data from cursor position @@ -2662,7 +2662,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) while (offset < textLength) { if (!isspace(nextCodepoint & 0xff)) break; - + offset += nextCodepointSize; accCodepointSize += nextCodepointSize; nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); @@ -2673,11 +2673,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; } - + else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, after current cursor position - + int nextCodepointSize = 0; GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); @@ -2704,7 +2704,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) 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); @@ -2723,11 +2723,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; textBoxCursorIndex -= accCodepointSize; } - + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, before current cursor position - + int prevCodepointSize = 0; GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); @@ -3026,14 +3026,14 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int // 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) + //#if !defined(RAYGUI_VALUEBOX_MAX_CHARS) #define RAYGUI_VALUEBOX_MAX_CHARS 32 - #endif + //#endif int result = 0; GuiState state = guiState; - char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; + char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = { 0 }; snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value); Rectangle textBounds = { 0 }; @@ -3051,7 +3051,6 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { Vector2 mousePoint = GetMousePosition(); - bool valueHasChanged = false; if (editMode) @@ -3070,7 +3069,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in keyCount--; valueHasChanged = true; } - else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS -1) + else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) { if (keyCount == 0) { @@ -3087,30 +3086,26 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in } } - // Only allow keys in range [48..57] - if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + // Add new digit to text value + if ((keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) { - if (GuiGetTextWidth(textValue) < bounds.width) + int key = GetCharPressed(); + + // Only allow keys in range [48..57] + if ((key >= 48) && (key <= 57)) { - int key = GetCharPressed(); - if ((key >= 48) && (key <= 57)) - { - textValue[keyCount] = (char)key; - keyCount++; - valueHasChanged = true; - } + textValue[keyCount] = (char)key; + keyCount++; + valueHasChanged = true; } } // Delete text - if (keyCount > 0) + if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE)) { - if (IsKeyPressed(KEY_BACKSPACE)) - { - keyCount--; - textValue[keyCount] = '\0'; - valueHasChanged = true; - } + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; } if (valueHasChanged) *value = TextToInteger(textValue); @@ -3224,9 +3219,9 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float textValue[1] = '\0'; keyCount++; } - + for (int i = keyCount; i > -1; i--) textValue[i + 1] = textValue[i]; - + textValue[0] = '-'; keyCount++; valueHasChanged = true; From 063986fdae7b9e6fe62da18304a0cec884c425ce Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 19:20:23 +0100 Subject: [PATCH 101/189] Updated solution --- .../examples/textures_screen_buffer.vcxproj | 2 +- projects/VS2022/raylib.sln | 54 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/projects/VS2022/examples/textures_screen_buffer.vcxproj b/projects/VS2022/examples/textures_screen_buffer.vcxproj index 0453d2182..1697481ce 100644 --- a/projects/VS2022/examples/textures_screen_buffer.vcxproj +++ b/projects/VS2022/examples/textures_screen_buffer.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD} Win32Proj textures_screen_buffer 10.0 diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index c3fbb6d2b..f7bbf1641 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -409,7 +409,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_viewport_scaling", "ex 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", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_screen_buffer", "examples\textures_screen_buffer.vcxproj", "{4E9D2828-EE83-40C8-97E0-137EEDFBAAAD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -5081,30 +5081,30 @@ Global {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 - {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 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5272,7 +5272,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} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {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} @@ -5311,7 +5311,7 @@ Global {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} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {4E9D2828-EE83-40C8-97E0-137EEDFBAAAD} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} From a59012635172150e616524260b068e5e4ff8ffb4 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 19:20:45 +0100 Subject: [PATCH 102/189] Updated some examples --- examples/core/core_custom_logging.c | 8 ++++---- examples/core/core_directory_files.c | 12 ++++-------- examples/core/core_input_gestures.c | 2 ++ examples/core/core_input_gestures_testbed.c | 4 ++-- examples/core/core_input_mouse.c | 10 ++-------- 5 files changed, 14 insertions(+), 22 deletions(-) diff --git a/examples/core/core_custom_logging.c b/examples/core/core_custom_logging.c index 5ea2a4762..b1e7ee989 100644 --- a/examples/core/core_custom_logging.c +++ b/examples/core/core_custom_logging.c @@ -17,11 +17,11 @@ #include "raylib.h" -#include // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen() -#include // Required for: time_t, tm, time(), localtime(), strftime() +#include // Required for: printf(), vprintf(), fprintf() +#include // Required for: time_t, tm, time(), localtime(), strftime() // Custom logging function -void CustomLog(int msgType, const char *text, va_list args) +void CustomTraceLog(int msgType, const char *text, va_list args) { char timeStr[64] = { 0 }; time_t now = time(NULL); @@ -54,7 +54,7 @@ int main(void) const int screenHeight = 450; // Set custom logger - SetTraceLogCallback(CustomLog); + SetTraceLogCallback(CustomTraceLog); InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging"); diff --git a/examples/core/core_directory_files.c b/examples/core/core_directory_files.c index 83a4239d0..a98c950f6 100644 --- a/examples/core/core_directory_files.c +++ b/examples/core/core_directory_files.c @@ -20,9 +20,7 @@ #define RAYGUI_IMPLEMENTATION #include "raygui.h" // Required for GUI controls -#include // Required for: strcpy() - -#define MAX_FILEPATH_SIZE 2048 +#define MAX_FILEPATH_SIZE 1024 //------------------------------------------------------------------------------------ // Program main entry point @@ -53,12 +51,10 @@ int main(void) //---------------------------------------------------------------------------------- if (btnBackPressed) { - strcpy(directory, GetPrevDirectoryPath(directory)); + TextCopy(directory, GetPrevDirectoryPath(directory)); UnloadDirectoryFiles(files); files = LoadDirectoryFiles(directory); } - - //---------------------------------------------------------------------------------- // Draw @@ -68,7 +64,7 @@ int main(void) DrawText(directory, 100, 40, 20, DARKGRAY); - btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<"); + btnBackPressed = GuiButton((Rectangle){ 40.0f, 38.0f, 48, 24 }, "<"); for (int i = 0; i < (int)files.count; i++) { @@ -78,7 +74,7 @@ int main(void) { if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, "")) { - strcpy(directory, files.paths[i]); + TextCopy(directory, files.paths[i]); UnloadDirectoryFiles(files); files = LoadDirectoryFiles(directory); continue; diff --git a/examples/core/core_input_gestures.c b/examples/core/core_input_gestures.c index fd7250658..168e2a0c3 100644 --- a/examples/core/core_input_gestures.c +++ b/examples/core/core_input_gestures.c @@ -118,4 +118,6 @@ int main(void) //-------------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- + + return 0; } \ No newline at end of file diff --git a/examples/core/core_input_gestures_testbed.c b/examples/core/core_input_gestures_testbed.c index f1cdfdbc5..f318ab4a4 100644 --- a/examples/core/core_input_gestures_testbed.c +++ b/examples/core/core_input_gestures_testbed.c @@ -22,9 +22,9 @@ #define GESTURE_LOG_SIZE 20 #define MAX_TOUCH_COUNT 32 -//---------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------ // Module Functions Declaration -//---------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------ static char const *GetGestureName(int gesture); // Get text string for gesture value static Color GetGestureColor(int gesture); // Get color for gesture value diff --git a/examples/core/core_input_mouse.c b/examples/core/core_input_mouse.c index f429018b0..d46106996 100644 --- a/examples/core/core_input_mouse.c +++ b/examples/core/core_input_mouse.c @@ -40,14 +40,8 @@ int main(void) //---------------------------------------------------------------------------------- if (IsKeyPressed(KEY_H)) { - if (IsCursorHidden()) - { - ShowCursor(); - } - else - { - HideCursor(); - } + if (IsCursorHidden()) ShowCursor(); + else HideCursor(); } ballPosition = GetMousePosition(); From cde917c63c7e90fdb3b203aca12e2910d15330d2 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 19:40:23 +0100 Subject: [PATCH 103/189] REXM: ADDED: Build check warnings logs --- tools/rexm/rexm.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 8b0053c20..c294d65e0 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -94,8 +94,9 @@ typedef struct { // Automated testing data typedef struct { - int warnings; // Warnings counter - int status; // Testing status result flags + int buildwarns; // Example building warnings count (by GCC compiler) + int warnings; // Example run output log warnings count + int status; // Example run testing status flags (>0 = FAILS) } rlExampleTesting; // Validation status for a single example @@ -1501,6 +1502,8 @@ int main(int argc, char *argv[]) SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[2]); for (int i = 0; i < 3; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } + MakeDirectory(TextFormat("%s/%s/logs", exBasePath, exCategory)); + // STEP 2: Build example for DESKTOP platform #if defined(_WIN32) // Set required environment variables @@ -1512,7 +1515,8 @@ int main(int argc, char *argv[]) // Build example for PLATFORM_DESKTOP #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); + system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", + exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); @@ -1525,10 +1529,24 @@ int main(int argc, char *argv[]) // STEP 3: Run example with required arguments // NOTE: Not easy to retrieve process return value from system(), it's platform dependant ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); - system(TextFormat("%s --frames 2 > %s.log", exName, exName)); + system(TextFormat("%s --frames 2 > logs/%s.log", exName, exName)); // STEP 4: Load and validate log info - char *exTestLog = LoadFileText(TextFormat("%s/%s/%s.log", exBasePath, exCategory, exName)); + //--------------------------------------------------------------------------------------------- + // Load .build.log to check for compilation warnings + char *exTestBuildLog = LoadFileText(TextFormat("%s/%s/logs/%s.build.log", exBasePath, exCategory, exName)); + int exTestBuildLogLinesCount = 0; + char **exTestBuildLogLines = LoadTextLines(exTestBuildLog, &exTestBuildLogLinesCount); + + for (int k = 0, index = 0; k < exTestBuildLogLinesCount; k++) + { + if (TextFindIndex(exTestBuildLogLines[k], "warning:") >= 0) testing[i].buildwarns++; + } + + UnloadTextLines(exTestBuildLogLines, exTestBuildLogLinesCount); + UnloadFileText(exTestBuildLog); + + char *exTestLog = LoadFileText(TextFormat("%s/%s/logs/%s.log", exBasePath, exCategory, exName)); int exTestLogLinesCount = 0; char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); @@ -1557,6 +1575,8 @@ int main(int argc, char *argv[]) UnloadTextLines(exTestLogLines, exTestLogLinesCount); UnloadFileText(exTestLog); + //--------------------------------------------------------------------------------------------- +#endif } // STEP 5: Generate testing report/table with results (.md) From bbba3d080249d4ef86a486a8cd083b6f77329b60 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 17 Nov 2025 19:40:55 +0100 Subject: [PATCH 104/189] REXM: ADDED: Web platform logs automated reports -WIP- --- tools/rexm/rexm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index c294d65e0..615dbe1c1 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1456,6 +1456,21 @@ int main(int argc, char *argv[]) rlExampleTesting *testing = (rlExampleTesting *)RL_CALLOC(exBuildListCount, sizeof(rlExampleTesting)); +#if defined(_WIN32) + // Set required environment variables + //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); + //_putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); + //putenv("MAKE=mingw32-make"); + //ChangeDirectory(exBasePath); + //_putenv("MAKE_PATH=C:\\raylib\\w64devkit\\bin"); + //_putenv("EMSDK_PATH = C:\\raylib\\emsdk"); + //_putenv("PYTHON_PATH=$(EMSDK_PATH)\\python\\3.9.2-nuget_64bit"); + //_putenv("NODE_PATH=$(EMSDK_PATH)\\node\\20.18.0_64bit\\bin"); + //_putenv("PATH=%PATH%;$(MAKE_PATH);$(EMSDK_PATH);$(NODE_PATH);$(PYTHON_PATH)"); + + _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin;C:\\raylib\\emsdk\\python\\3.9.2-nuget_64bit;C:\\raylib\\emsdk\\node\\20.18.0_64bit\\bin"); +#endif + for (int i = 0; i < exBuildListCount; i++) { // Get example name and category @@ -1474,7 +1489,7 @@ int main(int argc, char *argv[]) // STEP 3: Run example with arguments: --frames 2 > .out.log // STEP 4: Load .out.log and check "WARNING:" messages -> Some could maybe be ignored // STEP 5: Generate report with results - + // STEP 1: Load example and inject required code // PROBLEM: As we need to modify the example source code for building, we need to keep a copy or something // WARNING: If we make a copy and something fails, it could not be restored at the end @@ -1485,6 +1500,71 @@ int main(int argc, char *argv[]) TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); +#define BUILD_TESTING_WEB +#if defined(BUILD_TESTING_WEB) + static const char *mainReplaceText = + "#include \n" + "#include \n" + "#include \n" + "#include \n\n" + "static char logText[1024] = {0};\n" + "static int logTextOffset = 0;\n\n" + "void CustomTraceLog(int msgType, const char *text, va_list args)\n{\n" + " switch (msgType)\n {\n" + " case LOG_INFO: logTextOffset += sprintf(logText + logTextOffset, \"INFO: \"); break;\n" + " case LOG_ERROR: logTextOffset += sprintf(logText + logTextOffset, \"ERROR: \"); break;\n" + " case LOG_WARNING: logTextOffset += sprintf(logText + logTextOffset, \"WARNING: \"); break;\n" + " case LOG_DEBUG: logTextOffset += sprintf(logText + logTextOffset, \"DEBUG: \"); break;\n" + " default: break;\n }\n" + " logTextOffset += vsprintf(logText + logTextOffset, text, args);\n" + " logTextOffset += sprintf(logText + logTextOffset, \"\\n\");\n}\n\n" + "int main(int argc, char *argv[])\n{\n" + " SetTraceLogCallback(CustomTraceLog);\n" + " int requestedTestFrames = 0;\n" + " int testFramesCount = 0;\n" + " if ((argc > 1) && (argc == 3) && (strcmp(argv[1], \"--frames\") != 0)) requestedTestFrames = atoi(argv[2]);\n"; + + static const char *returnReplaceText = + " char outputLogFile[256] = { 0 };\n" + " TextCopy(outputLogFile, GetFileNameWithoutExt(argv[0]));\n" + " SaveFileText(outputLogFile, logText);\n" + " emscripten_run_script(TextFormat(\"saveFileFromMEMFSToDisk('%s','%s')\", outputLogFile, GetFileName(outputLogFile)));\n\n" + " return 0"; + + char *srcTextUpdated[4] = { 0 }; + srcTextUpdated[0] = TextReplace(srcText, "int main(void)\n{", mainReplaceText); + srcTextUpdated[1] = TextReplace(srcTextUpdated[0], "WindowShouldClose()", "WindowShouldClose() && (testFramesCount < requestedTestFrames)"); + srcTextUpdated[2] = TextReplace(srcTextUpdated[1], "EndDrawing();", "EndDrawing(); testFramesCount++;"); + srcTextUpdated[3] = TextReplace(srcTextUpdated[2], " return 0", returnReplaceText); + UnloadFileText(srcText); + + //SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[3]); + for (int i = 0; i < 4; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } + + // Build example for PLATFORM_WEB + // Build: raylib.com/examples//_example_name.html + // Build: raylib.com/examples//_example_name.data + // Build: raylib.com/examples//_example_name.wasm + // Build: raylib.com/examples//_example_name.js +#if defined(_WIN32) + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); + system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); +#else + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); + system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); +#endif + // Restore original source code before continue + FileCopy(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName), + TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); + FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); + + // STEP 3: Run example on browser + ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); + system("start python -m http.server 8080"); + system(TextFormat("start explorer \"http:\\localhost:8080/%s.html", exName)); + +#else // BUILD_TESTING_DESKTOP + static const char *mainReplaceText = "#include \n" "#include \n" From be9a24e68cf32a4cad01148b4dbc734158b4145a Mon Sep 17 00:00:00 2001 From: Serhii Zasenko Date: Tue, 18 Nov 2025 17:17:58 +0200 Subject: [PATCH 105/189] Fix controller not available right after win init (#5358) - Fix IsGamepadAvailable() returns false for an available controller immediately after window initialization --- src/platforms/rcore_desktop_glfw.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index bf383031b..746dc8a3c 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1749,7 +1749,12 @@ int InitPlatform(void) { // 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) - if (glfwJoystickPresent(i)) strncpy(CORE.Input.Gamepad.name[i], glfwGetJoystickName(i), MAX_GAMEPAD_NAME_LENGTH - 1); + if (glfwJoystickPresent(i)) + { + CORE.Input.Gamepad.ready[i] = true; + CORE.Input.Gamepad.axisCount[i] = GLFW_GAMEPAD_AXIS_LAST + 1; + strncpy(CORE.Input.Gamepad.name[i], glfwGetJoystickName(i), MAX_GAMEPAD_NAME_LENGTH - 1); + } } //---------------------------------------------------------------------------- From b18f547d8fd3da129bea7f8e1a0fe10d35f0784d Mon Sep 17 00:00:00 2001 From: MikiZX1 <161243635+MikiZX1@users.noreply.github.com> Date: Tue, 18 Nov 2025 16:19:07 +0100 Subject: [PATCH 106/189] Update rcore_desktop_sdl.c, fix crash when strncpy tries to copy using NULL pointer (#5359) When SDL_GameControllerNameForIndex returns null, the app crashes. This was addressed earlier in PR#4859 though the fix submitted on PR #4859 was only fixing the crashing and not addressing the root cause. --- src/platforms/rcore_desktop_sdl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index cf11037cb..e9686912b 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1723,7 +1723,10 @@ void PollInputEvents(void) CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; memset(CORE.Input.Gamepad.name[nextAvailableSlot], 0, MAX_GAMEPAD_NAME_LENGTH); - strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], SDL_GameControllerNameForIndex(nextAvailableSlot), MAX_GAMEPAD_NAME_LENGTH - 1); + if (SDL_GameControllerNameForIndex(nextAvailableSlot)) + strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], SDL_GameControllerNameForIndex(nextAvailableSlot), MAX_GAMEPAD_NAME_LENGTH - 1); + else + strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], "Noname", 6); } else { From f531ee2d8fe5a53dd57ff236dee6d5299b5ffd95 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 16:19:43 +0100 Subject: [PATCH 107/189] Update rexm.c --- tools/rexm/rexm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 615dbe1c1..5569d511b 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1266,8 +1266,8 @@ int main(int argc, char *argv[]) _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name)); #else - LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->filter); - system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->filter)); + LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exInfo->name); + system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name)); #endif // Update generated .html metadata @@ -1538,7 +1538,7 @@ int main(int argc, char *argv[]) srcTextUpdated[3] = TextReplace(srcTextUpdated[2], " return 0", returnReplaceText); UnloadFileText(srcText); - //SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[3]); + SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[3]); for (int i = 0; i < 4; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } // Build example for PLATFORM_WEB From 95a8977e335809bc87f965db3b76b5476e73fcc1 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 16:28:10 +0100 Subject: [PATCH 108/189] REXM: FIX: Web log redirect and download --- tools/rexm/rexm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 5569d511b..5b33bfbb3 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1507,9 +1507,10 @@ int main(int argc, char *argv[]) "#include \n" "#include \n" "#include \n\n" - "static char logText[1024] = {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" " switch (msgType)\n {\n" " case LOG_INFO: logTextOffset += sprintf(logText + logTextOffset, \"INFO: \"); break;\n" " case LOG_ERROR: logTextOffset += sprintf(logText + logTextOffset, \"ERROR: \"); break;\n" @@ -1517,7 +1518,7 @@ int main(int argc, char *argv[]) " case LOG_DEBUG: logTextOffset += sprintf(logText + logTextOffset, \"DEBUG: \"); break;\n" " default: break;\n }\n" " logTextOffset += vsprintf(logText + logTextOffset, text, args);\n" - " logTextOffset += sprintf(logText + logTextOffset, \"\\n\");\n}\n\n" + " logTextOffset += sprintf(logText + logTextOffset, \"\\n\");\n}\n}\n\n" "int main(int argc, char *argv[])\n{\n" " SetTraceLogCallback(CustomTraceLog);\n" " int requestedTestFrames = 0;\n" @@ -1525,17 +1526,17 @@ int main(int argc, char *argv[]) " if ((argc > 1) && (argc == 3) && (strcmp(argv[1], \"--frames\") != 0)) requestedTestFrames = atoi(argv[2]);\n"; static const char *returnReplaceText = - " char outputLogFile[256] = { 0 };\n" - " TextCopy(outputLogFile, GetFileNameWithoutExt(argv[0]));\n" - " SaveFileText(outputLogFile, logText);\n" - " emscripten_run_script(TextFormat(\"saveFileFromMEMFSToDisk('%s','%s')\", outputLogFile, GetFileName(outputLogFile)));\n\n" + " SaveFileText(\"outputLogFileName\", logText);\n" + " emscripten_run_script(\"saveFileFromMEMFSToDisk('outputLogFileName','outputLogFileName')\");\n\n" " return 0"; + char *returnReplaceTextUpdated = TextReplace(returnReplaceText, "outputLogFileName", TextFormat("%s.log", exName)); char *srcTextUpdated[4] = { 0 }; srcTextUpdated[0] = TextReplace(srcText, "int main(void)\n{", mainReplaceText); srcTextUpdated[1] = TextReplace(srcTextUpdated[0], "WindowShouldClose()", "WindowShouldClose() && (testFramesCount < requestedTestFrames)"); srcTextUpdated[2] = TextReplace(srcTextUpdated[1], "EndDrawing();", "EndDrawing(); testFramesCount++;"); - srcTextUpdated[3] = TextReplace(srcTextUpdated[2], " return 0", returnReplaceText); + srcTextUpdated[3] = TextReplace(srcTextUpdated[2], " return 0", returnReplaceTextUpdated); + MemFree(returnReplaceTextUpdated); UnloadFileText(srcText); SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[3]); From 86e00bde655177f7848eb1ae3101f1e9b505ed72 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 16:30:48 +0100 Subject: [PATCH 109/189] Update rcore_desktop_sdl.c --- src/platforms/rcore_desktop_sdl.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index e9686912b..d6c7fd476 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1723,15 +1723,11 @@ void PollInputEvents(void) CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; CORE.Input.Gamepad.axisState[nextAvailableSlot][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; memset(CORE.Input.Gamepad.name[nextAvailableSlot], 0, MAX_GAMEPAD_NAME_LENGTH); - if (SDL_GameControllerNameForIndex(nextAvailableSlot)) - strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], SDL_GameControllerNameForIndex(nextAvailableSlot), MAX_GAMEPAD_NAME_LENGTH - 1); - else - strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], "Noname", 6); - } - else - { - TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); + const char *controllerName = SDL_GameControllerNameForIndex(nextAvailableSlot); + if (controllerName != NULL) strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], controllerName, MAX_GAMEPAD_NAME_LENGTH - 1); + else strncpy(CORE.Input.Gamepad.name[nextAvailableSlot], "noname", 6); } + else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError()); } } break; case SDL_JOYDEVICEREMOVED: From 4caba49658bf6e662c9fbdc5d8fd056595db7f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Tue, 18 Nov 2025 10:31:43 -0500 Subject: [PATCH 110/189] [examples] Added: `shapes_rlgl_color_wheel` example (#5355) * [examples] Added: `shapes_rlgl_triangle` example * correct name * formatting * Revert "formatting" This reverts commit f1d246a6482afb438d6371c469558729cbabf466. * Revert "correct name" This reverts commit 974985ed495d41323bd879e5ebcc21d80876db37. * Revert "[examples] Added: `shapes_rlgl_triangle` example" This reverts commit d053b9afa0a6f1d2c991f336db22397bb581742d. * [examples] Added: `shapes_rlgl_color_wheel` example * clarify color variable * formatting * formatting * formatting * formatting * reduce redundancy * moved color updating code to update --- examples/shapes/shapes_rlgl_color_wheel.c | 280 ++++++++++++++++++++ examples/shapes/shapes_rlgl_color_wheel.png | Bin 0 -> 68500 bytes 2 files changed, 280 insertions(+) create mode 100644 examples/shapes/shapes_rlgl_color_wheel.c create mode 100644 examples/shapes/shapes_rlgl_color_wheel.png diff --git a/examples/shapes/shapes_rlgl_color_wheel.c b/examples/shapes/shapes_rlgl_color_wheel.c new file mode 100644 index 000000000..323a08956 --- /dev/null +++ b/examples/shapes/shapes_rlgl_color_wheel.c @@ -0,0 +1,280 @@ +/******************************************************************************************* +* +* raylib [shapes] example - rlgl color wheel +* +* Example complexity rating: [★★★☆] 3/4 +* +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev +* +* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025-2025 Robin (@RobinsAviary) +* +********************************************************************************************/ + +#include "raylib.h" +#include "rlgl.h" +#include "raymath.h" +#include +#include + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + // The minimum/maximum points the circle can have + const unsigned int pointsMin = 3; + const unsigned int pointsMax = 256; + + // The current number of points and the radius of the circle + unsigned int triangleCount = 64; + float pointScale = 150.0f; + + // Slider value, literally maps to value in HSV + float value = 1.0f; + + // The center of the screen + Vector2 center = { (float)screenWidth/2.0f, (float)screenHeight/2.0f }; + // The location of the color wheel + Vector2 circlePosition = center; + + // The currently selected color + Color color = { 255, 255, 255, 255 }; + + // Indicates if the slider is being clicked + bool sliderClicked = false; + + // Indicates if the current color going to be updated, as well as the handle position + bool settingColor = false; + + // How the color wheel will be rendered + unsigned int renderType = RL_TRIANGLES; + + // Enable anti-aliasing + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rlgl color wheel"); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + triangleCount += (unsigned int)GetMouseWheelMove(); + triangleCount = (unsigned int)Clamp((float)triangleCount, (float)pointsMin, (float)pointsMax); + + Rectangle sliderRectangle = { 42.0f, 16.0f + 64.0f + 45.0f, 64.0f, 16.0f }; + Vector2 mousePosition = GetMousePosition(); + + // Checks if the user is hovering over the value slider + bool sliderHover = (mousePosition.x >= sliderRectangle.x && mousePosition.y >= sliderRectangle.y && mousePosition.x < sliderRectangle.x + sliderRectangle.width && mousePosition.y < sliderRectangle.y + sliderRectangle.height); + + // Copy color as hex + if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_C)) + { + if (IsKeyPressed(KEY_C)) + { + SetClipboardText(TextFormat("#%02X%02X%02X", color.r, color.g, color.b)); + } + } + + // Scale up the color wheel, adjusting the handle visually + if (IsKeyDown(KEY_UP)) + { + pointScale *= 1.025f; + + if (pointScale > (float)screenHeight/2.0f) + { + pointScale = (float)screenHeight/2.0f; + } + else + { + circlePosition = Vector2Add(Vector2Multiply(Vector2Subtract(circlePosition, center), (Vector2){ 1.025f, 1.025f }), center); + } + } + + // Scale down the wheel, adjusting the handle visually + if (IsKeyDown(KEY_DOWN)) + { + pointScale *= 0.975f; + + if (pointScale < 32.0f) + { + pointScale = 32.0f; + } + else + { + circlePosition = Vector2Add(Vector2Multiply(Vector2Subtract(circlePosition, center), (Vector2){ 0.975f, 0.975f }), center); + } + + float distance = Vector2Distance(center, circlePosition)/pointScale; + float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f) / 2.0f); + + if (distance > 1.0f) + { + circlePosition = Vector2Add((Vector2){ sinf(angle*(PI * 2.0f)) * pointScale, -cosf(angle*(PI*2.0f))*pointScale }, center); + } + } + + // Checks if the user clicked on the color wheel + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && Vector2Distance(GetMousePosition(), center) <= pointScale + 10.0f) + { + settingColor = true; + } + + // Update flag when mouse button is released + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) settingColor = false; + + // Check if the user clicked/released the slider for the color's value + if (sliderHover && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) sliderClicked = true; + + if (sliderClicked && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) sliderClicked = false; + + // Update render mode accordingly + if (IsKeyPressed(KEY_SPACE)) renderType = RL_LINES; + + if (IsKeyReleased(KEY_SPACE)) renderType = RL_TRIANGLES; + + // If the slider or the wheel was clicked, update the current color + if (settingColor || sliderClicked) + { + if (settingColor) { + circlePosition = GetMousePosition(); + } + + float distance = Vector2Distance(center, circlePosition) / pointScale; + + float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f)/2.0f); + if (settingColor && distance > 1.0f) { + circlePosition = Vector2Add((Vector2){ sinf(angle*(PI*2.0f))*pointScale, -cosf(angle*(PI* 2.0f))*pointScale }, center); + } + + float angle360 = angle*360.0f; + + float valueActual = Clamp(distance, 0.0f, 1.0f); + + color = ColorLerp((Color){ (int)(value*255.0f), (int)(value*255.0f), (int)(value*255.0f), 255 }, ColorFromHSV(angle360, Clamp(distance, 0.0f, 1.0f), 1.0f), valueActual); + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Begin rendering color wheel + rlBegin(renderType); + for (unsigned int i = 0; i < triangleCount; i++) + { + float angleOffset = ((PI*2.0f)/(float)triangleCount); + float angle = angleOffset*(float)i; + float angleOffsetCalculated = ((float)i + 1)*angleOffset; + Vector2 scale = (Vector2){ pointScale, pointScale }; + + Vector2 offset = Vector2Multiply((Vector2){ sinf(angle), -cosf(angle) }, scale); + Vector2 offset2 = Vector2Multiply((Vector2){ sinf(angleOffsetCalculated), -cosf(angleOffsetCalculated) }, scale); + + Vector2 position = Vector2Add(center, offset); + Vector2 position2 = Vector2Add(center, offset2); + + float angleNonRadian = (angle/(2.0f*PI))*360.0f; + float angleNonRadianOffset = (angleOffset/(2.0f*PI))*360.0f; + + Color currentColor = ColorFromHSV(angleNonRadian, 1.0f, 1.0f); + Color offsetColor = ColorFromHSV(angleNonRadian + angleNonRadianOffset, 1.0f, 1.0f); + + // Input vertices differently depending on mode + if (renderType == RL_TRIANGLES) + { + // RL_TRIANGLES expects three vertices per triangle + rlColor4ub(currentColor.r, currentColor.g, currentColor.b, currentColor.a); + rlVertex2f(position.x, position.y); + rlColor4f(value, value, value, 1.0f); + rlVertex2f(center.x, center.y); + rlColor4ub(offsetColor.r, offsetColor.g, offsetColor.b, offsetColor.a); + rlVertex2f(position2.x, position2.y); + } + else if (renderType == RL_LINES) + { + // RL_LINES expects two vertices per line + rlColor4ub(currentColor.r, currentColor.g, currentColor.b, currentColor.a); + rlVertex2f(position.x, position.y); + rlColor4ub(WHITE.r, WHITE.g, WHITE.b, WHITE.a); + rlVertex2f(center.x, center.y); + + rlVertex2f(center.x, center.y); + rlColor4ub(offsetColor.r, offsetColor.g, offsetColor.b, offsetColor.a); + rlVertex2f(position2.x, position2.y); + + rlVertex2f(position2.x, position2.y); + rlColor4ub(currentColor.r, currentColor.g, currentColor.b, currentColor.a); + rlVertex2f(position.x, position.y); + } + } + rlEnd(); + + // Make the handle slightly more visible overtop darker colors + Color handleColor = BLACK; + + if (Vector2Distance(center, circlePosition)/pointScale <= 0.5f && value <= 0.5f) + { + handleColor = DARKGRAY; + } + + // Draw the color handle + DrawCircleLinesV(circlePosition, 4.0f, handleColor); + + // Draw the color in a preview, with a darkened outline. + DrawRectangleV((Vector2){ 8.0f, 8.0f }, (Vector2){ 64.0f, 64.0f }, color); + DrawRectangleLinesEx((Rectangle){ 8.0f, 8.0f, 64.0f, 64.0f }, 2.0f, ColorLerp(color, BLACK, 0.5f)); + + // Draw current color as hex and decimal + DrawText(TextFormat("#%02X%02X%02X\n(%d, %d, %d)", color.r, color.g, color.b, color.r, color.g, color.b), 8, 8 + 64 + 8, 20, DARKGRAY); + + // Update the visuals for the copying text + Color copyColor = DARKGRAY; + unsigned int offset = 0; + if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_C)) + { + copyColor = DARKGREEN; + offset = 4; + } + + // Draw the copying text + DrawText("press ctrl+c to copy!", 8, 425 - offset, 20, copyColor); + + // Display the number of rendered triangles + DrawText(TextFormat("triangle count: %d", triangleCount), 8, 395, 20, DARKGRAY); + + // Slider to change color's value + GuiSliderBar(sliderRectangle, "value: ", "", &value, 0.0f, 1.0f); + + // Draw FPS next to outlined color preview + DrawFPS(64 + 16, 8); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/shapes/shapes_rlgl_color_wheel.png b/examples/shapes/shapes_rlgl_color_wheel.png new file mode 100644 index 0000000000000000000000000000000000000000..43344da5961248739620a6833fc134f27cd73e72 GIT binary patch literal 68500 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 literal 0 HcmV?d00001 From 9efe127f5d10a5da66b9ba6ab5cfaad243d98e5a Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 19:50:07 +0100 Subject: [PATCH 111/189] Update shapes_lines_drawing.c --- examples/shapes/shapes_lines_drawing.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/examples/shapes/shapes_lines_drawing.c b/examples/shapes/shapes_lines_drawing.c index aeaae3d45..16f59884d 100644 --- a/examples/shapes/shapes_lines_drawing.c +++ b/examples/shapes/shapes_lines_drawing.c @@ -51,6 +51,8 @@ int main(void) BeginTextureMode(canvas); ClearBackground(backgroundColor); EndTextureMode(); + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -59,10 +61,7 @@ int main(void) // Update //---------------------------------------------------------------------------------- // Disable the hint text once the user clicks - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText) - { - startText = false; - } + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText) startText = false; // Clear the canvas when the user middle-clicks if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) @@ -79,7 +78,7 @@ int main(void) if (leftButtonDown || rightButtonDown) { // The color for the line - Color drawColor; + Color drawColor = WHITE; if (leftButtonDown) { @@ -88,10 +87,7 @@ int main(void) // While the hue is >=360, subtract it to bring it down into the range 0-360 // This is more visually accurate than resetting to zero - while (lineHue >= 360.0f) - { - lineHue -= 360.0f; - } + while (lineHue >= 360.0f) lineHue -= 360.0f; // Create the final color drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f); @@ -104,10 +100,12 @@ int main(void) // Draw the line onto the canvas BeginTextureMode(canvas); + // Circles act as "caps", smoothing corners DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor); DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor); DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor); + EndTextureMode(); } From a4a6812d68702866d852f11cbbce0810a1e0e194 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 19:50:45 +0100 Subject: [PATCH 112/189] REXM: REVIEWED: Testing report generation --- tools/rexm/rexm.c | 67 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 5b33bfbb3..1e67dffe9 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1479,6 +1479,11 @@ int main(int argc, char *argv[]) memset(exCategory, 0, 32); strncpy(exCategory, exName, TextFindIndex(exName, "_")); + // Skip some examples from building + if ((strcmp(exName, "others") == 0) || + (strcmp(exName, "core_custom_logging") == 0) || + (strcmp(exName, "core_window_should_close") == 0)) continue; + LOG("INFO: [%i/%i] Testing example: [%s]\n", i + 1, exBuildListCount, exName); // Steps to follow @@ -1500,7 +1505,7 @@ int main(int argc, char *argv[]) TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); -#define BUILD_TESTING_WEB +//#define BUILD_TESTING_WEB #if defined(BUILD_TESTING_WEB) static const char *mainReplaceText = "#include \n" @@ -1549,7 +1554,7 @@ int main(int argc, char *argv[]) // Build: raylib.com/examples//_example_name.js #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); + system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); @@ -1561,9 +1566,11 @@ int main(int argc, char *argv[]) // STEP 3: Run example on browser ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); - system("start python -m http.server 8080"); + system("start python -m http.server 8080"); // TODO: Init localhost just once! system(TextFormat("start explorer \"http:\\localhost:8080/%s.html", exName)); + // NOTE: Example .log is automatically downloaded into system Downloads directory on browser-example exectution + #else // BUILD_TESTING_DESKTOP static const char *mainReplaceText = @@ -1621,6 +1628,7 @@ int main(int argc, char *argv[]) for (int k = 0, index = 0; k < exTestBuildLogLinesCount; k++) { + // Checking compilation warnings generated if (TextFindIndex(exTestBuildLogLines[k], "warning:") >= 0) testing[i].buildwarns++; } @@ -1664,7 +1672,8 @@ int main(int argc, char *argv[]) //----------------------------------------------------------------------------------------------------- /* Columns: - - [WARN] : WARNING messages count + - [CWARN] : Compilation WARNING messages + - [LWARN] : Log WARNING messages count - [INIT] : Initialization - [CLOSE] : Closing - [ASSETS] : Assets loading @@ -1673,9 +1682,9 @@ int main(int argc, char *argv[]) - [FONT] : Font default initialization - [TIMER] : Timer initialization - | **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | - |:---------------------------------|:------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| - | core_basic window | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | + | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | + |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| + | core_basic window | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | */ LOG("INFO: [examples_testing.md] Generating examples testing report...\n"); @@ -1695,8 +1704,8 @@ int main(int argc, char *argv[]) repIndex += sprintf(report + repIndex, " - [FONT] : Font default initialization\n"); repIndex += sprintf(report + repIndex, " - [TIMER] : Timer initialization\n```\n"); - repIndex += sprintf(report + repIndex, "| **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] |\n"); - repIndex += sprintf(report + repIndex, "|:---------------------------------|:------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:|\n"); + repIndex += sprintf(report + repIndex, "| **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] |\n"); + repIndex += sprintf(report + repIndex, "|:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:|\n"); /* TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" @@ -1709,23 +1718,41 @@ int main(int argc, char *argv[]) */ for (int i = 0; i < exBuildListCount; i++) { - if (testing[i].status > 0) + if ((testing[i].buildwarns > 0) || (testing[i].warnings > 0) || (testing[i].status > 0)) { - repIndex += sprintf(report + repIndex, "| %-32s | %i | %s | %s | %s | %s | %s | %s | %s |\n", - exBuildList[i], testing[i].warnings, - (testing[i].status & TESTING_FAIL_INIT)? "✔" : "❌", - (testing[i].status & TESTING_FAIL_CLOSE)? "✔" : "❌", - (testing[i].status & TESTING_FAIL_ASSETS)? "✔" : "❌", - (testing[i].status & TESTING_FAIL_RLGL)? "✔" : "❌", - (testing[i].status & TESTING_FAIL_PLATFORM)? "✔" : "❌", - (testing[i].status & TESTING_FAIL_FONT)? "✔" : "❌", - (testing[i].status & TESTING_FAIL_TIMER)? "✔" : "❌"); + repIndex += sprintf(report + repIndex, "| %-32s | %i | %i | %s | %s | %s | %s | %s | %s | %s |\n", + exBuildList[i], + testing[i].buildwarns, + testing[i].warnings, + (testing[i].status & TESTING_FAIL_INIT)? "❌" : "✔", + (testing[i].status & TESTING_FAIL_CLOSE)? "❌" : "✔", + (testing[i].status & TESTING_FAIL_ASSETS)? "❌" : "✔", + (testing[i].status & TESTING_FAIL_RLGL)? "❌" : "✔", + (testing[i].status & TESTING_FAIL_PLATFORM)? "❌" : "✔", + (testing[i].status & TESTING_FAIL_FONT)? "❌" : "✔", + (testing[i].status & TESTING_FAIL_TIMER)? "❌" : "✔"); } } repIndex += sprintf(report + repIndex, "\n"); - SaveFileText(TextFormat("%s/../tools/rexm/reports/%s", exBasePath, "examples_testing_windows.md"), report); +#if defined(PLATFORM_DRM) + const char *osName = "drm"; +#elif defined(PLATFORM_WEB) + const char *osName = "web"; +#elif defined(PLATFORM_DESKTOP) + #if defined(_WIN32) + const char *osName = "windows"; + #elif defined(__linux__) + const char *osName = "linux"; + #elif defined(__FreeBSD__) + const char *osName = "freebsd"; + #elif defined(__APPLE__) + const char *osName = "macos"; + #endif // Desktop OSs +#endif + SaveFileText(TextFormat("%s/../tools/rexm/reports/examples_testing_%s.md", exBasePath, osName), report); + RL_FREE(report); //----------------------------------------------------------------------------------------------------- From 6993bc7337fd690c8bda29a0a69203be3290ee3c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 19:51:34 +0100 Subject: [PATCH 113/189] Update examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index c9ac48a9f..07085d39e 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -13,8 +13,16 @@ Example automated testing elements validated: - [FONT] : Font default initialization - [TIMER] : Timer initialization ``` -| **EXAMPLE NAME** | [WARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | -|:---------------------------------|:------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| -| core_custom_logging | 0 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| core_custom_frame_control | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✔ | +| **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | +|:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| shapes_recursive_tree | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_ring_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_circle_sector_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rounded_rectangle_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_splines_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_digital_clock | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_triangle_strip | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_pie_chart | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_math_sine_cosine | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_lines_drawing | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | From dcc9e961481b5254d7ded360e7702699e07a53e8 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:18:17 +0100 Subject: [PATCH 114/189] Update rexm.c --- tools/rexm/rexm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 1e67dffe9..e25081303 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -415,12 +415,17 @@ int main(int argc, char *argv[]) else { // Support building/testing not only individual examples but multiple: ALL/ - rlExampleInfo *exBuildListInfo = LoadExampleData(argv[2], false, &exBuildListCount); + int exBuildListInfoCount = 0; + rlExampleInfo *exBuildListInfo = LoadExampleData(argv[2], false, &exBuildListInfoCount); - for (int i = 0; i < exBuildListCount; i++) + for (int i = 0; i < exBuildListInfoCount; i++) { - exBuildList[i] = (char *)RL_CALLOC(256, sizeof(char)); - strcpy(exBuildList[i], exBuildListInfo[i].name); + if (!TextIsEqual(exBuildListInfo[i].category, "others")) + { + exBuildList[exBuildListCount] = (char *)RL_CALLOC(256, sizeof(char)); + strcpy(exBuildList[exBuildListCount], exBuildListInfo[i].name); + exBuildListCount++; + } } UnloadExampleData(exBuildListInfo); From e062e3835e0ccdaf8a4a3956f7d36248f026de04 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:43:58 +0100 Subject: [PATCH 115/189] REVIEWED: examples: Several minor issues --- examples/models/models_loading_vox.c | 72 ++++++++----------- examples/models/models_point_rendering.c | 22 +++--- examples/shaders/shaders_lightmap_rendering.c | 36 +++++----- examples/textures/textures_tiled_drawing.c | 12 ++-- 4 files changed, 60 insertions(+), 82 deletions(-) diff --git a/examples/models/models_loading_vox.c b/examples/models/models_loading_vox.c index 956c181a0..6675f3fd7 100644 --- a/examples/models/models_loading_vox.c +++ b/examples/models/models_loading_vox.c @@ -67,7 +67,7 @@ int main(void) models[i] = LoadModel(voxFileNames[i]); double t1 = GetTime()*1000.0; - TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0)); + TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0)); // Compute model translation matrix to center model on draw position (0, 0 , 0) BoundingBox bb = GetModelBoundingBox(models[i]); @@ -80,6 +80,8 @@ int main(void) } int currentModel = 0; + Vector3 modelpos = { 0 }; + Vector3 camerarot = { 0 }; // Load voxel shader Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION), @@ -98,11 +100,7 @@ int main(void) // Assign out lighting shader to model for (int i = 0; i < MAX_VOX_FILES; i++) { - Model m = models[i]; - for (int j = 0; j < m.materialCount; j++) - { - m.materials[j].shader = shader; - } + for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader; } // Create lights @@ -112,12 +110,8 @@ int main(void) lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader); lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader); - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- - Vector3 modelpos = { 0 }; - Vector3 camerarot = { 0 }; // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key @@ -137,15 +131,11 @@ int main(void) } UpdateCameraPro(&camera, - (Vector3) { - (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, - (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, - 0.0f // Move up-down - }, - camerarot, - GetMouseWheelMove()*-2.0f); // Move to target (zoom) + (Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward + (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left + 0.0f }, // Move up-down + camerarot, // Camera rotation + GetMouseWheelMove()*-2.0f); // Move to target (zoom) // Cycle between models on mouse click if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES; @@ -156,36 +146,34 @@ int main(void) // Update light values (actually, only enable/disable them) for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]); - //---------------------------------------------------------------------------------- + // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(RAYWHITE); + ClearBackground(RAYWHITE); - // Draw 3D model - BeginMode3D(camera); + // Draw 3D model + BeginMode3D(camera); + DrawModel(models[currentModel], modelpos, 1.0f, WHITE); + DrawGrid(10, 1.0); - DrawModel(models[currentModel], modelpos, 1.0f, WHITE); - DrawGrid(10, 1.0); + // Draw spheres to show where the lights are + for (int i = 0; i < MAX_LIGHTS; i++) + { + if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color); + else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f)); + } + EndMode3D(); - // Draw spheres to show where the lights are - for (int i = 0; i < MAX_LIGHTS; i++) - { - if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color); - else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f)); - } - - EndMode3D(); - - // Display info - DrawRectangle(10, 400, 340, 60, Fade(SKYBLUE, 0.5f)); - DrawRectangleLines(10, 400, 340, 60, Fade(DARKBLUE, 0.5f)); - DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE); - DrawText("MOUSE MIDDLE BUTTON to ZOOM OR ROTATE CAMERA", 40, 420, 10, BLUE); - DrawText("UP-DOWN-LEFT-RIGHT KEYS to MOVE CAMERA", 40, 430, 10, BLUE); - DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY); + // Display info + DrawRectangle(10, 40, 340, 70, Fade(SKYBLUE, 0.5f)); + DrawRectangleLines(10, 40, 340, 70, Fade(DARKBLUE, 0.5f)); + DrawText("- MOUSE LEFT BUTTON: CYCLE VOX MODELS", 20, 50, 10, BLUE); + DrawText("- MOUSE MIDDLE BUTTON: ZOOM OR ROTATE CAMERA", 20, 70, 10, BLUE); + DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE); + DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY); EndDrawing(); //---------------------------------------------------------------------------------- @@ -201,5 +189,3 @@ int main(void) return 0; } - - diff --git a/examples/models/models_point_rendering.c b/examples/models/models_point_rendering.c index ebfad5ac1..71b907225 100644 --- a/examples/models/models_point_rendering.c +++ b/examples/models/models_point_rendering.c @@ -57,7 +57,7 @@ int main(void) Mesh mesh = GenMeshPoints(numPoints); Model model = LoadModelFromMesh(mesh); - //SetTargetFPS(60); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -92,15 +92,12 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); + ClearBackground(BLACK); BeginMode3D(camera); - // The new method only uploads the points once to the GPU - if (useDrawModelPoints) - { - DrawModelPoints(model, position, 1.0f, WHITE); - } + if (useDrawModelPoints) DrawModelPoints(model, position, 1.0f, WHITE); else { // The old method must continually draw the "points" (lines) @@ -124,17 +121,16 @@ int main(void) // Draw a unit sphere for reference DrawSphereWires(position, 1.0f, 10, 10, YELLOW); - EndMode3D(); // Draw UI text - DrawText(TextFormat("Point Count: %d", numPoints), 20, screenHeight - 50, 40, WHITE); - DrawText("Up - increase points", 20, 70, 20, WHITE); - DrawText("Down - decrease points", 20, 100, 20, WHITE); - DrawText("Space - drawing function", 20, 130, 20, WHITE); + DrawText(TextFormat("Point Count: %d", numPoints), 10, screenHeight - 50, 40, WHITE); + DrawText("UP - Increase points", 10, 40, 20, WHITE); + DrawText("DOWN - Decrease points", 10, 70, 20, WHITE); + DrawText("SPACE - Drawing function", 10, 100, 20, WHITE); - if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 20, 160, 20, GREEN); - else DrawText("Using: DrawPoint3D()", 20, 160, 20, RED); + if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 10, 130, 20, GREEN); + else DrawText("Using: DrawPoint3D()", 10, 130, 20, RED); DrawFPS(10, 10); diff --git a/examples/shaders/shaders_lightmap_rendering.c b/examples/shaders/shaders_lightmap_rendering.c index e269aada2..51651cfd3 100644 --- a/examples/shaders/shaders_lightmap_rendering.c +++ b/examples/shaders/shaders_lightmap_rendering.c @@ -33,7 +33,7 @@ #define GLSL_VERSION 100 #endif -#define MAP_SIZE 10 +#define MAP_SIZE 16 //------------------------------------------------------------------------------------ // Program main entry point @@ -88,8 +88,6 @@ int main(void) RenderTexture lightmap = LoadRenderTexture(MAP_SIZE, MAP_SIZE); - SetTextureFilter(lightmap.texture, TEXTURE_FILTER_TRILINEAR); - Material material = LoadMaterialDefault(); material.shader = shader; material.maps[MATERIAL_MAP_ALBEDO].texture = texture; @@ -103,29 +101,33 @@ int main(void) DrawTexturePro( light, (Rectangle){ 0, 0, (float)light.width, (float)light.height }, - (Rectangle){ 0, 0, 20, 20 }, - (Vector2){ 10.0, 10.0 }, + (Rectangle){ 0, 0, 2.0f*MAP_SIZE, 2.0f*MAP_SIZE }, + (Vector2){ (float)MAP_SIZE, (float)MAP_SIZE }, 0.0, RED ); DrawTexturePro( light, (Rectangle){ 0, 0, (float)light.width, (float)light.height }, - (Rectangle){ 8, 4, 20, 20 }, - (Vector2){ 10.0, 10.0 }, + (Rectangle){ (float)MAP_SIZE*0.8f, (float)MAP_SIZE/2.0f, 2.0f*MAP_SIZE, 2.0f*MAP_SIZE }, + (Vector2){ (float)MAP_SIZE, (float)MAP_SIZE }, 0.0, BLUE ); DrawTexturePro( light, (Rectangle){ 0, 0, (float)light.width, (float)light.height }, - (Rectangle){ 8, 8, 10, 10 }, - (Vector2){ 5.0, 5.0 }, + (Rectangle){ (float)MAP_SIZE*0.8f, (float)MAP_SIZE*0.8f, (float)MAP_SIZE, (float)MAP_SIZE }, + (Vector2){ (float)MAP_SIZE/2.0f, (float)MAP_SIZE/2.0f }, 0.0, GREEN ); BeginBlendMode(BLEND_ALPHA); EndTextureMode(); + + // NOTE: To enable trilinear filtering we need mipmaps available for texture + GenTextureMipmaps(&lightmap.texture); + SetTextureFilter(lightmap.texture, TEXTURE_FILTER_TRILINEAR); SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -141,24 +143,20 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); + ClearBackground(RAYWHITE); BeginMode3D(camera); DrawMesh(mesh, material, MatrixIdentity()); EndMode3D(); - DrawFPS(10, 10); - - DrawTexturePro( - lightmap.texture, - (Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE }, + DrawTexturePro(lightmap.texture, (Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE }, (Rectangle){ (float)GetRenderWidth() - MAP_SIZE*8 - 10, 10, (float)MAP_SIZE*8, (float)MAP_SIZE*8 }, - (Vector2){ 0.0, 0.0 }, - 0.0, - WHITE); + (Vector2){ 0.0, 0.0 }, 0.0, WHITE); - DrawText("lightmap", GetRenderWidth() - 66, 16 + MAP_SIZE*8, 10, GRAY); - DrawText("10x10 pixels", GetRenderWidth() - 76, 30 + MAP_SIZE*8, 10, GRAY); + DrawText(TextFormat("LIGHTMAP: %ix%i pixels", MAP_SIZE, MAP_SIZE), GetRenderWidth() - 130, 20 + MAP_SIZE*8, 10, GREEN); + + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/textures/textures_tiled_drawing.c b/examples/textures/textures_tiled_drawing.c index 10bcad1ad..39a168850 100644 --- a/examples/textures/textures_tiled_drawing.c +++ b/examples/textures/textures_tiled_drawing.c @@ -40,7 +40,7 @@ int main(void) // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) Texture texPattern = LoadTexture("resources/patterns.png"); - SetTextureFilter(texPattern, TEXTURE_FILTER_TRILINEAR); // Makes the texture smoother when upscaled + SetTextureFilter(texPattern, TEXTURE_FILTER_BILINEAR); // Makes the texture smoother when upscaled // Coordinates for all patterns inside the texture const Rectangle recPattern[] = { @@ -110,19 +110,17 @@ int main(void) } } - // Handle keys - - // Change scale + // Handle keys: change scale if (IsKeyPressed(KEY_UP)) scale += 0.25f; if (IsKeyPressed(KEY_DOWN)) scale -= 0.25f; if (scale > 10.0f) scale = 10.0f; else if ( scale <= 0.0f) scale = 0.25f; - // Change rotation + // Handle keys: change rotation if (IsKeyPressed(KEY_LEFT)) rotation -= 25.0f; if (IsKeyPressed(KEY_RIGHT)) rotation += 25.0f; - // Reset + // Handle keys: reset if (IsKeyPressed(KEY_SPACE)) { rotation = 0.0f; scale = 1.0f; } //---------------------------------------------------------------------------------- @@ -165,7 +163,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - UnloadTexture(texPattern); // Unload texture + UnloadTexture(texPattern); // Unload texture CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- From 6f4f4cc508e8b9b732f0e535973de054b4492d4c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:44:23 +0100 Subject: [PATCH 116/189] Update rexm.c --- tools/rexm/rexm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index e25081303..42f32ab47 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1485,9 +1485,9 @@ int main(int argc, char *argv[]) strncpy(exCategory, exName, TextFindIndex(exName, "_")); // Skip some examples from building - if ((strcmp(exName, "others") == 0) || - (strcmp(exName, "core_custom_logging") == 0) || - (strcmp(exName, "core_window_should_close") == 0)) continue; + if ((strcmp(exName, "core_custom_logging") == 0) || + (strcmp(exName, "core_window_should_close") == 0) || + (strcmp(exName, "core_custom_frame_control") == 0)) continue; LOG("INFO: [%i/%i] Testing example: [%s]\n", i + 1, exBuildListCount, exName); From 5da90172ac5a8bc0b9037c625a3856f4e9a644ef Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:49:21 +0100 Subject: [PATCH 117/189] Update examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index 07085d39e..8eb14257a 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -15,6 +15,10 @@ Example automated testing elements validated: ``` | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| core_input_actions | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_directory_files | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_clipboard_text | 5 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_compute_hash | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_recursive_tree | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_ring_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_circle_sector_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -24,5 +28,9 @@ Example automated testing elements validated: | shapes_triangle_strip | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_pie_chart | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_math_sine_cosine | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_lines_drawing | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | +| text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_font_sdf | 0 | 73 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_inline_styling | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | From 95d58ed988747ac1f33b85195db82de2d0304bde Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:52:05 +0100 Subject: [PATCH 118/189] Update examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index 8eb14257a..37c50a486 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -4,7 +4,8 @@ ``` Example automated testing elements validated: - - [WARN] : WARNING messages count + - [CWARN] : Compilation WARNING messages + - [LWARN] : Log WARNING messages count - [INIT] : Initialization - [CLOSE] : Closing - [ASSETS] : Assets loading From 8455f9d088ea46014d295f8f4f6870e26faaf282 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:59:33 +0100 Subject: [PATCH 119/189] Update rexm.c --- tools/rexm/rexm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 42f32ab47..20ceadb91 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1700,7 +1700,8 @@ int main(int argc, char *argv[]) repIndex += sprintf(report + repIndex, "## Tested Platform: Windows\n\n"); repIndex += sprintf(report + repIndex, "```\nExample automated testing elements validated:\n"); - repIndex += sprintf(report + repIndex, " - [WARN] : WARNING messages count\n"); + repIndex += sprintf(report + repIndex, " - [CWARN] : Compilation WARNING messages\n"); + repIndex += sprintf(report + repIndex, " - [LWARN] : Log WARNING messages count\n"); repIndex += sprintf(report + repIndex, " - [INIT] : Initialization\n"); repIndex += sprintf(report + repIndex, " - [CLOSE] : Closing\n"); repIndex += sprintf(report + repIndex, " - [ASSETS] : Assets loading\n"); From f3393b8fd85cabff2ce6d0207eeb56751edc9927 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:59:38 +0100 Subject: [PATCH 120/189] Update core_clipboard_text.c --- examples/core/core_clipboard_text.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/core/core_clipboard_text.c b/examples/core/core_clipboard_text.c index 895c235da..2f8e5712b 100644 --- a/examples/core/core_clipboard_text.c +++ b/examples/core/core_clipboard_text.c @@ -41,7 +41,7 @@ int main(void) "Copy and paste me!" }; - char *clipboardText = NULL; + const char *clipboardText = NULL; char inputBuffer[256] = "Hello from raylib!"; // Random initial string // UI required variables @@ -144,7 +144,7 @@ int main(void) GuiSetState(STATE_DISABLED); GuiLabel((Rectangle){ 50, 260, 700, 40 }, "Clipboard current text data:"); GuiSetStyle(TEXTBOX, TEXT_READONLY, 1); - GuiTextBox((Rectangle){ 50, 300, 700, 40 }, clipboardText, 256, false); + GuiTextBox((Rectangle){ 50, 300, 700, 40 }, (char *)clipboardText, 256, false); GuiSetStyle(TEXTBOX, TEXT_READONLY, 0); GuiLabel((Rectangle){ 50, 360, 700, 40 }, "Try copying text from other applications and pasting here!"); GuiSetState(STATE_NORMAL); From 46ca641ec50df8392f571746feef4a3e94f6318a Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 20:59:48 +0100 Subject: [PATCH 121/189] Update raygui to avoid warnings --- examples/core/raygui.h | 6 +- examples/shaders/raygui.h | 961 ++++++++++++++++++++++++-------------- examples/shapes/raygui.h | 135 +++--- 3 files changed, 667 insertions(+), 435 deletions(-) diff --git a/examples/core/raygui.h b/examples/core/raygui.h index 2bd65e478..f86247ac4 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -3026,9 +3026,9 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int // 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) + #if !defined(RAYGUI_VALUEBOX_MAX_CHARS) #define RAYGUI_VALUEBOX_MAX_CHARS 32 - //#endif + #endif int result = 0; GuiState state = guiState; @@ -3087,7 +3087,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in } // Add new digit to text value - if ((keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) + if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) { int key = GetCharPressed(); diff --git a/examples/shaders/raygui.h b/examples/shaders/raygui.h index a3fc51f0f..f86247ac4 100644 --- a/examples/shaders/raygui.h +++ b/examples/shaders/raygui.h @@ -4,7 +4,7 @@ * * 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. +* available as a standalone library, as long as input and drawing functions are provided * * FEATURES: * - Immediate-mode gui, minimal retained data @@ -27,7 +27,7 @@ * - 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). +* by default any previously loaded font (texture, recs, glyphs) * - Global UI alpha (guiAlpha) is applied inside GuiDrawRectangle() and GuiDrawText() functions * * CONTROLS PROVIDED: @@ -65,7 +65,7 @@ * - 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). +* It also provides a set of functions for styling the controls based on its properties (size, color) * * * RAYGUI STYLE (guiStyle): @@ -77,11 +77,11 @@ * * static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)]; * -* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB +* 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. +* 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) @@ -100,7 +100,7 @@ * 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. +* 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: * @@ -112,20 +112,20 @@ * * 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. +* 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. +* 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 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). +* 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) @@ -141,12 +141,17 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 4.5-dev (Sep-2024) Current dev version... +* 5.0 (xx-Nov-2025) 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 +* 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 @@ -156,6 +161,8 @@ * 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 * @@ -259,16 +266,16 @@ * 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. +* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria +* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria +* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria * * DEPENDENCIES: -* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing +* 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. +* 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: * @@ -309,7 +316,7 @@ * * LICENSE: zlib/libpng * -* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) +* Copyright (c) 2014-2025 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -334,7 +341,7 @@ #define RAYGUI_VERSION_MAJOR 4 #define RAYGUI_VERSION_MINOR 5 #define RAYGUI_VERSION_PATCH 0 -#define RAYGUI_VERSION "4.5-dev" +#define RAYGUI_VERSION "5.0-dev" #if !defined(RAYGUI_STANDALONE) #include "raylib.h" @@ -358,17 +365,6 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// Allow custom memory allocators -#ifndef RAYGUI_MALLOC - #define RAYGUI_MALLOC(sz) malloc(sz) -#endif -#ifndef RAYGUI_CALLOC - #define RAYGUI_CALLOC(n,sz) calloc(n,sz) -#endif -#ifndef RAYGUI_FREE - #define RAYGUI_FREE(p) free(p) -#endif - // Simple log system to avoid printf() calls if required // NOTE: Avoiding those calls, also avoids const strings memory usage #define RAYGUI_SUPPORT_LOG_INFO @@ -421,13 +417,16 @@ // TODO: Texture2D type is very coupled to raylib, required by Font type // It should be redesigned to be provided by user - typedef struct Texture2D { + 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) - } Texture2D; + } Texture; + + // Texture2D, same as Texture + typedef Texture Texture2D; // Image, pixel data stored in CPU memory (RAM) typedef struct Image { @@ -527,7 +526,7 @@ typedef enum { DROPDOWNBOX, TEXTBOX, // Used also for: TEXTBOXMULTI VALUEBOX, - SPINNER, // Uses: BUTTON, VALUEBOX + CONTROL11, LISTVIEW, COLORPICKER, SCROLLBAR, @@ -549,12 +548,12 @@ typedef enum { BORDER_COLOR_DISABLED, // Control border color in STATE_DISABLED BASE_COLOR_DISABLED, // Control base color in STATE_DISABLED TEXT_COLOR_DISABLED, // Control text color in STATE_DISABLED - BORDER_WIDTH, // Control border size, 0 for no border + 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, // Control text padding, not considering border - TEXT_ALIGNMENT, // Control text horizontal alignment inside control text bound (after border and padding) + //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; @@ -641,11 +640,14 @@ typedef enum { TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable } GuiTextBoxProperty; -// Spinner +// ValueBox/Spinner typedef enum { - SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width - SPIN_BUTTON_SPACING, // Spinner buttons separation -} GuiSpinnerProperty; + SPINNER_BUTTON_WIDTH = 16, // Spinner left/right buttons width + SPINNER_BUTTON_SPACING, // Spinner buttons separation +} GuiValueBoxProperty; + +// Control11 +//typedef enum { } GuiControl11Property; // ListView typedef enum { @@ -653,6 +655,7 @@ typedef enum { 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; @@ -717,6 +720,9 @@ RAYGUIAPI char **GuiLoadIcons(const char *fileName, bool loadIconsName); // Load 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 @@ -999,33 +1005,33 @@ typedef enum { ICON_MLAYERS = 226, ICON_MAPS = 227, ICON_HOT = 228, - ICON_229 = 229, - ICON_230 = 230, - ICON_231 = 231, - ICON_232 = 232, - ICON_233 = 233, - ICON_234 = 234, - ICON_235 = 235, - ICON_236 = 236, - ICON_237 = 237, - ICON_238 = 238, - ICON_239 = 239, - ICON_240 = 240, - ICON_241 = 241, - ICON_242 = 242, - ICON_243 = 243, - ICON_244 = 244, - ICON_245 = 245, - ICON_246 = 246, - ICON_247 = 247, - ICON_248 = 248, - ICON_249 = 249, + ICON_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, + ICON_255 = 255 } GuiIconName; #endif @@ -1046,12 +1052,24 @@ typedef enum { #if defined(RAYGUI_IMPLEMENTATION) #include // required for: isspace() [GuiTextBox()] -#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()] -#include // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()] +#include // Required for: 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 @@ -1060,7 +1078,7 @@ typedef enum { // Check if two rectangles are equal, used to validate a slider bounds as an id #ifndef CHECK_BOUNDS_ID - #define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height)) + #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) @@ -1318,27 +1336,27 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x422a422a, 0x422e422a, 0x40384e28, 0x00007fe0, // ICON_MLAYERS 0x0ffe0000, 0x3ffa0802, 0x7fea200a, 0x402a402a, 0x5b2a512a, 0x512e552a, 0x40385128, 0x00007fe0, // ICON_MAPS 0x04200000, 0x1cf00c60, 0x11f019f0, 0x0f3807b8, 0x1e3c0f3c, 0x1c1c1e1c, 0x1e3c1c1c, 0x00000f70, // ICON_HOT - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_229 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_230 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_231 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_232 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_233 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249 + 0x00000000, 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 @@ -1363,7 +1381,7 @@ static unsigned int *guiIconsPtr = guiIcons; #define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties //---------------------------------------------------------------------------------- -// Types and Structures Definition +// Module Types and Structures Definition //---------------------------------------------------------------------------------- // Gui control property style color element typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement; @@ -1387,8 +1405,7 @@ static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds static int textBoxCursorIndex = 0; // Cursor index, shared by all GuiTextBox*() //static int blinkCursorFrameCounter = 0; // Frame counter for cursor blinking -static int autoCursorCooldownCounter = 0; // Cooldown frame counter for automatic cursor movement on key-down -static int autoCursorDelayCounter = 0; // Delay frame counter for automatic cursor movement +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) @@ -1484,7 +1501,6 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co //---------------------------------------------------------------------------------- static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only) -static int GetTextWidth(const char *text); // Gui get text width using gui font and style static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor @@ -1589,6 +1605,10 @@ int GuiWindowBox(Rectangle bounds, const char *title) #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; @@ -1597,9 +1617,10 @@ int GuiWindowBox(Rectangle bounds, const char *title) 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) - 20, - statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18 }; + Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT - vPadding, + statusBar.y + vPadding, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT, RAYGUI_WINDOWBOX_CLOSEBUTTON_HEIGHT }; // Update control //-------------------------------------------------------------------- @@ -1653,7 +1674,7 @@ int GuiGroupBox(Rectangle bounds, const char *text) // Line control int GuiLine(Rectangle bounds, const char *text) { - #if !defined(RAYGUI_LINE_ORIGIN_SIZE) + #if !defined(RAYGUI_LINE_MARGIN_TEXT) #define RAYGUI_LINE_MARGIN_TEXT 12 #endif #if !defined(RAYGUI_LINE_TEXT_PADDING) @@ -1671,7 +1692,7 @@ int GuiLine(Rectangle bounds, const char *text) else { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(text) + 2; + textBounds.width = (float)GuiGetTextWidth(text) + 2; textBounds.height = bounds.height; textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT; textBounds.y = bounds.y; @@ -1711,8 +1732,8 @@ int GuiPanel(Rectangle bounds, const char *text) //-------------------------------------------------------------------- if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar - GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? (int)BORDER_COLOR_DISABLED: (int)LINE_COLOR)), - GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR))); + 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; @@ -1722,7 +1743,7 @@ int GuiPanel(Rectangle bounds, const char *text) // NOTE: Using GuiToggle() for the TABS int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) { - #define RAYGUI_TABBAR_ITEM_WIDTH 160 + #define RAYGUI_TABBAR_ITEM_WIDTH 148 int result = -1; //GuiState state = guiState; @@ -1755,12 +1776,12 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) if (i == (*active)) { toggle = true; - GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + GuiToggle(tabBounds, text[i], &toggle); } else { toggle = false; - GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + GuiToggle(tabBounds, text[i], &toggle); if (toggle) *active = i; } @@ -2011,7 +2032,7 @@ int GuiLabelButton(Rectangle bounds, const char *text) bool pressed = false; // NOTE: We force bounds.width to be all text - float textWidth = (float)GetTextWidth(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 @@ -2149,7 +2170,9 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) // Get substrings items from text (items pointers) int itemCount = 0; - const char **items = GuiTextSplit(text, ';', &itemCount, NULL); + const char **items = NULL; + + if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); Rectangle slider = { 0, // Calculated later depending on the active toggle @@ -2196,7 +2219,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active) if (text != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(text); + 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; @@ -2221,7 +2244,7 @@ int GuiCheckBox(Rectangle bounds, const char *text, bool *checked) if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -2474,7 +2497,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) { #if !defined(RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN) - #define RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN 40 // Frames to wait for autocursor movement + #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 @@ -2487,10 +2510,10 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int wrapMode = GuiGetStyle(DEFAULT, TEXT_WRAP_MODE); Rectangle textBounds = GetTextBounds(TEXTBOX, bounds); - int textLength = (int)strlen(text); // Get current text length + int textLength = (text != NULL)? (int)strlen(text) : 0; // Get current text length int thisCursorIndex = textBoxCursorIndex; if (thisCursorIndex > textLength) thisCursorIndex = textLength; - int textWidth = GetTextWidth(text) - GetTextWidth(text + thisCursorIndex); + int textWidth = GuiGetTextWidth(text) - GuiGetTextWidth(text + thisCursorIndex); int textIndexOffset = 0; // Text index offset to start drawing in the box // Cursor rectangle @@ -2511,15 +2534,6 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) mouseCursor.x = -1; mouseCursor.width = 1; - // Auto-cursor movement logic - // NOTE: Cursor moves automatically when key down after some time - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_UP) || IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_BACKSPACE) || IsKeyDown(KEY_DELETE)) autoCursorCooldownCounter++; - else - { - autoCursorCooldownCounter = 0; // GLOBAL: Cursor cooldown counter - autoCursorDelayCounter = 0; // GLOBAL: Cursor delay counter - } - // Blink-cursor frame counter //if (!autoCursorMode) blinkCursorFrameCounter++; //else blinkCursorFrameCounter = 0; @@ -2537,6 +2551,13 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) 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++; + 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; @@ -2550,7 +2571,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textIndexOffset += nextCodepointSize; - textWidth = GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex); + textWidth = GuiGetTextWidth(text + textIndexOffset) - GuiGetTextWidth(text + textBoxCursorIndex); } int codepoint = GetCharPressed(); // Get Unicode codepoint @@ -2560,10 +2581,43 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int codepointSize = 0; const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize); - // Add codepoint to text, at current cursor position - // NOTE: Make sure we do not overflow buffer size - if (((multiline && (codepoint == (int)'\n')) || (codepoint >= 32)) && ((textLength + codepointSize) < textSize)) + // Handle text paste action + if (IsKeyPressed(KEY_V) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(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]; @@ -2583,113 +2637,185 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Move cursor to end if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_END)) textBoxCursorIndex = textLength; - // Delete codepoint from text, after current cursor position - if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + // Delete related codepoints from text, after current cursor position + if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_DELETE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - autoCursorDelayCounter++; + int offset = textBoxCursorIndex; + int accCodepointSize = 0; + int nextCodepointSize; + int nextCodepoint; - if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + // 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) { - int nextCodepointSize = 0; - GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); - - // Move backward text from cursor position - for (int i = textBoxCursorIndex; i < textLength; i++) text[i] = text[i + nextCodepointSize]; - - textLength -= codepointSize; - if (textBoxCursorIndex > textLength) textBoxCursorIndex = textLength; - - // Make sure text last character is EOL - text[textLength] = '\0'; + 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) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(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 ((textLength > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) + if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_BACKSPACE) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - int i = textBoxCursorIndex - 1; + int offset = textBoxCursorIndex; int accCodepointSize = 0; + int prevCodepointSize; + int prevCodepoint; - // Move cursor to the end of word if on space already - while ((i > 0) && isspace(text[i])) + // Check whitespace to delete (ASCII only) + while (offset > 0) { - int prevCodepointSize = 0; - GetCodepointPrevious(text + i, &prevCodepointSize); - i -= prevCodepointSize; + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if (!isspace(prevCodepoint & 0xff)) break; + + offset -= prevCodepointSize; accCodepointSize += prevCodepointSize; } - // Move cursor to the start of the word - while ((i > 0) && !isspace(text[i])) + // 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) { - int prevCodepointSize = 0; - GetCodepointPrevious(text + i, &prevCodepointSize); - i -= prevCodepointSize; + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if ((puctuation && !ispunct(prevCodepoint & 0xff)) || (!puctuation && (isspace(prevCodepoint & 0xff) || ispunct(prevCodepoint & 0xff)))) break; + + offset -= prevCodepointSize; accCodepointSize += prevCodepointSize; } - // Move forward text from cursor position - for (int j = (textBoxCursorIndex - accCodepointSize); j < textLength; j++) text[j] = text[j + accCodepointSize]; + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex; i <= textLength; i++) text[i - accCodepointSize] = text[i]; - // Prevent cursor index from decrementing past 0 - if (textBoxCursorIndex > 0) - { - textBoxCursorIndex -= accCodepointSize; - textLength -= accCodepointSize; - } + textLength -= accCodepointSize; + textBoxCursorIndex -= accCodepointSize; + } - // Make sure text last character is EOL - text[textLength] = '\0'; - } - else if ((textLength > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && (autoCursorCooldownCounter >= RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN)))) + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) { - autoCursorDelayCounter++; + // Delete single codepoint from text, before current cursor position - if (IsKeyPressed(KEY_BACKSPACE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames - { - int prevCodepointSize = 0; + int prevCodepointSize = 0; - // Prevent cursor index from decrementing past 0 - if (textBoxCursorIndex > 0) - { - GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - // Move backward text from cursor position - for (int i = (textBoxCursorIndex - prevCodepointSize); i < textLength; i++) text[i] = text[i + prevCodepointSize]; + // Move text after cursor forward (including final null terminator) + for (int i = textBoxCursorIndex; i <= textLength; i++) text[i - prevCodepointSize] = text[i]; - textBoxCursorIndex -= codepointSize; - textLength -= codepointSize; - } - - // Make sure text last character is EOL - text[textLength] = '\0'; - } + textLength -= prevCodepointSize; + textBoxCursorIndex -= prevCodepointSize; } // Move cursor position with keys - if (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + if ((textBoxCursorIndex > 0) && IsKeyPressed(KEY_LEFT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))) { - autoCursorDelayCounter++; + int offset = textBoxCursorIndex; + //int accCodepointSize = 0; + int prevCodepointSize; + int prevCodepoint; - if (IsKeyPressed(KEY_LEFT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + // Check whitespace to skip (ASCII only) + while (offset > 0) { - int prevCodepointSize = 0; - if (textBoxCursorIndex > 0) GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); + prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); + if (!isspace(prevCodepoint & 0xff)) break; - if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize; + 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 (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && (autoCursorCooldownCounter > RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN))) + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_LEFT) || (IsKeyDown(KEY_LEFT) && autoCursorShouldTrigger))) { - autoCursorDelayCounter++; + int prevCodepointSize = 0; + GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); - if (IsKeyPressed(KEY_RIGHT) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames + textBoxCursorIndex -= prevCodepointSize; + } + else if ((textLength > textBoxCursorIndex) && IsKeyPressed(KEY_RIGHT) && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(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) { - int nextCodepointSize = 0; - GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) break; - if ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize; + 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) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger))) + { + int nextCodepointSize = 0; + GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); + + textBoxCursorIndex += nextCodepointSize; } // Move cursor position with mouse @@ -2701,7 +2827,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) float widthToMouseX = 0; int mouseCursorIndex = 0; - for (int i = textIndexOffset; i < textLength; i++) + for (int i = textIndexOffset; i < textLength; i += codepointSize) { codepoint = GetCodepointNext(&text[i], &codepointSize); codepointIndex = GetGlyphIndex(guiFont, codepoint); @@ -2720,7 +2846,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) } // Check if mouse cursor is at the last position - int textEndWidth = GetTextWidth(text + textIndexOffset); + int textEndWidth = GuiGetTextWidth(text + textIndexOffset); if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2)) { mouseCursor.x = textBounds.x + textEndWidth; @@ -2737,7 +2863,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) else mouseCursor.x = -1; // Recalculate cursor position.y depending on textBoxCursorIndex - cursor.x = bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text + textIndexOffset) - GetTextWidth(text + textBoxCursorIndex) + GuiGetStyle(DEFAULT, TEXT_SPACING); + 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 @@ -2745,6 +2871,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) (!CheckCollisionPointRec(mousePosition, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) { textBoxCursorIndex = 0; // GLOBAL: Reset the shared cursor index + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes result = 1; } } @@ -2757,6 +2884,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { textBoxCursorIndex = textLength; // GLOBAL: Place cursor index to the end of current text + autoCursorCounter = 0; // GLOBAL: Reset counter for repeated keystrokes result = 1; } } @@ -2825,19 +2953,22 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int int tempValue = *value; - Rectangle spinner = { bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING), bounds.y, - bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING)), bounds.height }; - Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; - Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height }; + Rectangle 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)GetTextWidth(text) + 2; + textBounds.width = (float)GuiGetTextWidth(text) + 2; textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); - textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING); + textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING); textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; - if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING); + if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING); } // Update control @@ -2871,20 +3002,20 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int // Draw control //-------------------------------------------------------------------- - result = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode); + 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(SPINNER, BORDER_WIDTH)); + 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(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); + GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); //-------------------------------------------------------------------- *value = tempValue; @@ -2902,13 +3033,13 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int result = 0; GuiState state = guiState; - char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; - sprintf(textValue, "%i", *value); + 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)GetTextWidth(text) + 2; + 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; @@ -2920,7 +3051,6 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { Vector2 mousePoint = GetMousePosition(); - bool valueHasChanged = false; if (editMode) @@ -2929,30 +3059,53 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int keyCount = (int)strlen(textValue); - // Only allow keys in range [48..57] - if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + // Add or remove minus symbol + if (IsKeyPressed(KEY_MINUS)) { - if (GetTextWidth(textValue) < bounds.width) + if (textValue[0] == '-') { - int key = GetCharPressed(); - if ((key >= 48) && (key <= 57)) + 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[keyCount] = (char)key; + textValue[0] = '0'; + textValue[1] = '\0'; keyCount++; - valueHasChanged = true; } + + 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 = GetCharPressed(); + + // Only allow keys in range [48..57] + if ((key >= 48) && (key <= 57)) + { + textValue[keyCount] = (char)key; + keyCount++; + valueHasChanged = true; } } // Delete text - if (keyCount > 0) + if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE)) { - if (IsKeyPressed(KEY_BACKSPACE)) - { - keyCount--; - textValue[keyCount] = '\0'; - valueHasChanged = true; - } + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; } if (valueHasChanged) *value = TextToInteger(textValue); @@ -2992,11 +3145,14 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in 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 + // Draw cursor rectangle if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = { bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) }; + 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))); } @@ -3019,12 +3175,12 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float GuiState state = guiState; //char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; - //sprintf(textValue, "%2.2f", *value); + //snprintf(textValue, sizeof(textValue), "%2.2f", *value); - Rectangle textBounds = {0}; + Rectangle textBounds = { 0 }; if (text != NULL) { - textBounds.width = (float)GetTextWidth(text) + 2; + 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; @@ -3045,10 +3201,37 @@ 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 (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 (GetTextWidth(textValue) < bounds.width) + if (GuiGetTextWidth(textValue) < bounds.width) { int key = GetCharPressed(); if (((key >= 48) && (key <= 57)) || @@ -3103,7 +3286,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float if (editMode) { // NOTE: ValueBox internal text is always centered - Rectangle cursor = {bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 1, + 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))); @@ -3120,7 +3303,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float // Slider control with pro parameters // NOTE: Other GuiSlider*() controls use this one -int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth) +int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) { int result = 0; GuiState state = guiState; @@ -3129,6 +3312,8 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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) }; @@ -3146,7 +3331,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, { 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; + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; } } else @@ -3166,7 +3351,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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; + *value = (maxValue - minValue)*((mousePoint.x - bounds.x - sliderWidth/2)/(bounds.width - sliderWidth)) + minValue; } } else state = STATE_FOCUSED; @@ -3205,44 +3390,45 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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)GetTextWidth(textLeft); + 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(SLIDER, TEXT + (state*3)))); + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } if (textRight != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textRight); + 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(SLIDER, TEXT + (state*3)))); + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } //-------------------------------------------------------------------- return result; } -// Slider control extended, returns selected value and has text -int GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) -{ - return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH)); -} - // Slider Bar control extended, returns selected value int GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue) { - return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0); + 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 @@ -3257,14 +3443,14 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight // Progress bar Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0, - bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) }; + 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 - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f); + if ((state != STATE_DISABLED)) progress.width = ((float)*value/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)); //-------------------------------------------------------------------- // Draw control @@ -3282,15 +3468,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, (int)progress.width + (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); } - else GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + 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 + 1, bounds.y, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_FOCUSED))); + 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 + 1, bounds.y, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); - GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + (int)progress.width + 1, bounds.y + bounds.height - 1, bounds.width - (int)progress.width - 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); - GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y + 1, (float)GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), bounds.height - 2 }, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BORDER_COLOR_NORMAL))); + 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) @@ -3301,23 +3487,23 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight if (textLeft != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textLeft); + 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(PROGRESSBAR, TEXT + (state*3)))); + GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } if (textRight != NULL) { Rectangle textBounds = { 0 }; - textBounds.width = (float)GetTextWidth(textRight); + 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(PROGRESSBAR, TEXT + (state*3)))); + GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, GetColor(GuiGetStyle(LABEL, TEXT + (state*3)))); } //-------------------------------------------------------------------- @@ -3467,11 +3653,11 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd // Draw visible items for (int i = 0; ((i < visibleItems) && (text != NULL)); i++) { - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, LIST_ITEMS_BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_NORMAL)), BLANK); + if (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, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_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(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED))); } @@ -3480,18 +3666,18 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd if (((startIndex + i) == itemSelected) && (active != NULL)) { // Draw item selected - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED))); + 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))); } else if (((startIndex + i) == itemFocused)) // && (focus != NULL)) // NOTE: We want items focused, despite not returned! { // Draw item focused - GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED))); + 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))); } else { - // Draw item normal + // Draw item normal (no rectangle) GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL))); } } @@ -3531,22 +3717,22 @@ int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollInd return result; } -// Color Panel control - Color (RGBA) variant. +// 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. + 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. + // 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); @@ -3570,7 +3756,10 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) 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 }; + 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 //-------------------------------------------------------------------- @@ -3617,7 +3806,6 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha) // Draw control //-------------------------------------------------------------------- - // Draw alpha bar: checked background if (state != STATE_DISABLED) { @@ -3755,7 +3943,7 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *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. + // 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); @@ -3768,8 +3956,8 @@ int GuiColorPicker(Rectangle bounds, const char *text, Color *color) 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. +// 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) @@ -3917,7 +4105,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount; buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT; - //int textWidth = GetTextWidth(message) + 2; + //int textWidth = GuiGetTextWidth(message) + 2; Rectangle textBounds = { 0 }; textBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; @@ -3981,7 +4169,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co Rectangle textBounds = { 0 }; if (message != NULL) { - int textSize = GetTextWidth(message) + 2; + 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; @@ -4221,7 +4409,7 @@ void GuiLoadStyle(const char *fileName) if (fileDataSize > 0) { - unsigned char *fileData = (unsigned char *)RAYGUI_MALLOC(fileDataSize*sizeof(unsigned char)); + unsigned char *fileData = (unsigned char *)RAYGUI_CALLOC(fileDataSize, sizeof(unsigned char)); fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile); GuiLoadStyleFromMemory(fileData, fileDataSize); @@ -4283,8 +4471,6 @@ void GuiLoadStyleDefault(void) GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(VALUEBOX, TEXT_PADDING, 0); GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); - GuiSetStyle(SPINNER, TEXT_PADDING, 0); - GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); GuiSetStyle(STATUSBAR, TEXT_PADDING, 8); GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT); @@ -4299,8 +4485,8 @@ void GuiLoadStyleDefault(void) GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2); GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16); GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2); - GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24); - GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2); + GuiSetStyle(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); @@ -4310,6 +4496,7 @@ void GuiLoadStyleDefault(void) 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); @@ -4322,8 +4509,8 @@ void GuiLoadStyleDefault(void) { // Unload previous font texture UnloadTexture(guiFont.texture); - RL_FREE(guiFont.recs); - RL_FREE(guiFont.glyphs); + RAYGUI_FREE(guiFont.recs); + RAYGUI_FREE(guiFont.glyphs); guiFont.recs = NULL; guiFont.glyphs = NULL; @@ -4352,7 +4539,7 @@ const char *GuiIconText(int iconId, const char *text) if (text != NULL) { memset(buffer, 0, 1024); - sprintf(buffer, "#%03i#", iconId); + snprintf(buffer, 1024, "#%03i#", iconId); for (int i = 5; i < 1024; i++) { @@ -4364,7 +4551,7 @@ const char *GuiIconText(int iconId, const char *text) } else { - sprintf(iconBuffer, "#%03i#", iconId); + snprintf(iconBuffer, 16, "#%03i#", iconId); return iconBuffer; } @@ -4430,17 +4617,17 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) { if (loadIconsName) { - guiIconsName = (char **)RAYGUI_MALLOC(iconCount*sizeof(char **)); + guiIconsName = (char **)RAYGUI_CALLOC(iconCount, sizeof(char *)); for (int i = 0; i < iconCount; i++) { - guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH); + 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), iconCount*(iconSize*iconSize/32), rgiFile); + fread(guiIconsPtr, sizeof(unsigned int), (int)iconCount*((int)iconSize*(int)iconSize/32), rgiFile); } fclose(rgiFile); @@ -4449,6 +4636,56 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) 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) { @@ -4476,12 +4713,73 @@ 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) @@ -4567,7 +4865,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) { // Compressed font atlas image data (DEFLATE), it requires DecompressData() int dataUncompSize = 0; - unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize); + unsigned char *compData = (unsigned char *)RAYGUI_CALLOC(fontImageCompSize, sizeof(unsigned char)); memcpy(compData, fileDataPtr, fontImageCompSize); fileDataPtr += fontImageCompSize; @@ -4581,7 +4879,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) else { // Font atlas image data is not compressed - imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize); + imFont.data = (unsigned char *)RAYGUI_CALLOC(fontImageUncompSize, sizeof(unsigned char)); memcpy(imFont.data, fileDataPtr, fontImageUncompSize); fileDataPtr += fontImageUncompSize; } @@ -4609,7 +4907,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) if ((recsDataCompressedSize > 0) && (recsDataCompressedSize != recsDataSize)) { // Recs data is compressed, uncompress it - unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_MALLOC(recsDataCompressedSize); + unsigned char *recsDataCompressed = (unsigned char *)RAYGUI_CALLOC(recsDataCompressedSize, sizeof(unsigned char)); memcpy(recsDataCompressed, fileDataPtr, recsDataCompressedSize); fileDataPtr += recsDataCompressedSize; @@ -4651,7 +4949,7 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) if ((glyphsDataCompressedSize > 0) && (glyphsDataCompressedSize != glyphsDataSize)) { // Glyphs data is compressed, uncompress it - unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_MALLOC(glyphsDataCompressedSize); + unsigned char *glypsDataCompressed = (unsigned char *)RAYGUI_CALLOC(glyphsDataCompressedSize, sizeof(unsigned char)); memcpy(glypsDataCompressed, fileDataPtr, glyphsDataCompressedSize); fileDataPtr += glyphsDataCompressedSize; @@ -4704,68 +5002,6 @@ static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize) } } -// Gui get text width considering icon -static int GetTextWidth(const char *text) -{ - #if !defined(ICON_TEXT_PADDING) - #define ICON_TEXT_PADDING 4 - #endif - - Vector2 textSize = { 0 }; - int textIconOffset = 0; - - if ((text != NULL) && (text[0] != '\0')) - { - if (text[0] == '#') - { - for (int i = 1; (i < 5) && (text[i] != '\0'); i++) - { - if (text[i] == '#') - { - textIconOffset = i; - break; - } - } - } - - text += textIconOffset; - - // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly - float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE); - - // Custom MeasureText() implementation - if ((guiFont.texture.id > 0) && (text != NULL)) - { - // Get size in bytes of text, considering end of line and line break - int size = 0; - for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++) - { - if ((text[i] != '\0') && (text[i] != '\n')) size++; - else break; - } - - float scaleFactor = fontSize/(float)guiFont.baseSize; - textSize.y = (float)guiFont.baseSize*scaleFactor; - float glyphWidth = 0.0f; - - for (int i = 0, codepointSize = 0; i < size; i += codepointSize) - { - int codepoint = GetCodepointNext(&text[i], &codepointSize); - int codepointIndex = GetGlyphIndex(guiFont, codepoint); - - if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor); - else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor); - - textSize.x += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING)); - } - } - - if (textIconOffset > 0) textSize.x += (RAYGUI_ICON_SIZE + ICON_TEXT_PADDING); - } - - return (int)textSize.x; -} - // Get text bounds considering control bounds static Rectangle GetTextBounds(int control, Rectangle bounds) { @@ -4786,7 +5022,7 @@ static Rectangle GetTextBounds(int control, Rectangle bounds) case SLIDER: case CHECKBOX: case VALUEBOX: - case SPINNER: + case CONTROL11: // TODO: More special cases (label on side): SLIDER, CHECKBOX, VALUEBOX, SPINNER default: { @@ -4832,7 +5068,8 @@ static const char *GetTextIcon(const char *text, int *iconId) } // Get text divided into lines (by line-breaks '\n') -const char **GetTextLines(const char *text, int *count) +// 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 @@ -4936,8 +5173,8 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C float textBoundsWidthOffset = 0.0f; // NOTE: We get text size after icon has been processed - // WARNING: GetTextWidth() also processes text icon to get width! -> Really needed? - int textSizeX = GetTextWidth(lines[i]); + // 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) @@ -5000,7 +5237,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C float textOffsetX = 0.0f; float glyphWidth = 0; - int ellipsisWidth = GetTextWidth("..."); + int ellipsisWidth = GuiGetTextWidth("..."); bool textOverflow = false; for (int c = 0, codepointSize = 0; c < lineSize; c += codepointSize) { @@ -5144,13 +5381,13 @@ 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.f }, NULL); + GuiPanel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, NULL); int textPadding = GuiGetStyle(LABEL, TEXT_PADDING); int textAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT); GuiSetStyle(LABEL, TEXT_PADDING, 0); GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); - GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.f }, guiTooltipPtr); + GuiLabel(RAYGUI_CLITERAL(Rectangle){ controlRec.x, controlRec.y + controlRec.height + 4, textSize.x + 16, GuiGetStyle(DEFAULT, TEXT_SIZE) + 8.0f }, guiTooltipPtr); GuiSetStyle(LABEL, TEXT_ALIGNMENT, textAlignment); GuiSetStyle(LABEL, TEXT_PADDING, textPadding); } @@ -5204,7 +5441,7 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i buffer[i] = '\0'; // Set an end of string at this point counter++; - if (counter > RAYGUI_TEXTSPLIT_MAX_ITEMS) break; + if (counter >= RAYGUI_TEXTSPLIT_MAX_ITEMS) break; } } @@ -5526,10 +5763,10 @@ 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; + 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; } @@ -5562,7 +5799,7 @@ static const char *TextFormat(const char *text, ...) va_list args; va_start(args, text); - vsprintf(buffer, text, args); + vsnprintf(buffer, RAYGUI_TEXTFORMAT_MAX_SIZE, text, args); va_end(args); return buffer; @@ -5731,7 +5968,7 @@ static int GetCodepointNext(const char *text, int *codepointSize) } else if (0xe0 == (0xf0 & ptr[0])) { - // 3 byte UTF-8 codepoint */ + // 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; diff --git a/examples/shapes/raygui.h b/examples/shapes/raygui.h index 17ced6ef5..f86247ac4 100644 --- a/examples/shapes/raygui.h +++ b/examples/shapes/raygui.h @@ -77,7 +77,7 @@ * * static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)]; * -* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB +* 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 @@ -141,7 +141,7 @@ * Draw text bounds rectangles for debug * * VERSIONS HISTORY: -* 5.0-dev (2025) Current dev version... +* 5.0 (xx-Nov-2025) 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 @@ -271,7 +271,7 @@ * 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria * * DEPENDENCIES: -* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing +* 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 @@ -1010,28 +1010,28 @@ typedef enum { ICON_SLICING = 231, ICON_MANUAL_CONTROL = 232, ICON_COLLISION = 233, - ICON_234 = 234, - ICON_235 = 235, - ICON_236 = 236, - ICON_237 = 237, - ICON_238 = 238, - ICON_239 = 239, - ICON_240 = 240, - ICON_241 = 241, - ICON_242 = 242, - ICON_243 = 243, - ICON_244 = 244, - ICON_245 = 245, - ICON_246 = 246, - ICON_247 = 247, - ICON_248 = 248, - ICON_249 = 249, + ICON_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, + ICON_255 = 255 } GuiIconName; #endif @@ -1078,7 +1078,7 @@ typedef enum { // Check if two rectangles are equal, used to validate a slider bounds as an id #ifndef CHECK_BOUNDS_ID - #define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height)) + #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) @@ -1341,22 +1341,22 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = 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 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248 - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249 + 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 @@ -1743,7 +1743,7 @@ int GuiPanel(Rectangle bounds, const char *text) // NOTE: Using GuiToggle() for the TABS int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) { - #define RAYGUI_TABBAR_ITEM_WIDTH 160 + #define RAYGUI_TABBAR_ITEM_WIDTH 148 int result = -1; //GuiState state = guiState; @@ -1776,12 +1776,12 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) if (i == (*active)) { toggle = true; - GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + GuiToggle(tabBounds, text[i], &toggle); } else { toggle = false; - GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle); + GuiToggle(tabBounds, text[i], &toggle); if (toggle) *active = i; } @@ -2590,7 +2590,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) int pasteLength = 0; int pasteCodepoint; int pasteCodepointSize; - + // Count how many codepoints to copy, stopping at the first unwanted control character while (true) { @@ -2599,7 +2599,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) if (!(multiline && (pasteCodepoint == (int)'\n')) && !(pasteCodepoint >= 32)) break; pasteLength += pasteCodepointSize; } - + if (pasteLength > 0) { // Move forward data from cursor position @@ -2662,7 +2662,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) while (offset < textLength) { if (!isspace(nextCodepoint & 0xff)) break; - + offset += nextCodepointSize; accCodepointSize += nextCodepointSize; nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize); @@ -2673,11 +2673,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; } - + else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, after current cursor position - + int nextCodepointSize = 0; GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize); @@ -2704,7 +2704,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) 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); @@ -2723,11 +2723,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) textLength -= accCodepointSize; textBoxCursorIndex -= accCodepointSize; } - + else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger))) { // Delete single codepoint from text, before current cursor position - + int prevCodepointSize = 0; GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize); @@ -3033,7 +3033,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in int result = 0; GuiState state = guiState; - char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0"; + char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = { 0 }; snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value); Rectangle textBounds = { 0 }; @@ -3051,7 +3051,6 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode) { Vector2 mousePoint = GetMousePosition(); - bool valueHasChanged = false; if (editMode) @@ -3070,7 +3069,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in keyCount--; valueHasChanged = true; } - else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS -1) + else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) { if (keyCount == 0) { @@ -3087,30 +3086,26 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in } } - // Only allow keys in range [48..57] - if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) + // Add new digit to text value + if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width)) { - if (GuiGetTextWidth(textValue) < bounds.width) + int key = GetCharPressed(); + + // Only allow keys in range [48..57] + if ((key >= 48) && (key <= 57)) { - int key = GetCharPressed(); - if ((key >= 48) && (key <= 57)) - { - textValue[keyCount] = (char)key; - keyCount++; - valueHasChanged = true; - } + textValue[keyCount] = (char)key; + keyCount++; + valueHasChanged = true; } } // Delete text - if (keyCount > 0) + if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE)) { - if (IsKeyPressed(KEY_BACKSPACE)) - { - keyCount--; - textValue[keyCount] = '\0'; - valueHasChanged = true; - } + keyCount--; + textValue[keyCount] = '\0'; + valueHasChanged = true; } if (valueHasChanged) *value = TextToInteger(textValue); @@ -3224,9 +3219,9 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float textValue[1] = '\0'; keyCount++; } - + for (int i = keyCount; i > -1; i--) textValue[i + 1] = textValue[i]; - + textValue[0] = '-'; keyCount++; valueHasChanged = true; From c7c6aaf156426e5e955b67135327672471af1b33 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:12:25 +0100 Subject: [PATCH 122/189] Update examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index 37c50a486..b68e5c0be 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -17,18 +17,7 @@ Example automated testing elements validated: | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| | core_input_actions | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_directory_files | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_clipboard_text | 5 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_compute_hash | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_recursive_tree | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_ring_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_circle_sector_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_rounded_rectangle_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_splines_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_digital_clock | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_triangle_strip | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_pie_chart | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_math_sine_cosine | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_sdf | 0 | 73 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From e6ef99275a575ff5ad5d923609326573c74b0789 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:14:48 +0100 Subject: [PATCH 123/189] Update shapes_digital_clock.c --- examples/shapes/shapes_digital_clock.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c index 77b020704..5f55fa836 100644 --- a/examples/shapes/shapes_digital_clock.c +++ b/examples/shapes/shapes_digital_clock.c @@ -284,11 +284,13 @@ static void DrawDisplaySegment(Vector2 center, int length, int thick, bool verti if (!vertical) { // Horizontal segment points - // 3___________________________5 - // / \ - // /1 x 6\ - // \ / - // \2___________________________4/ + /* + 3___________________________5 + / \ + /1 x 6\ + \ / + \2___________________________4/ + */ Vector2 segmentPointsH[6] = { (Vector2){ center.x - length/2.0f - thick/2.0f, center.y }, // Point 1 (Vector2){ center.x - length/2.0f, center.y + thick/2.0f }, // Point 2 From 48496e230767280307f14dd4ab01e42fff33d06a Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:18:32 +0100 Subject: [PATCH 124/189] Update core_input_actions.c --- examples/core/core_input_actions.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/core/core_input_actions.c b/examples/core/core_input_actions.c index aff356087..cbf7e0e92 100644 --- a/examples/core/core_input_actions.c +++ b/examples/core/core_input_actions.c @@ -71,6 +71,7 @@ int main(void) // Set default actions char actionSet = 0; SetActionsDefault(); + bool releaseAction = false; Vector2 position = (Vector2){ 400.0f, 200.0f }; Vector2 size = (Vector2){ 40.0f, 40.0f }; @@ -83,7 +84,8 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - gamepadIndex = 0; // set this to gamepad being checked + gamepadIndex = 0; // Set gamepad being checked + if (IsActionDown(ACTION_UP)) position.y -= 2; if (IsActionDown(ACTION_DOWN)) position.y += 2; if (IsActionDown(ACTION_LEFT)) position.x -= 2; @@ -93,6 +95,10 @@ int main(void) position.x = (screenWidth-size.x)/2; position.y = (screenHeight-size.y)/2; } + + // Register release action for one frame + releaseAction = false; + if (IsActionReleased(ACTION_FIRE)) releaseAction = true; // Switch control scheme by pressing TAB if (IsKeyPressed(KEY_TAB)) @@ -109,7 +115,7 @@ int main(void) ClearBackground(GRAY); - DrawRectangleV(position, size, RED); + DrawRectangleV(position, size, releaseAction? BLUE : RED); DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE); DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN); From 83a167ca3f90ee61f30193d72252a7ff8204d1d4 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:19:55 +0100 Subject: [PATCH 125/189] Update text_inline_styling.c --- examples/text/text_inline_styling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c index b221c7e6f..0e5e8091f 100644 --- a/examples/text/text_inline_styling.c +++ b/examples/text/text_inline_styling.c @@ -210,7 +210,7 @@ static Vector2 MeasureTextStyled(Font font, const char *text, float fontSize, fl if ((font.texture.id == 0) || (text == NULL) || (text[0] == '\0')) return textSize; // Security check int textLen = TextLength(text); // Get size in bytes of text - float textLineSpacing = fontSize*1.5f; + //float textLineSpacing = fontSize*1.5f; // Not used... float textWidth = 0.0f; float textHeight = fontSize; From 1b6303b9007cfaa48564f28255da1c1b8f9b5a2c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:20:05 +0100 Subject: [PATCH 126/189] Update examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index b68e5c0be..9a28d47ca 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -16,11 +16,8 @@ Example automated testing elements validated: ``` | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| -| core_input_actions | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_digital_clock | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_sdf | 0 | 73 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| text_inline_styling | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | From 57e22d5fa0781211815a55d27142a22b37b152aa Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:26:26 +0100 Subject: [PATCH 127/189] Update rtext.c --- src/rtext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rtext.c b/src/rtext.c index 1705e5b49..1c70aedc1 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -724,7 +724,8 @@ 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); - if (cpHeight > fontSize) TRACELOG(LOG_WARNING, "FONT: [0x%04x] Glyph height is bigger than requested font size: %i > %i", cp, cpHeight, (int)fontSize); + // WARNING: If requested SDF font, sdf-glyph height is definitely bigger than fontSize due to FONT_SDF_CHAR_PADDING + if ((type != FONT_SDF) && (cpHeight > fontSize)) TRACELOG(LOG_WARNING, "FONT: [0x%04x] Glyph height is bigger than requested font size: %i > %i", cp, cpHeight, (int)fontSize); // Load glyph image glyphs[k].image.width = cpWidth; From a24e65d8e17224925ae9ffdb27cc498fb27f6719 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:26:54 +0100 Subject: [PATCH 128/189] Update examples_testing_windows.md --- tools/rexm/reports/examples_testing_windows.md | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/rexm/reports/examples_testing_windows.md b/tools/rexm/reports/examples_testing_windows.md index 9a28d47ca..8b8804bda 100644 --- a/tools/rexm/reports/examples_testing_windows.md +++ b/tools/rexm/reports/examples_testing_windows.md @@ -17,7 +17,6 @@ Example automated testing elements validated: | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| | text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| text_font_sdf | 0 | 73 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | From f51204821a371731a38aa3306409bfc3bd2f0dbd Mon Sep 17 00:00:00 2001 From: Serhii Zasenko Date: Tue, 18 Nov 2025 22:27:50 +0200 Subject: [PATCH 129/189] Add vibration test button to core_input_gamepad (#5362) --- examples/core/core_input_gamepad.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index abfdb11c1..9e1bbc386 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -72,6 +72,8 @@ int main(void) if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--; if (IsKeyPressed(KEY_RIGHT)) gamepad++; + Vector2 mousePosition = GetMousePosition(); + bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT); if (IsGamepadAvailable(gamepad)) { @@ -262,6 +264,14 @@ int main(void) DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 10, DARKGRAY); } + Rectangle vibrateButton = (Rectangle){10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 10}; + if (mousePressed && CheckCollisionPointRec(mousePosition, vibrateButton)){ + SetGamepadVibration(gamepad, 1.0, 1.0, 1.0); + } + DrawRectangleRec(vibrateButton, SKYBLUE); + + DrawText("VIBRATE", vibrateButton.x + 14, 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); } From d5e8ee77b1a5633d1fff7a8e3836107540ace0cc Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 18 Nov 2025 21:32:20 +0100 Subject: [PATCH 130/189] Update core_input_gamepad.c --- examples/core/core_input_gamepad.c | 42 ++++++++++++------------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index 9e1bbc386..b64e0c1a0 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -50,6 +50,8 @@ int main(void) const float rightStickDeadzoneY = 0.1f; const float leftTriggerDeadzone = -0.9f; const float rightTriggerDeadzone = -0.9f; + + Rectangle vibrateButton = { 0 }; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -61,7 +63,12 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // ... + if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--; + if (IsKeyPressed(KEY_RIGHT)) gamepad++; + Vector2 mousePosition = GetMousePosition(); + + vibrateButton = (Rectangle){ 10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 }; + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0); //---------------------------------------------------------------------------------- // Draw @@ -70,11 +77,6 @@ int main(void) ClearBackground(RAYWHITE); - if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--; - if (IsKeyPressed(KEY_RIGHT)) gamepad++; - Vector2 mousePosition = GetMousePosition(); - bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT); - if (IsGamepadAvailable(gamepad)) { DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK); @@ -95,7 +97,8 @@ int main(void) if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f; if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f; - if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1) + if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1) || + (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)) { DrawTexture(texXboxPad, 0, 0, DARKGRAY); @@ -127,16 +130,14 @@ int main(void) if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED; DrawCircle(259, 152, 39, BLACK); DrawCircle(259, 152, 34, LIGHTGRAY); - DrawCircle(259 + (int)(leftStickX*20), - 152 + (int)(leftStickY*20), 25, leftGamepadColor); + DrawCircle(259 + (int)(leftStickX*20), 152 + (int)(leftStickY*20), 25, leftGamepadColor); // Draw axis: right joystick Color rightGamepadColor = BLACK; if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED; DrawCircle(461, 237, 38, BLACK); DrawCircle(461, 237, 33, LIGHTGRAY); - DrawCircle(461 + (int)(rightStickX*20), - 237 + (int)(rightStickY*20), 25, rightGamepadColor); + DrawCircle(461 + (int)(rightStickX*20), 237 + (int)(rightStickY*20), 25, rightGamepadColor); // Draw axis: left-right triggers DrawRectangle(170, 30, 15, 70, GRAY); @@ -179,16 +180,14 @@ int main(void) if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED; DrawCircle(319, 255, 35, BLACK); DrawCircle(319, 255, 31, LIGHTGRAY); - DrawCircle(319 + (int)(leftStickX*20), - 255 + (int)(leftStickY*20), 25, leftGamepadColor); + DrawCircle(319 + (int)(leftStickX*20), 255 + (int)(leftStickY*20), 25, leftGamepadColor); // Draw axis: right joystick Color rightGamepadColor = BLACK; if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED; DrawCircle(475, 255, 35, BLACK); DrawCircle(475, 255, 31, LIGHTGRAY); - DrawCircle(475 + (int)(rightStickX*20), - 255 + (int)(rightStickY*20), 25, rightGamepadColor); + DrawCircle(475 + (int)(rightStickX*20), 255 + (int)(rightStickY*20), 25, rightGamepadColor); // Draw axis: left-right triggers DrawRectangle(169, 48, 15, 70, GRAY); @@ -238,23 +237,20 @@ int main(void) if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED; DrawCircle(345, 260, 40, BLACK); DrawCircle(345, 260, 35, LIGHTGRAY); - DrawCircle(345 + (int)(leftStickX*20), - 260 + (int)(leftStickY*20), 25, leftGamepadColor); + DrawCircle(345 + (int)(leftStickX*20), 260 + (int)(leftStickY*20), 25, leftGamepadColor); // Draw axis: right joystick Color rightGamepadColor = BLACK; if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED; DrawCircle(465, 260, 40, BLACK); DrawCircle(465, 260, 35, LIGHTGRAY); - DrawCircle(465 + (int)(rightStickX*20), - 260 + (int)(rightStickY*20), 25, rightGamepadColor); + DrawCircle(465 + (int)(rightStickX*20), 260 + (int)(rightStickY*20), 25, rightGamepadColor); // Draw axis: left-right triggers DrawRectangle(151, 110, 15, 70, GRAY); DrawRectangle(644, 110, 15, 70, GRAY); DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED); DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED); - } DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(gamepad)), 10, 50, 10, MAROON); @@ -264,12 +260,8 @@ int main(void) DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 10, DARKGRAY); } - Rectangle vibrateButton = (Rectangle){10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 10}; - if (mousePressed && CheckCollisionPointRec(mousePosition, vibrateButton)){ - SetGamepadVibration(gamepad, 1.0, 1.0, 1.0); - } + // Draw vibrate button DrawRectangleRec(vibrateButton, SKYBLUE); - DrawText("VIBRATE", vibrateButton.x + 14, vibrateButton.y + 1, 10, DARKGRAY); if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED); From 3f92c396a009ecb51a5efab378802851f805cd76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Wed, 19 Nov 2025 02:56:32 -0500 Subject: [PATCH 131/189] Fixed typo (#5364) --- src/rlgl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rlgl.h b/src/rlgl.h index 99e9037d5..6cdf8a317 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -1252,7 +1252,7 @@ void rlPushMatrix(void) RLGL.State.stackCounter++; } -// Pop lattest inserted matrix from RLGL.State.stack +// Pop latest inserted matrix from RLGL.State.stack void rlPopMatrix(void) { if (RLGL.State.stackCounter > 0) From e2233acdb0d51d5f11f63d1b8550a766a962aac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adi=20=C4=8Cau=C5=A1evi=C4=87?= <31798801+ChocolateChipKookie@users.noreply.github.com> Date: Wed, 19 Nov 2025 08:58:43 +0100 Subject: [PATCH 132/189] feat: Optimize ImageClearBackground and ImageDrawRectangleRec with doubling strategy (#5363) --- src/rtextures.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/rtextures.c b/src/rtextures.c index ddaee2939..00554e418 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3341,11 +3341,14 @@ void ImageClearBackground(Image *dst, Color color) unsigned char *pSrcPixel = (unsigned char *)dst->data; int bytesPerPixel = GetPixelDataSize(1, 1, dst->format); + int totalPixels = dst->width * dst->height; - // Repeat the first pixel data throughout the image - for (int i = 1; i < dst->width*dst->height; i++) + // Repeat the first pixel data throughout the image, + // doubling the pixels copied on each iteration + for (int i = 1; i < totalPixels; i *= 2) { - memcpy(pSrcPixel + i*bytesPerPixel, pSrcPixel, bytesPerPixel); + int pixelsToCopy = MIN(i, totalPixels - i); + memcpy(pSrcPixel + i * bytesPerPixel, pSrcPixel, pixelsToCopy * bytesPerPixel); } } @@ -3724,9 +3727,10 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) unsigned char *pSrcPixel = (unsigned char *)dst->data + bytesOffset; // Repeat the first pixel data throughout the row - for (int x = 1; x < (int)rec.width; x++) + for (int x = 1; x < (int)rec.width; x *= 2) { - memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, bytesPerPixel); + int pixelsToCopy = MIN(x, (int)rec.width - x); + memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, pixelsToCopy * bytesPerPixel); } // Repeat the first row data for all other rows From 8081d2bd076ed39dbe9f32c1dae6c82ee78bd9e4 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 09:34:13 +0100 Subject: [PATCH 133/189] REDESIGNED: example: `shapes_kaleidoscope`, store lines #5361 This redesign stores lines in Update and draws stored lines in Draw, instead of previous approach of drawing directly to framebuffer with no cleaning. This approach allows some interesting features like line draw replay or reversing. --- examples/shapes/shapes_kaleidoscope.c | 77 +++++++++++++++++++-------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/examples/shapes/shapes_kaleidoscope.c b/examples/shapes/shapes_kaleidoscope.c index 07c96344c..7eeadb8aa 100644 --- a/examples/shapes/shapes_kaleidoscope.c +++ b/examples/shapes/shapes_kaleidoscope.c @@ -11,13 +11,26 @@ * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2025 Hugo ARNAL (@hugoarnal) +* Copyright (c) 2025 Hugo ARNAL (@hugoarnal) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" +#define MAX_DRAW_LINES 8192 + +// Line data type +typedef struct { + Vector2 start; + Vector2 end; +} Line; + +// Lines array as a global static variable to be stored +// in heap and avoid potential stack overflow (on Web platform) +static Line lines[MAX_DRAW_LINES] = { 0 }; + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -30,22 +43,24 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - kaleidoscope"); + // Line drawing properties int symmetry = 6; float angle = 360.0f/(float)symmetry; float thickness = 3.0f; + Vector2 mousePos = { 0 }; Vector2 prevMousePos = { 0 }; - - SetTargetFPS(60); - ClearBackground(BLACK); - + Vector2 scaleVector = { 1.0f, -1.0f }; Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f }; + Camera2D camera = { 0 }; camera.target = (Vector2){ 0 }; camera.offset = offset; camera.rotation = 0.0f; camera.zoom = 1.0f; + + int lineCounter = 0; - Vector2 scaleVector = { 1.0f, -1.0f }; + SetTargetFPS(20); //-------------------------------------------------------------------------------------- // Main game loop @@ -53,38 +68,58 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - Vector2 mousePos = GetMousePosition(); + prevMousePos = mousePos; + mousePos = GetMousePosition(); + Vector2 lineStart = Vector2Subtract(mousePos, offset); Vector2 lineEnd = Vector2Subtract(prevMousePos, offset); + + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + { + for (int s = 0; (s < symmetry) && (lineCounter < (MAX_DRAW_LINES - 1)); s++) + { + lineStart = Vector2Rotate(lineStart, angle*DEG2RAD); + lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD); + + // Store mouse line + lines[lineCounter].start = lineStart; + lines[lineCounter].end = lineEnd; + + // Store reflective line + lines[lineCounter + 1].start = Vector2Multiply(lineStart, scaleVector); + lines[lineCounter + 1].end = Vector2Multiply(lineEnd, scaleVector); + + lineCounter += 2; + } + } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); + + ClearBackground(RAYWHITE); + BeginMode2D(camera); - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { - for (int i = 0; i < symmetry; i++) { - lineStart = Vector2Rotate(lineStart, angle*DEG2RAD); - lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD); - - DrawLineEx(lineStart, lineEnd, thickness, WHITE); - - Vector2 reflectLineStart = Vector2Multiply(lineStart, scaleVector); - Vector2 reflectLineEnd = Vector2Multiply(lineEnd, scaleVector); - - DrawLineEx(reflectLineStart, reflectLineEnd, thickness, WHITE); + for (int s = 0; s < symmetry; s++) + { + for (int i = 0; i < lineCounter; i += 2) + { + DrawLineEx(lines[i].start, lines[i].end, thickness, BLACK); + DrawLineEx(lines[i + 1].start, lines[i + 1].end, thickness, BLACK); } } - - prevMousePos = mousePos; EndMode2D(); + + DrawText(TextFormat("LINES: %i/%i", lineCounter, MAX_DRAW_LINES), 10, screenHeight - 30, 20, MAROON); + DrawFPS(10, 10); + EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- From 33cee1146c22e0ef45885d438aec5183845a4e4a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 09:54:54 +0100 Subject: [PATCH 134/189] REXM: REVIEWED: Automated testing for Web --- tools/rexm/rexm.c | 69 ++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 20ceadb91..20bf120ce 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1491,6 +1491,9 @@ int main(int argc, char *argv[]) LOG("INFO: [%i/%i] Testing example: [%s]\n", i + 1, exBuildListCount, exName); + // Create directory for logs (build and run logs) + MakeDirectory(TextFormat("%s/%s/logs", exBasePath, exCategory)); + // Steps to follow // STEP 1: Load example.c and replace required code to inject basic testing code: frames to run // OPTION 1: Code injection required multiple changes for testing but it does not require raylib changes! @@ -1510,7 +1513,7 @@ int main(int argc, char *argv[]) TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); -//#define BUILD_TESTING_WEB +#define BUILD_TESTING_WEB #if defined(BUILD_TESTING_WEB) static const char *mainReplaceText = "#include \n" @@ -1557,13 +1560,14 @@ int main(int argc, char *argv[]) // Build: raylib.com/examples//_example_name.data // Build: raylib.com/examples//_example_name.wasm // Build: raylib.com/examples//_example_name.js -#if defined(_WIN32) + #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName)); -#else + system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1", + exBasePath, exCategory, exName, exBasePath, exCategory, exName)); + #else LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); -#endif + #endif // Restore original source code before continue FileCopy(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName), TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); @@ -1571,7 +1575,7 @@ int main(int argc, char *argv[]) // STEP 3: Run example on browser ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); - system("start python -m http.server 8080"); // TODO: Init localhost just once! + if (i == 0) system("start python -m http.server 8080"); // TODO: Init localhost just once! system(TextFormat("start explorer \"http:\\localhost:8080/%s.html", exName)); // NOTE: Example .log is automatically downloaded into system Downloads directory on browser-example exectution @@ -1595,22 +1599,20 @@ int main(int argc, char *argv[]) SaveFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName), srcTextUpdated[2]); for (int i = 0; i < 3; i++) { MemFree(srcTextUpdated[i]); srcTextUpdated[i] = NULL; } - MakeDirectory(TextFormat("%s/%s/logs", exBasePath, exCategory)); - // STEP 2: Build example for DESKTOP platform -#if defined(_WIN32) + #if defined(_WIN32) // Set required environment variables //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); _putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin"); //putenv("MAKE=mingw32-make"); //ChangeDirectory(exBasePath); -#endif + #endif // Build example for PLATFORM_DESKTOP -#if defined(_WIN32) + #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); -#else + #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); #endif @@ -1623,7 +1625,7 @@ int main(int argc, char *argv[]) // NOTE: Not easy to retrieve process return value from system(), it's platform dependant ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); system(TextFormat("%s --frames 2 > logs/%s.log", exName, exName)); - +#endif // STEP 4: Load and validate log info //--------------------------------------------------------------------------------------------- // Load .build.log to check for compilation warnings @@ -1640,7 +1642,11 @@ int main(int argc, char *argv[]) UnloadTextLines(exTestBuildLogLines, exTestBuildLogLinesCount); UnloadFileText(exTestBuildLog); +#if defined(BUILD_TESTING_WEB) + char *exTestLog = LoadFileText(TextFormat("C:/Users/raysa/Downloads/%s.log", exName)); +#else char *exTestLog = LoadFileText(TextFormat("%s/%s/logs/%s.log", exBasePath, exCategory, exName)); +#endif int exTestLogLinesCount = 0; char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); @@ -1670,11 +1676,27 @@ int main(int argc, char *argv[]) UnloadTextLines(exTestLogLines, exTestLogLinesCount); UnloadFileText(exTestLog); //--------------------------------------------------------------------------------------------- -#endif } // STEP 5: Generate testing report/table with results (.md) //----------------------------------------------------------------------------------------------------- +#if defined(BUILD_TESTING_WEB) + const char *osName = "Web"; +#else + #if defined(PLATFORM_DRM) + const char *osName = "DRM"; + #elif defined(PLATFORM_DESKTOP) + #if defined(_WIN32) + const char *osName = "Windows"; + #elif defined(__linux__) + const char *osName = "Linux"; + #elif defined(__FreeBSD__) + const char *osName = "FreeBSD"; + #elif defined(__APPLE__) + const char *osName = "macOS"; + #endif // Desktop OSs + #endif +#endif /* Columns: - [CWARN] : Compilation WARNING messages @@ -1697,7 +1719,7 @@ int main(int argc, char *argv[]) int repIndex = 0; repIndex += sprintf(report + repIndex, "# EXAMPLES COLLECTION - TESTING REPORT\n\n"); - repIndex += sprintf(report + repIndex, "## Tested Platform: Windows\n\n"); + repIndex += sprintf(report + repIndex, TextFormat("## Tested Platform: %s\n\n", osName)); repIndex += sprintf(report + repIndex, "```\nExample automated testing elements validated:\n"); repIndex += sprintf(report + repIndex, " - [CWARN] : Compilation WARNING messages\n"); @@ -1742,22 +1764,7 @@ int main(int argc, char *argv[]) repIndex += sprintf(report + repIndex, "\n"); -#if defined(PLATFORM_DRM) - const char *osName = "drm"; -#elif defined(PLATFORM_WEB) - const char *osName = "web"; -#elif defined(PLATFORM_DESKTOP) - #if defined(_WIN32) - const char *osName = "windows"; - #elif defined(__linux__) - const char *osName = "linux"; - #elif defined(__FreeBSD__) - const char *osName = "freebsd"; - #elif defined(__APPLE__) - const char *osName = "macos"; - #endif // Desktop OSs -#endif - SaveFileText(TextFormat("%s/../tools/rexm/reports/examples_testing_%s.md", exBasePath, osName), report); + SaveFileText(TextFormat("%s/../tools/rexm/reports/examples_testing_%s.md", exBasePath, TextToLower(osName)), report); RL_FREE(report); //----------------------------------------------------------------------------------------------------- From ec828071ef32d8d9ad62d16708b4bd9f25c5a3cb Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 10:04:01 +0100 Subject: [PATCH 135/189] Update rtext.c --- src/rtext.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rtext.c b/src/rtext.c index 1c70aedc1..9c627559c 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1452,6 +1452,10 @@ Rectangle GetGlyphAtlasRec(Font font, int codepoint) // NOTE: Returned lines end with null terminator '\0' char **LoadTextLines(const char *text, int *count) { + char **lines = NULL; + + if (text == NULL) { *count = 0; return lines; } + int lineCount = 1; int textSize = (int)strlen(text); From f21c1cc6ae4c74ef8cb3a0da8e7a10493a69df71 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 10:08:42 +0100 Subject: [PATCH 136/189] Update rtext.c --- src/rtext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtext.c b/src/rtext.c index 9c627559c..52938e3d2 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1459,13 +1459,13 @@ char **LoadTextLines(const char *text, int *count) int lineCount = 1; int textSize = (int)strlen(text); - // Text pass to get required line count + // First text scan pass to get required line count for (int i = 0; i < textSize; i++) { if (text[i] == '\n') lineCount++; } - char **lines = (char **)RL_CALLOC(lineCount, sizeof(char *)); + lines = (char **)RL_CALLOC(lineCount, sizeof(char *)); for (int i = 0, l = 0, lineLen = 0; i <= textSize; i++) { if ((text[i] == '\n') || (text[i] == '\0')) From 265fa7833ca58617e978b8565e23f5c0e9067ef0 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 10:21:16 +0100 Subject: [PATCH 137/189] Update rtext.c --- src/rtext.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rtext.c b/src/rtext.c index 52938e3d2..009aba044 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1891,6 +1891,7 @@ void TextAppend(char *text, const char *append, int *position) int TextFindIndex(const char *text, const char *search) { int position = -1; + if (text == NULL) return position; char *ptr = (char *)strstr(text, search); From d56371ce85c09e556560fd4358bc5d604b9b8881 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 11:41:50 +0100 Subject: [PATCH 138/189] Update Makefile.Web --- examples/Makefile.Web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 01426d7f5..7a2afc931 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -975,7 +975,7 @@ textures/textures_blend_modes: textures/textures_blend_modes.c textures/textures_bunnymark: textures/textures_bunnymark.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file textures/resources/wabbit_alpha.png@resources/wabbit_alpha.png + --preload-file textures/resources/raybunny.png@resources/raybunny.png textures/textures_fog_of_war: textures/textures_fog_of_war.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) From e3738c1b172880e360f6f7f016802eb44a8b5498 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 11:53:55 +0100 Subject: [PATCH 139/189] REXM: UPDATE: Reviewed all examples requirements --- examples/Makefile | 8 +- examples/Makefile.Web | 31 +- examples/README.md | 21 +- .../audio/audio_fft_spectrum_visualizer.c | 2 +- examples/core/core_3d_camera_fps.c | 4 +- examples/core/core_viewport_scaling.c | 4 +- examples/examples_list.txt | 11 +- .../models/models_directional_billboard.c | 2 +- examples/shapes/shapes_rlgl_color_wheel.c | 2 +- examples/shapes/shapes_rlgl_triangle.c | 2 +- examples/textures/textures_screen_buffer.c | 6 +- examples/textures/textures_sprite_stacking.c | 2 +- .../audio_fft_spectrum_visualizer.vcxproj | 569 ++++++++++++++++++ .../models_directional_billboard.vcxproj | 569 ++++++++++++++++++ .../examples/shapes_rlgl_color_wheel.vcxproj | 569 ++++++++++++++++++ .../examples/shapes_rlgl_triangle.vcxproj | 569 ++++++++++++++++++ .../examples/textures_sprite_stacking.vcxproj | 569 ++++++++++++++++++ projects/VS2022/raylib.sln | 139 ++++- tools/rexm/reports/examples_validation.md | 6 + 19 files changed, 3054 insertions(+), 31 deletions(-) create mode 100644 projects/VS2022/examples/audio_fft_spectrum_visualizer.vcxproj create mode 100644 projects/VS2022/examples/models_directional_billboard.vcxproj create mode 100644 projects/VS2022/examples/shapes_rlgl_color_wheel.vcxproj create mode 100644 projects/VS2022/examples/shapes_rlgl_triangle.vcxproj create mode 100644 projects/VS2022/examples/textures_sprite_stacking.vcxproj diff --git a/examples/Makefile b/examples/Makefile index ccd24bf28..edddb366e 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -587,6 +587,8 @@ SHAPES = \ shapes/shapes_rectangle_scaling \ shapes/shapes_recursive_tree \ shapes/shapes_ring_drawing \ + shapes/shapes_rlgl_color_wheel \ + shapes/shapes_rlgl_triangle \ shapes/shapes_rounded_rectangle_drawing \ shapes/shapes_simple_particles \ shapes/shapes_splines_drawing \ @@ -615,11 +617,12 @@ TEXTURES = \ textures/textures_particles_blending \ textures/textures_polygon_drawing \ textures/textures_raw_data \ + textures/textures_screen_buffer \ textures/textures_sprite_animation \ textures/textures_sprite_button \ textures/textures_sprite_explosion \ + textures/textures_sprite_stacking \ textures/textures_srcrec_dstrec \ - textures/textures_screen_buffer \ textures/textures_textured_curve \ textures/textures_tiled_drawing \ textures/textures_to_image @@ -650,6 +653,7 @@ MODELS = \ models/models_box_collisions \ models/models_cubicmap_rendering \ models/models_decals \ + models/models_directional_billboard \ models/models_first_person_maze \ models/models_geometric_shapes \ models/models_heightmap_rendering \ @@ -704,7 +708,7 @@ SHADERS = \ shaders/shaders_vertex_displacement AUDIO = \ - audio/audio_fft_spectrum_visualizer \ + audio/audio_fft_spectrum_visualizer \ audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 7a2afc931..35024cbd5 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -575,6 +575,8 @@ SHAPES = \ shapes/shapes_rectangle_scaling \ shapes/shapes_recursive_tree \ shapes/shapes_ring_drawing \ + shapes/shapes_rlgl_color_wheel \ + shapes/shapes_rlgl_triangle \ shapes/shapes_rounded_rectangle_drawing \ shapes/shapes_simple_particles \ shapes/shapes_splines_drawing \ @@ -603,11 +605,12 @@ TEXTURES = \ textures/textures_particles_blending \ textures/textures_polygon_drawing \ textures/textures_raw_data \ + textures/textures_screen_buffer \ textures/textures_sprite_animation \ textures/textures_sprite_button \ textures/textures_sprite_explosion \ + textures/textures_sprite_stacking \ textures/textures_srcrec_dstrec \ - textures/textures_screen_buffer \ textures/textures_textured_curve \ textures/textures_tiled_drawing \ textures/textures_to_image @@ -638,6 +641,7 @@ MODELS = \ models/models_box_collisions \ models/models_cubicmap_rendering \ models/models_decals \ + models/models_directional_billboard \ models/models_first_person_maze \ models/models_geometric_shapes \ models/models_heightmap_rendering \ @@ -692,6 +696,7 @@ SHADERS = \ shaders/shaders_vertex_displacement AUDIO = \ + audio/audio_fft_spectrum_visualizer \ audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ @@ -940,6 +945,12 @@ shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +shapes/shapes_rlgl_color_wheel: shapes/shapes_rlgl_color_wheel.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + +shapes/shapes_rlgl_triangle: shapes/shapes_rlgl_triangle.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -1041,6 +1052,9 @@ textures/textures_raw_data: textures/textures_raw_data.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw +textures/textures_screen_buffer: textures/textures_screen_buffer.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + textures/textures_sprite_animation: textures/textures_sprite_animation.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/scarfy.png@resources/scarfy.png @@ -1055,13 +1069,14 @@ textures/textures_sprite_explosion: textures/textures_sprite_explosion.c --preload-file textures/resources/boom.wav@resources/boom.wav \ --preload-file textures/resources/explosion.png@resources/explosion.png +textures/textures_sprite_stacking: textures/textures_sprite_stacking.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file textures/resources/booth.png@resources/booth.png + textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/scarfy.png@resources/scarfy.png -textures/textures_screen_buffer: textures/textures_screen_buffer.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - textures/textures_textured_curve: textures/textures_textured_curve.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file textures/resources/road.png@resources/road.png @@ -1184,6 +1199,10 @@ models/models_decals: models/models_decals.c --preload-file models/resources/models/obj/character_diffuse.png@resources/models/obj/character_diffuse.png \ --preload-file models/resources/raylib_logo.png@resources/raylib_logo.png +models/models_directional_billboard: models/models_directional_billboard.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file models/resources/skillbot.png@resources/skillbot.png + models/models_first_person_maze: models/models_first_person_maze.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file models/resources/cubicmap.png@resources/cubicmap.png \ @@ -1452,6 +1471,10 @@ shaders/shaders_vertex_displacement: shaders/shaders_vertex_displacement.c --preload-file shaders/resources/shaders/glsl100/vertex_displacement.fs@resources/shaders/glsl100/vertex_displacement.fs # Compile AUDIO examples +audio/audio_fft_spectrum_visualizer: audio/audio_fft_spectrum_visualizer.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file audio/resources/country.mp3@resources/country.mp3 + audio/audio_mixed_processor: audio/audio_mixed_processor.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file audio/resources/country.mp3@resources/country.mp3 \ diff --git a/examples/README.md b/examples/README.md index bdf50cb82..41c3c7c01 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: 195] +## EXAMPLES COLLECTION [TOTAL: 200] ### category: core [47] @@ -43,7 +43,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_3d_camera_free](core/core_3d_camera_free.c) | core_3d_camera_free | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) | | [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | core_3d_camera_first_person | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) | | [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) | core_3d_camera_split_screen | ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) | -| [core_3d_camera_fps](core/core_3d_camera_fps.c) | core_3d_camera_fps | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) | +| [core_3d_camera_fps](core/core_3d_camera_fps.c) | core_3d_camera_fps | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) | | [core_3d_picking](core/core_3d_picking.c) | core_3d_picking | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) | | [core_world_screen](core/core_world_screen.c) | core_world_screen | ⭐⭐☆☆ | 1.3 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) | | [core_window_flags](core/core_window_flags.c) | core_window_flags | ⭐⭐⭐☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) | @@ -64,7 +64,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_high_dpi](core/core_high_dpi.c) | core_high_dpi | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) | | [core_render_texture](core/core_render_texture.c) | core_render_texture | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | | [core_undo_redo](core/core_undo_redo.c) | core_undo_redo | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) | -| [core_viewport_scaling](core/core_viewport_scaling.c) | core_viewport_scaling | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) | +| [core_viewport_scaling](core/core_viewport_scaling.c) | core_viewport_scaling | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) | | [core_input_actions](core/core_input_actions.c) | core_input_actions | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) | | [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) | @@ -73,7 +73,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind | [core_text_file_loading](core/core_text_file_loading.c) | core_text_file_loading | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) | | [core_compute_hash](core/core_compute_hash.c) | core_compute_hash | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) | -### category: shapes [34] +### category: shapes [36] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. @@ -113,8 +113,10 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | shapes_starfield_effect | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | | [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | shapes_lines_drawing | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) | | [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | shapes_math_angle_rotation | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) | +| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | shapes_rlgl_color_wheel | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | +| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | shapes_rlgl_triangle | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) | -### category: textures [27] +### category: textures [28] Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module. @@ -145,8 +147,9 @@ Examples using raylib textures functionality, including image/textures loading/g | [textures_image_kernel](textures/textures_image_kernel.c) | textures_image_kernel | ⭐⭐⭐⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) | | [textures_image_channel](textures/textures_image_channel.c) | textures_image_channel | ⭐⭐☆☆ | 5.5 | 5.5 | [Bruno Cabral](https://github.com/brccabral) | | [textures_image_rotate](textures/textures_image_rotate.c) | textures_image_rotate | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) | -| [textures_screen_buffer](textures/textures_screen_buffer.c) | textures_screen_buffer | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) | +| [textures_screen_buffer](textures/textures_screen_buffer.c) | textures_screen_buffer | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) | | [textures_textured_curve](textures/textures_textured_curve.c) | textures_textured_curve | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) | +| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | textures_sprite_stacking | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) | ### category: text [15] @@ -170,7 +173,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat | [text_inline_styling](text/text_inline_styling.c) | text_inline_styling | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) | | [text_words_alignment](text/text_words_alignment.c) | text_words_alignment | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) | -### category: models [26] +### category: models [27] Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module. @@ -202,6 +205,7 @@ Examples using raylib models functionality, including models loading/generation | [models_basic_voxel](models/models_basic_voxel.c) | models_basic_voxel | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) | | [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) | ### category: shaders [32] @@ -242,7 +246,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) | -### category: audio [8] +### category: audio [9] 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. @@ -256,6 +260,7 @@ Examples using raylib audio functionality, including sound/music loading and pla | [audio_stream_effects](audio/audio_stream_effects.c) | audio_stream_effects | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) | | [audio_sound_multi](audio/audio_sound_multi.c) | audio_sound_multi | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) | | [audio_sound_positioning](audio/audio_sound_positioning.c) | audio_sound_positioning | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) | +| [audio_fft_spectrum_visualizer](audio/audio_fft_spectrum_visualizer.c) | audio_fft_spectrum_visualizer | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) | ### category: others [6] diff --git a/examples/audio/audio_fft_spectrum_visualizer.c b/examples/audio/audio_fft_spectrum_visualizer.c index ad38020fd..299b610ee 100644 --- a/examples/audio/audio_fft_spectrum_visualizer.c +++ b/examples/audio/audio_fft_spectrum_visualizer.c @@ -4,7 +4,7 @@ * * Example complexity rating: [★★★☆] 3/4 * -* Example originally created with raylib 6.0 +* Example originally created with raylib 6.0, last time updated with raylib 5.6-dev * * Inspired by Inigo Quilez's https://www.shadertoy.com/ * Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8 diff --git a/examples/core/core_3d_camera_fps.c b/examples/core/core_3d_camera_fps.c index 7aa79c174..ef36e912f 100644 --- a/examples/core/core_3d_camera_fps.c +++ b/examples/core/core_3d_camera_fps.c @@ -6,12 +6,12 @@ * * Example originally created with raylib 5.5, last time updated with raylib 5.5 * -* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5) +* Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2025 Agnis Aldins (@nezvers) +* Copyright (c) 2025 Agnis Aldiņš (@nezvers) * ********************************************************************************************/ diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index 59e0bd026..3044dd0af 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -6,12 +6,12 @@ * * Example originally created with raylib 5.5, last time updated with raylib 5.5 * -* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5) +* Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2025 Agnis Aldins (@nezvers) +* Copyright (c) 2025 Agnis Aldiņš (@nezvers) * ********************************************************************************************/ diff --git a/examples/examples_list.txt b/examples/examples_list.txt index 4e7130d7d..b6223e09a 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -25,7 +25,7 @@ core;core_3d_camera_mode;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@rays core;core_3d_camera_free;★☆☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5 core;core_3d_camera_first_person;★★☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5 core;core_3d_camera_split_screen;★★★☆;3.7;4.0;2021;2025;"Jeffery Myers";@JeffM2501 -core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldins";@nezvers +core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers core;core_3d_picking;★★☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5 core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan5 core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5 @@ -46,7 +46,7 @@ core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@r core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997 core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5 -core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldins";@nezvers +core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5 @@ -88,6 +88,8 @@ shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@ shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@krispy-snacc +shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary +shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary 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 @@ -113,8 +115,9 @@ textures;textures_gif_player;★★★☆;4.2;4.2;2021;2025;"Ramon Santamaria";@ textures;textures_image_kernel;★★★★;1.3;1.3;2015;2025;"Karim Salem";@kimo-s textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@brccabral textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5 -textures;textures_screen_buffer;★★☆☆;5.5;5.5;2014;2025;"Agnis Aldins";@nezvers +textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501 +textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary 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 @@ -156,6 +159,7 @@ models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van 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 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 @@ -196,6 +200,7 @@ audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5 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_fft_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 diff --git a/examples/models/models_directional_billboard.c b/examples/models/models_directional_billboard.c index fe1b33b2d..f471da4d0 100644 --- a/examples/models/models_directional_billboard.c +++ b/examples/models/models_directional_billboard.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) 2025-2025 Robin (@RobinsAviary) +* Copyright (c) 2025 Robin (@RobinsAviary) * Killbot art by patvanmackelberg https://opengameart.org/content/killbot-8-directional under CC0 * ********************************************************************************************/ diff --git a/examples/shapes/shapes_rlgl_color_wheel.c b/examples/shapes/shapes_rlgl_color_wheel.c index 323a08956..47ae5f7a4 100644 --- a/examples/shapes/shapes_rlgl_color_wheel.c +++ b/examples/shapes/shapes_rlgl_color_wheel.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) 2025-2025 Robin (@RobinsAviary) +* Copyright (c) 2025 Robin (@RobinsAviary) * ********************************************************************************************/ diff --git a/examples/shapes/shapes_rlgl_triangle.c b/examples/shapes/shapes_rlgl_triangle.c index 1ce8e7949..37626a5c8 100644 --- a/examples/shapes/shapes_rlgl_triangle.c +++ b/examples/shapes/shapes_rlgl_triangle.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) 2025-2025 Robin (@RobinsAviary) +* Copyright (c) 2025 Robin (@RobinsAviary) * ********************************************************************************************/ diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c index f5e67f20c..4c737901b 100644 --- a/examples/textures/textures_screen_buffer.c +++ b/examples/textures/textures_screen_buffer.c @@ -1,10 +1,10 @@ /******************************************************************************************* * -* raylib [textures] example - screen buffer / update Image as screen buffer and display with texture +* raylib [textures] example - screen buffer * * Example complexity rating: [★★☆☆] 2/4 * -* Example originally created with raylib 5.5, last time updated with raylib 5.6 +* Example originally created with raylib 5.5, last time updated with raylib 5.5 * * Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5) * @@ -40,7 +40,7 @@ int main(void) const int pixelScale = SCALE_FACTOR; const int imageWidth = screenWidth / pixelScale; const int imageHeight = screenHeight / pixelScale; - InitWindow(screenWidth, screenHeight, "raylib [] example - "); + InitWindow(screenWidth, screenHeight, "raylib [textures] example - screen buffer"); Color palette[MAX_COLORS] = {0}; unsigned char indexBuffer[INDEX_BUFFER_SIZE] = {0}; diff --git a/examples/textures/textures_sprite_stacking.c b/examples/textures/textures_sprite_stacking.c index 793a83699..a2cb04d2f 100644 --- a/examples/textures/textures_sprite_stacking.c +++ b/examples/textures/textures_sprite_stacking.c @@ -12,7 +12,7 @@ * BSD-like license that allows static linking with closed source software * * Redbooth model (c) 2017-2025 @kluchek under https://creativecommons.org/licenses/by/4.0/ https://github.com/kluchek/vox-models/ -* Copyright (c) 2025-2025 Robin (@RobinsAviary) +* Copyright (c) 2025 Robin (@RobinsAviary) * ********************************************************************************************/ diff --git a/projects/VS2022/examples/audio_fft_spectrum_visualizer.vcxproj b/projects/VS2022/examples/audio_fft_spectrum_visualizer.vcxproj new file mode 100644 index 000000000..d7c6d8d3f --- /dev/null +++ b/projects/VS2022/examples/audio_fft_spectrum_visualizer.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 + + + + {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68} + Win32Proj + audio_fft_spectrum_visualizer + 10.0 + audio_fft_spectrum_visualizer + + + + 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\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\audio + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/models_directional_billboard.vcxproj b/projects/VS2022/examples/models_directional_billboard.vcxproj new file mode 100644 index 000000000..2e6c0e8b2 --- /dev/null +++ b/projects/VS2022/examples/models_directional_billboard.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 + + + + {30011884-25EE-42C9-BB15-888CAFB1AA6E} + Win32Proj + models_directional_billboard + 10.0 + models_directional_billboard + + + + 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/examples/shapes_rlgl_color_wheel.vcxproj b/projects/VS2022/examples/shapes_rlgl_color_wheel.vcxproj new file mode 100644 index 000000000..b22703577 --- /dev/null +++ b/projects/VS2022/examples/shapes_rlgl_color_wheel.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 + + + + {32FE2658-1D70-442E-8672-0AC5C6F0BD7B} + Win32Proj + shapes_rlgl_color_wheel + 10.0 + shapes_rlgl_color_wheel + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/shapes_rlgl_triangle.vcxproj b/projects/VS2022/examples/shapes_rlgl_triangle.vcxproj new file mode 100644 index 000000000..780f514a0 --- /dev/null +++ b/projects/VS2022/examples/shapes_rlgl_triangle.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 + + + + {842B6472-4AA6-4C2B-A5E5-A62F80DE2C4F} + Win32Proj + shapes_rlgl_triangle + 10.0 + shapes_rlgl_triangle + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shapes + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/examples/textures_sprite_stacking.vcxproj b/projects/VS2022/examples/textures_sprite_stacking.vcxproj new file mode 100644 index 000000000..a3e5be045 --- /dev/null +++ b/projects/VS2022/examples/textures_sprite_stacking.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 + + + + {FC4DEBD2-4B17-4534-8EEA-BB24A2DBEB5F} + Win32Proj + textures_sprite_stacking + 10.0 + textures_sprite_stacking + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\textures + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index f7bbf1641..4af8d0539 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -411,6 +411,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_compute_hash", "exampl 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_fft_spectrum_visualizer", "examples\audio_fft_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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug.DLL|ARM64 = Debug.DLL|ARM64 @@ -5105,6 +5115,126 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -5272,7 +5402,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} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {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} @@ -5299,7 +5429,7 @@ Global {124935CC-73BB-489E-92E8-4F922A85DB5D} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {AC215730-2B5F-4498-B7F5-5DB80AEFCA5F} = {278D8859-20B1-428F-8448-064F46E1F021} {0835E6BF-0170-4E99-A55C-E06E1EF4C3B2} = {278D8859-20B1-428F-8448-064F46E1F021} - {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {278D8859-20B1-428F-8448-064F46E1F021} + {EA4AD5A7-DB95-43C0-9A67-2D94146BCF91} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE} {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} @@ -5312,6 +5442,11 @@ Global {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} 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 e3d64137b..79fdf05f9 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -101,6 +101,8 @@ Example elements validated: | shapes_starfield_effect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_lines_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_math_angle_rotation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rlgl_color_wheel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rlgl_triangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -126,7 +128,9 @@ Example elements validated: | textures_image_kernel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_channel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_image_rotate | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_screen_buffer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_sprite_stacking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_sprite_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -168,6 +172,7 @@ Example elements validated: | models_basic_voxel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_rotating_cube | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_decals | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_directional_billboard | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_ascii_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -208,6 +213,7 @@ Example elements validated: | audio_stream_effects | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| audio_fft_spectrum_visualizer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 5fdf178969315e9cd4eb594d017fb22fdddf69e1 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 12:30:38 +0100 Subject: [PATCH 140/189] REVIEWED: audio_fft_spectrum_visualizer, not working on web --- .../audio/audio_fft_spectrum_visualizer.c | 43 +++++++++++-------- examples/audio/resources/fft.glsl | 32 -------------- .../audio/resources/shaders/glsl100/fft.fs | 37 ++++++++++++++++ .../audio/resources/shaders/glsl120/fft.fs | 35 +++++++++++++++ .../audio/resources/shaders/glsl330/fft.fs | 35 +++++++++++++++ 5 files changed, 133 insertions(+), 49 deletions(-) delete mode 100644 examples/audio/resources/fft.glsl create mode 100644 examples/audio/resources/shaders/glsl100/fft.fs create mode 100644 examples/audio/resources/shaders/glsl120/fft.fs create mode 100644 examples/audio/resources/shaders/glsl330/fft.fs diff --git a/examples/audio/audio_fft_spectrum_visualizer.c b/examples/audio/audio_fft_spectrum_visualizer.c index 299b610ee..c667b5d6a 100644 --- a/examples/audio/audio_fft_spectrum_visualizer.c +++ b/examples/audio/audio_fft_spectrum_visualizer.c @@ -19,11 +19,19 @@ ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" + #include #include #include +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + #define MONO 1 #define SAMPLE_RATE 44100 #define SAMPLE_RATE_F 44100.0f @@ -77,7 +85,8 @@ int main(void) RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight); Vector2 iResolution = { (float)screenWidth, (float)screenHeight }; - Shader shader = LoadShader(NULL, "resources/fft.glsl"); + Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION)); + int iResolutionLocation = GetShaderLocation(shader, "iResolution"); int iChannel0Location = GetShaderLocation(shader, "iChannel0"); SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2); @@ -86,6 +95,7 @@ int main(void) InitAudioDevice(); SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE); + // WARNING: Memory out-of-bounds on PLATFORM_WEB Wave wav = LoadWave("resources/country.mp3"); WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO); @@ -95,10 +105,10 @@ int main(void) int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1; FFTData fft = { - .spectrum = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE), - .workBuffer = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE), - .prevMagnitudes = calloc(BUFFER_SIZE, sizeof(float)), - .fftHistory = calloc(fftHistoryLen, sizeof(float[BUFFER_SIZE])), + .spectrum = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE), + .workBuffer = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE), + .prevMagnitudes = RL_CALLOC(BUFFER_SIZE, sizeof(float)), + .fftHistory = RL_CALLOC(fftHistoryLen, sizeof(float[BUFFER_SIZE])), .fftHistoryLen = fftHistoryLen, .historyPos = 0, .lastFftTime = 0.0, @@ -127,15 +137,12 @@ int main(void) int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left; chunkSamples[i] = (short)((left + right)/2); - if (++wavCursor >= wav.frameCount) - wavCursor = 0; - + if (++wavCursor >= wav.frameCount) wavCursor = 0; } UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE); - for (int i = 0; i < FFT_WINDOW_SIZE; i++) - audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f; + for (int i = 0; i < FFT_WINDOW_SIZE; i++) audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f; } CaptureFrame(&fft, audioSamples); @@ -146,14 +153,16 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(BLACK); + + ClearBackground(RAYWHITE); + BeginShaderMode(shader); SetShaderValueTexture(shader, iChannel0Location, fftTexture); DrawTextureRec(bufferA.texture, (Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight }, - (Vector2){ 0, 0 }, - WHITE); + (Vector2){ 0, 0 }, WHITE); EndShaderMode(); + EndDrawing(); //------------------------------------------------------------------------------ } @@ -168,10 +177,10 @@ int main(void) UnloadWave(wav); CloseAudioDevice(); - free(fft.spectrum); - free(fft.workBuffer); - free(fft.prevMagnitudes); - free(fft.fftHistory); + RL_FREE(fft.spectrum); + RL_FREE(fft.workBuffer); + RL_FREE(fft.prevMagnitudes); + RL_FREE(fft.fftHistory); CloseWindow(); // Close window and OpenGL context //---------------------------------------------------------------------------------- diff --git a/examples/audio/resources/fft.glsl b/examples/audio/resources/fft.glsl deleted file mode 100644 index 95fd4b38f..000000000 --- a/examples/audio/resources/fft.glsl +++ /dev/null @@ -1,32 +0,0 @@ -#version 330 - -in vec2 fragTexCoord; -in vec4 fragColor; - -out vec4 finalColor; - -uniform vec2 iResolution; -uniform sampler2D iChannel0; - -const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0); -const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0); -const float FFT_ROW = 0.0; -const float NUM_OF_BINS = 512.0; - -void main() { - vec2 fragCoord = fragTexCoord*iResolution; - float cell_width = iResolution.x/NUM_OF_BINS; - float bin_index = floor(fragCoord.x/cell_width); - float local_x = mod(fragCoord.x, cell_width); - float bar_width = cell_width - 1.0; - vec4 color = BLACK; - if (local_x <= bar_width) { - float sample_x = (bin_index + 0.5)/NUM_OF_BINS; - vec2 sample_coord = vec2(sample_x, FFT_ROW); - float amplitude = texture(iChannel0, sample_coord).r; // only filled the red channel, all channels left open for alternative use - if (fragTexCoord.y < amplitude) { - color = WHITE; - } - } - finalColor = color; -} diff --git a/examples/audio/resources/shaders/glsl100/fft.fs b/examples/audio/resources/shaders/glsl100/fft.fs new file mode 100644 index 000000000..a97bf336b --- /dev/null +++ b/examples/audio/resources/shaders/glsl100/fft.fs @@ -0,0 +1,37 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform vec2 iResolution; +uniform sampler2D iChannel0; + +const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0); +const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0); +const float FFT_ROW = 0.0; +const float NUM_OF_BINS = 512.0; + +void main() +{ + vec2 fragCoord = fragTexCoord*iResolution; + float cellWidth = iResolution.x/NUM_OF_BINS; + float binIndex = floor(fragCoord.x/cellWidth); + float localX = mod(fragCoord.x, cellWidth); + float barWidth = cellWidth - 1.0; + vec4 color = WHITE; + + if (localX <= barWidth) + { + float sampleX = (binIndex + 0.5)/NUM_OF_BINS; + vec2 sampleCoord = vec2(sampleX, FFT_ROW); + float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use + + if (fragTexCoord.y < amplitude) color = BLACK; + } + + gl_FragColor = color; +} diff --git a/examples/audio/resources/shaders/glsl120/fft.fs b/examples/audio/resources/shaders/glsl120/fft.fs new file mode 100644 index 000000000..bab5d533b --- /dev/null +++ b/examples/audio/resources/shaders/glsl120/fft.fs @@ -0,0 +1,35 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform vec2 iResolution; +uniform sampler2D iChannel0; + +const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0); +const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0); +const float FFT_ROW = 0.0; +const float NUM_OF_BINS = 512.0; + +void main() +{ + vec2 fragCoord = fragTexCoord*iResolution; + float cellWidth = iResolution.x/NUM_OF_BINS; + float binIndex = floor(fragCoord.x/cellWidth); + float localX = mod(fragCoord.x, cellWidth); + float barWidth = cellWidth - 1.0; + vec4 color = WHITE; + + if (localX <= barWidth) + { + float sampleX = (binIndex + 0.5)/NUM_OF_BINS; + vec2 sampleCoord = vec2(sampleX, FFT_ROW); + float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use + + if (fragTexCoord.y < amplitude) color = BLACK; + } + + gl_FragColor = color; +} diff --git a/examples/audio/resources/shaders/glsl330/fft.fs b/examples/audio/resources/shaders/glsl330/fft.fs new file mode 100644 index 000000000..20b2e9dfa --- /dev/null +++ b/examples/audio/resources/shaders/glsl330/fft.fs @@ -0,0 +1,35 @@ +#version 330 + +in vec2 fragTexCoord; +in vec4 fragColor; + +out vec4 finalColor; + +uniform vec2 iResolution; +uniform sampler2D iChannel0; + +const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0); +const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0); +const float FFT_ROW = 0.0; +const float NUM_OF_BINS = 512.0; + +void main() +{ + vec2 fragCoord = fragTexCoord*iResolution; + float cellWidth = iResolution.x/NUM_OF_BINS; + float binIndex = floor(fragCoord.x/cellWidth); + float localX = mod(fragCoord.x, cellWidth); + float barWidth = cellWidth - 1.0; + vec4 color = WHITE; + + if (localX <= barWidth) + { + float sampleX = (binIndex + 0.5)/NUM_OF_BINS; + vec2 sampleCoord = vec2(sampleX, FFT_ROW); + float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use + + if (fragTexCoord.y < amplitude) color = BLACK; + } + + finalColor = color; +} From 39e39216f6599309e9b1a9c9b09dc115c06899e5 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 12:31:15 +0100 Subject: [PATCH 141/189] REXM: ADDED: TestLog option for logs processing (without rebuilding) --- tools/rexm/rexm.c | 60 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 20bf120ce..80dd9f8c8 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -141,7 +141,8 @@ typedef enum { OP_VALIDATE = 5, // Validate examples, using [examples_list.txt] as main source by default OP_UPDATE = 6, // Validate and update required examples (as far as possible): ALL OP_BUILD = 7, // Build example(s) for desktop and web, copy web output - Multiple examples supported - OP_TEST = 8, // Test example(s), checking output log "WARNING" - Multiplee examples supported + OP_TEST = 8, // Test example(s), checking output log "WARNING" - Multiple examples supported + 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" }; @@ -403,7 +404,7 @@ int main(int argc, char *argv[]) opCode = OP_UPDATE; } - else if ((strcmp(argv[1], "build") == 0) || (strcmp(argv[1], "test") == 0)) + else if ((strcmp(argv[1], "build") == 0) || (strcmp(argv[1], "test") == 0) || (strcmp(argv[1], "testlog") == 0)) { // Build/Test example(s) for PLATFORM_DESKTOP and PLATFORM_WEB // NOTE: Build outputs to default directory, usually where the .c file is located, @@ -431,7 +432,12 @@ int main(int argc, char *argv[]) UnloadExampleData(exBuildListInfo); if (exBuildListCount == 0) LOG("WARNING: BUILD: Example requested not available in the collection\n"); - else opCode = OP_TEST; + else + { + if (strcmp(argv[1], "build") == 0) opCode = OP_BUILD; + else if (strcmp(argv[1], "test") == 0) opCode = OP_TEST; + else if (strcmp(argv[1], "testlog") == 0) opCode = OP_TESTLOG; + } } } @@ -1459,8 +1465,6 @@ int main(int argc, char *argv[]) LOG("INFO: Command requested: TEST\n"); LOG("INFO: Example(s) to be build and tested: %i [%s]\n", exBuildListCount, (exBuildListCount == 1)? exBuildList[0] : argv[2]); - rlExampleTesting *testing = (rlExampleTesting *)RL_CALLOC(exBuildListCount, sizeof(rlExampleTesting)); - #if defined(_WIN32) // Set required environment variables //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath)); @@ -1574,9 +1578,11 @@ int main(int argc, char *argv[]) FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); // STEP 3: Run example on browser - ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); - if (i == 0) system("start python -m http.server 8080"); // TODO: Init localhost just once! - system(TextFormat("start explorer \"http:\\localhost:8080/%s.html", 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 @@ -1626,10 +1632,34 @@ int main(int argc, char *argv[]) ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); system(TextFormat("%s --frames 2 > logs/%s.log", exName, exName)); #endif - // STEP 4: Load and validate log info - //--------------------------------------------------------------------------------------------- + } + } break; + case OP_TESTLOG: + { + // STEP 4: Load and validate available logs info + //--------------------------------------------------------------------------------------------- + rlExampleTesting *testing = (rlExampleTesting *)RL_CALLOC(exBuildListCount, sizeof(rlExampleTesting)); + + for (int i = 0; i < exBuildListCount; i++) + { + // Get example name and category + memset(exName, 0, 64); + strcpy(exName, exBuildList[i]); + memset(exCategory, 0, 32); + strncpy(exCategory, exName, TextFindIndex(exName, "_")); + + // Skip some examples from building + if ((strcmp(exName, "core_custom_logging") == 0) || + (strcmp(exName, "core_window_should_close") == 0) || + (strcmp(exName, "core_custom_frame_control") == 0)) continue; + + LOG("INFO: [%i/%i] Checking example log: [%s]\n", i + 1, exBuildListCount, exName); + // Load .build.log to check for compilation warnings char *exTestBuildLog = LoadFileText(TextFormat("%s/%s/logs/%s.build.log", exBasePath, exCategory, exName)); + if (exTestBuildLog == NULL) continue; + + // Load build log text lines int exTestBuildLogLinesCount = 0; char **exTestBuildLogLines = LoadTextLines(exTestBuildLog, &exTestBuildLogLinesCount); @@ -1647,9 +1677,12 @@ int main(int argc, char *argv[]) #else char *exTestLog = LoadFileText(TextFormat("%s/%s/logs/%s.log", exBasePath, exCategory, exName)); #endif + if (exTestLog == NULL) continue; + + // Load build log text lines int exTestLogLinesCount = 0; char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); - + /* TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" TESTING_FAIL_CLOSE = 1 << 1, // Closing (CloseWindow()) -> "INFO: Window closed successfully" @@ -1670,13 +1703,14 @@ int main(int argc, char *argv[]) for (int k = 0, index = 0; k < exTestLogLinesCount; k++) { + if (TextFindIndex(exTestLogLines[k], "WARNING: GL: NPOT") >= 0) continue; // Ignore warning if (TextFindIndex(exTestLogLines[k], "WARNING") >= 0) testing[i].warnings++; } UnloadTextLines(exTestLogLines, exTestLogLinesCount); UnloadFileText(exTestLog); - //--------------------------------------------------------------------------------------------- } + //--------------------------------------------------------------------------------------------- // STEP 5: Generate testing report/table with results (.md) //----------------------------------------------------------------------------------------------------- @@ -2024,7 +2058,7 @@ static int UpdateRequiredFiles(void) { mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, TextFormat("\n### category: core [%i]\n\n", exCollectionCount)); mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, - "Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.\n\n"); + "Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality.\n\n"); } else if (i == 1) // "shapes" { From a6976b1930c006a22e5bd8c4e3c5c3dcd7e7a640 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 12:33:49 +0100 Subject: [PATCH 142/189] Create examples_testing_web.md --- tools/rexm/reports/examples_testing_web.md | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tools/rexm/reports/examples_testing_web.md diff --git a/tools/rexm/reports/examples_testing_web.md b/tools/rexm/reports/examples_testing_web.md new file mode 100644 index 000000000..2aedfd180 --- /dev/null +++ b/tools/rexm/reports/examples_testing_web.md @@ -0,0 +1,47 @@ +# EXAMPLES COLLECTION - TESTING REPORT + +## Tested Platform: Web + +``` +Example automated testing elements validated: + - [CWARN] : Compilation WARNING messages + - [LWARN] : Log WARNING messages count + - [INIT] : Initialization + - [CLOSE] : Closing + - [ASSETS] : Assets loading + - [RLGL] : OpenGL-wrapped initialization + - [PLAT] : Platform initialization + - [FONT] : Font default initialization + - [TIMER] : Timer initialization +``` +| **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | +|:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| core_monitor_detector | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_directory_files | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_clipboard_text | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_compute_hash | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_recursive_tree | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_ring_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_circle_sector_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rounded_rectangle_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_splines_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_triangle_strip | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_pie_chart | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_math_sine_cosine | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rlgl_color_wheel | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | +| text_sprite_fonts | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| text_font_loading | 0 | 3 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | +| text_font_sdf | 0 | 22 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | +| models_mesh_generation | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_loading_gltf | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| models_bone_socket | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| shaders_postprocessing | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| shaders_color_correction | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_deferred_rendering | 0 | 2 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shaders_shadowmap_rendering | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| shaders_basic_pbr | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| audio_module_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | + From 313659d37d932ac4cc9798d4f062ddafbe533a24 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 12:40:59 +0100 Subject: [PATCH 143/189] Update examples_testing_web.md --- tools/rexm/reports/examples_testing_web.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/rexm/reports/examples_testing_web.md b/tools/rexm/reports/examples_testing_web.md index 2aedfd180..e969c48aa 100644 --- a/tools/rexm/reports/examples_testing_web.md +++ b/tools/rexm/reports/examples_testing_web.md @@ -28,7 +28,9 @@ Example automated testing elements validated: | shapes_triangle_strip | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_pie_chart | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_math_sine_cosine | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_lines_drawing | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | shapes_rlgl_color_wheel | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_screen_buffer | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_sprite_fonts | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_font_loading | 0 | 3 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | @@ -37,11 +39,15 @@ Example automated testing elements validated: | models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | models_mesh_generation | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_loading_gltf | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| models_loading_vox | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | models_bone_socket | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | +| models_decals | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | shaders_postprocessing | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | shaders_color_correction | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_deferred_rendering | 0 | 2 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_shadowmap_rendering | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | shaders_basic_pbr | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | audio_module_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | +| audio_sound_positioning | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| audio_fft_spectrum_visualizer | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | From 43bd2b1e18489ded5142a0af1113889e15e69826 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 12:41:36 +0100 Subject: [PATCH 144/189] REXM: Report issues if logs can not be loaded --- tools/rexm/rexm.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 80dd9f8c8..89f0145d0 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1657,7 +1657,11 @@ int main(int argc, char *argv[]) // Load .build.log to check for compilation warnings char *exTestBuildLog = LoadFileText(TextFormat("%s/%s/logs/%s.build.log", exBasePath, exCategory, exName)); - if (exTestBuildLog == NULL) continue; + if (exTestBuildLog == NULL) + { + LOG("WARNING: [%s] Build log could not be loaded\n", exName); + continue; + } // Load build log text lines int exTestBuildLogLinesCount = 0; @@ -1677,11 +1681,12 @@ int main(int argc, char *argv[]) #else char *exTestLog = LoadFileText(TextFormat("%s/%s/logs/%s.log", exBasePath, exCategory, exName)); #endif - if (exTestLog == NULL) continue; - - // Load build log text lines - int exTestLogLinesCount = 0; - char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); + if (exTestLog == NULL) + { + LOG("WARNING: [%s] Execution log could not be loaded\n", exName); + testing[i].status = 0b1111111; + continue; + } /* TESTING_FAIL_INIT = 1 << 0, // Initialization (InitWindow()) -> "INFO: DISPLAY: Device initialized successfully" @@ -1701,12 +1706,14 @@ int main(int argc, char *argv[]) if (TextFindIndex(exTestLog, "INFO: FONT: Default font loaded successfully") == -1) testing[i].status |= TESTING_FAIL_FONT; if (TextFindIndex(exTestLog, "INFO: TIMER: Target time per frame:") == -1) testing[i].status |= TESTING_FAIL_TIMER; + // Load build log text lines + int exTestLogLinesCount = 0; + char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); for (int k = 0, index = 0; k < exTestLogLinesCount; k++) { if (TextFindIndex(exTestLogLines[k], "WARNING: GL: NPOT") >= 0) continue; // Ignore warning if (TextFindIndex(exTestLogLines[k], "WARNING") >= 0) testing[i].warnings++; } - UnloadTextLines(exTestLogLines, exTestLogLinesCount); UnloadFileText(exTestLog); } From e1d5adb326a06c4a9aeaa2301cf8d920e5206242 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 12:43:44 +0100 Subject: [PATCH 145/189] Update rexm.c --- tools/rexm/rexm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 89f0145d0..4b5a7dcc7 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1677,7 +1677,8 @@ int main(int argc, char *argv[]) UnloadFileText(exTestBuildLog); #if defined(BUILD_TESTING_WEB) - char *exTestLog = LoadFileText(TextFormat("C:/Users/raysa/Downloads/%s.log", exName)); + // TODO: REVIEW: Hardcoded path where web logs are copied after automatic download + char *exTestLog = LoadFileText(TextFormat("D:/testing_logs_web/%s.log", exName)); #else char *exTestLog = LoadFileText(TextFormat("%s/%s/logs/%s.log", exBasePath, exCategory, exName)); #endif From 80e164fa045812883000b01d306352fbd9d1bf65 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:07:45 +0100 Subject: [PATCH 146/189] Update core_monitor_detector.c --- examples/core/core_monitor_detector.c | 37 ++++++++++----------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/examples/core/core_monitor_detector.c b/examples/core/core_monitor_detector.c index 0e94f6895..08e06c811 100644 --- a/examples/core/core_monitor_detector.c +++ b/examples/core/core_monitor_detector.c @@ -40,10 +40,9 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - MonitorInfo monitors[MAX_MONITORS] = { 0 }; - InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector"); + MonitorInfo monitors[MAX_MONITORS] = { 0 }; int currentMonitorIndex = GetCurrentMonitor(); int monitorCount = 0; @@ -55,7 +54,6 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // Variables to find the max x and Y to calculate the scale int maxWidth = 1; int maxHeight = 1; @@ -76,7 +74,8 @@ int main(void) GetMonitorPhysicalHeight(i), GetMonitorRefreshRate(i) }; - if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = (int)monitors[i].position.x*-1; + + if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = -(int)monitors[i].position.x; const int width = (int)monitors[i].position.x + monitors[i].width; const int height = (int)monitors[i].position.y + monitors[i].height; @@ -85,25 +84,22 @@ int main(void) if (maxHeight < height) maxHeight = height; } - if (IsKeyPressed(KEY_ENTER) && monitorCount > 1) + if (IsKeyPressed(KEY_ENTER) && (monitorCount > 1)) { currentMonitorIndex += 1; // Set index to 0 if the last one - if(currentMonitorIndex == monitorCount) currentMonitorIndex = 0; + if (currentMonitorIndex == monitorCount) currentMonitorIndex = 0; SetWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex } - else - { - // Get currentMonitorIndex if manually moved - currentMonitorIndex = GetCurrentMonitor(); - } + else currentMonitorIndex = GetCurrentMonitor(); // Get currentMonitorIndex if manually moved float monitorScale = 0.6f; - - if(maxHeight > maxWidth + monitorOffsetX) monitorScale *= ((float)screenHeight/(float)maxHeight); + + if (maxHeight > (maxWidth + monitorOffsetX)) monitorScale *= ((float)screenHeight/(float)maxHeight); else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX)); + //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- @@ -120,10 +116,10 @@ int main(void) { // Calculate retangle position and size using monitorScale const Rectangle rec = (Rectangle){ - (monitors[i].position.x + monitorOffsetX) * monitorScale + 140, - monitors[i].position.y * monitorScale + 80, - monitors[i].width * monitorScale, - monitors[i].height * monitorScale + (monitors[i].position.x + monitorOffsetX)*monitorScale + 140, + monitors[i].position.y*monitorScale + 80, + monitors[i].width*monitorScale, + monitors[i].height*monitorScale }; // Draw monitor name and information inside the rectangle @@ -148,14 +144,9 @@ int main(void) // Draw window position based on monitors DrawRectangleV(windowPosition, (Vector2){screenWidth * monitorScale, screenHeight * monitorScale}, Fade(GREEN, 0.5)); } - else - { - DrawRectangleLinesEx(rec, 5, GRAY); - } - + else DrawRectangleLinesEx(rec, 5, GRAY); } - EndDrawing(); //---------------------------------------------------------------------------------- } From 63fb407dc5e8f28570aab7c0f7e48acc8caa7742 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:07:57 +0100 Subject: [PATCH 147/189] Update raygui to avoid warnings --- examples/core/raygui.h | 9 +-------- examples/shaders/raygui.h | 9 +-------- examples/shapes/raygui.h | 9 +-------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/examples/core/raygui.h b/examples/core/raygui.h index f86247ac4..88fe5cc5b 100644 --- a/examples/core/raygui.h +++ b/examples/core/raygui.h @@ -5079,25 +5079,18 @@ static const char **GetTextLines(const char *text, int *count) int textSize = (int)strlen(text); lines[0] = text; - int len = 0; *count = 1; - //int lineSize = 0; // Stores current line size, not returned for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { if (text[i] == '\n') { - //lineSize = len; k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? - len = 0; + lines[k] = &text[i + 1]; // WARNING: next value is valid? *count += 1; } - else len++; } - //lines[*count - 1].size = len; - return lines; } diff --git a/examples/shaders/raygui.h b/examples/shaders/raygui.h index f86247ac4..88fe5cc5b 100644 --- a/examples/shaders/raygui.h +++ b/examples/shaders/raygui.h @@ -5079,25 +5079,18 @@ static const char **GetTextLines(const char *text, int *count) int textSize = (int)strlen(text); lines[0] = text; - int len = 0; *count = 1; - //int lineSize = 0; // Stores current line size, not returned for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { if (text[i] == '\n') { - //lineSize = len; k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? - len = 0; + lines[k] = &text[i + 1]; // WARNING: next value is valid? *count += 1; } - else len++; } - //lines[*count - 1].size = len; - return lines; } diff --git a/examples/shapes/raygui.h b/examples/shapes/raygui.h index f86247ac4..88fe5cc5b 100644 --- a/examples/shapes/raygui.h +++ b/examples/shapes/raygui.h @@ -5079,25 +5079,18 @@ static const char **GetTextLines(const char *text, int *count) int textSize = (int)strlen(text); lines[0] = text; - int len = 0; *count = 1; - //int lineSize = 0; // Stores current line size, not returned for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++) { if (text[i] == '\n') { - //lineSize = len; k++; - lines[k] = &text[i + 1]; // WARNING: next value is valid? - len = 0; + lines[k] = &text[i + 1]; // WARNING: next value is valid? *count += 1; } - else len++; } - //lines[*count - 1].size = len; - return lines; } From 4cef89cf04a25d675fc490c0b1a245d983de5f98 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:08:02 +0100 Subject: [PATCH 148/189] Update rexm.c --- tools/rexm/rexm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 4b5a7dcc7..5c89a9233 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1667,7 +1667,7 @@ int main(int argc, char *argv[]) int exTestBuildLogLinesCount = 0; char **exTestBuildLogLines = LoadTextLines(exTestBuildLog, &exTestBuildLogLinesCount); - for (int k = 0, index = 0; k < exTestBuildLogLinesCount; k++) + for (int k = 0; k < exTestBuildLogLinesCount; k++) { // Checking compilation warnings generated if (TextFindIndex(exTestBuildLogLines[k], "warning:") >= 0) testing[i].buildwarns++; @@ -1710,7 +1710,7 @@ int main(int argc, char *argv[]) // Load build log text lines int exTestLogLinesCount = 0; char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); - for (int k = 0, index = 0; k < exTestLogLinesCount; k++) + for (int k = 0; k < exTestLogLinesCount; k++) { if (TextFindIndex(exTestLogLines[k], "WARNING: GL: NPOT") >= 0) continue; // Ignore warning if (TextFindIndex(exTestLogLines[k], "WARNING") >= 0) testing[i].warnings++; @@ -2136,7 +2136,7 @@ static int UpdateRequiredFiles(void) mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, "\nSome example missing? As always, contributions are welcome, feel free to send new examples!\n"); mdIndex += sprintf(mdTextUpdated + mdListStartIndex + mdIndex, - "Here is an[examples template](examples_template.c) with instructions to start with!\n"); + "Here is an [examples template](examples_template.c) with instructions to start with!\n"); // Save updated file SaveFileText(TextFormat("%s/README.md", exBasePath), mdTextUpdated); From bd21d749145aa230b26d20d71397b24b22810bef Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:08:11 +0100 Subject: [PATCH 149/189] Update examples_testing_web.md --- tools/rexm/reports/examples_testing_web.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tools/rexm/reports/examples_testing_web.md b/tools/rexm/reports/examples_testing_web.md index e969c48aa..2e8cb5fb3 100644 --- a/tools/rexm/reports/examples_testing_web.md +++ b/tools/rexm/reports/examples_testing_web.md @@ -17,19 +17,7 @@ Example automated testing elements validated: | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| | core_monitor_detector | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_directory_files | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_clipboard_text | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_compute_hash | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_recursive_tree | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_ring_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_circle_sector_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_rounded_rectangle_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_splines_drawing | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_triangle_strip | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_pie_chart | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_math_sine_cosine | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_lines_drawing | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | -| shapes_rlgl_color_wheel | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | textures_screen_buffer | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_sprite_fonts | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | @@ -43,7 +31,6 @@ Example automated testing elements validated: | models_bone_socket | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | models_decals | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | shaders_postprocessing | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | -| shaders_color_correction | 1 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_deferred_rendering | 0 | 2 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | | shaders_shadowmap_rendering | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | shaders_basic_pbr | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | From 0b9f463e64c88d82ca8687f99af6cdb965fbee86 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:18:10 +0100 Subject: [PATCH 150/189] REVIEWED: examples: Replace TABS and Remove trailing spaces --- .../audio/audio_fft_spectrum_visualizer.c | 8 +- examples/core/core_compute_hash.c | 2 +- examples/core/core_delta_time.c | 4 +- examples/core/core_input_actions.c | 32 +-- examples/core/core_input_gamepad.c | 4 +- examples/core/core_input_gestures.c | 2 +- examples/core/core_input_virtual_controls.c | 6 +- examples/core/core_monitor_detector.c | 20 +- examples/core/core_undo_redo.c | 4 +- examples/core/core_viewport_scaling.c | 4 +- .../models/models_directional_billboard.c | 2 +- examples/models/models_loading_vox.c | 208 +++++++++--------- examples/models/models_rotating_cube.c | 16 +- examples/others/easings_testbed.c | 2 +- examples/shaders/shaders_ascii_rendering.c | 6 +- examples/shaders/shaders_basic_pbr.c | 4 +- examples/shaders/shaders_lightmap_rendering.c | 6 +- .../shaders/shaders_shadowmap_rendering.c | 22 +- .../shaders/shaders_spotlight_rendering.c | 4 +- examples/shapes/shapes_bouncing_ball.c | 10 +- examples/shapes/shapes_clock_of_clocks.c | 76 +++---- examples/shapes/shapes_digital_clock.c | 28 +-- examples/shapes/shapes_kaleidoscope.c | 18 +- examples/shapes/shapes_lines_drawing.c | 181 ++++++++------- examples/shapes/shapes_math_sine_cosine.c | 18 +- examples/shapes/shapes_mouse_trail.c | 20 +- examples/shapes/shapes_pie_chart.c | 16 +- examples/shapes/shapes_recursive_tree.c | 12 +- examples/shapes/shapes_rlgl_triangle.c | 12 +- examples/shapes/shapes_simple_particles.c | 54 ++--- examples/shapes/shapes_triangle_strip.c | 6 +- examples/shapes/shapes_vector_angle.c | 2 +- examples/text/text_inline_styling.c | 34 +-- examples/text/text_unicode_ranges.c | 14 +- examples/text/text_words_alignment.c | 22 +- examples/textures/textures_screen_buffer.c | 8 +- 36 files changed, 440 insertions(+), 447 deletions(-) diff --git a/examples/audio/audio_fft_spectrum_visualizer.c b/examples/audio/audio_fft_spectrum_visualizer.c index c667b5d6a..5993186ab 100644 --- a/examples/audio/audio_fft_spectrum_visualizer.c +++ b/examples/audio/audio_fft_spectrum_visualizer.c @@ -86,7 +86,7 @@ int main(void) Vector2 iResolution = { (float)screenWidth, (float)screenHeight }; Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION)); - + int iResolutionLocation = GetShaderLocation(shader, "iResolution"); int iChannel0Location = GetShaderLocation(shader, "iChannel0"); SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2); @@ -153,16 +153,16 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); - + BeginShaderMode(shader); SetShaderValueTexture(shader, iChannel0Location, fftTexture); DrawTextureRec(bufferA.texture, (Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2){ 0, 0 }, WHITE); EndShaderMode(); - + EndDrawing(); //------------------------------------------------------------------------------ } diff --git a/examples/core/core_compute_hash.c b/examples/core/core_compute_hash.c index 376e2d65c..505ffea7b 100644 --- a/examples/core/core_compute_hash.c +++ b/examples/core/core_compute_hash.c @@ -64,7 +64,7 @@ int main(void) // Encode data to Base64 string (includes NULL terminator), memory must be MemFree() base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize); - + hashCRC32 = ComputeCRC32((unsigned char *)textInput, textInputLen); // Compute CRC32 hash code (4 bytes) hashMD5 = ComputeMD5((unsigned char *)textInput, textInputLen); // Compute MD5 hash code, returns static int[4] (16 bytes) hashSHA1 = ComputeSHA1((unsigned char *)textInput, textInputLen); // Compute SHA1 hash code, returns static int[5] (20 bytes) diff --git a/examples/core/core_delta_time.c b/examples/core/core_delta_time.c index e52c743da..b77957ed6 100644 --- a/examples/core/core_delta_time.c +++ b/examples/core/core_delta_time.c @@ -59,7 +59,7 @@ int main(void) // GetFrameTime() returns the time it took to draw the last frame, in seconds (usually called delta time) // Uses the delta time to make the circle look like it's moving at a "consistent" speed regardless of FPS - // Multiply by 6.0 (an arbitrary value) in order to make the speed + // Multiply by 6.0 (an arbitrary value) in order to make the speed // visually closer to the other circle (at 60 fps), for comparison deltaCircle.x += GetFrameTime()*6.0f*speed; // This circle can move faster or slower visually depending on the FPS @@ -68,7 +68,7 @@ int main(void) // If either circle is off the screen, reset it back to the start if (deltaCircle.x > screenWidth) deltaCircle.x = 0; if (frameCircle.x > screenWidth) frameCircle.x = 0; - + // Reset both circles positions if (IsKeyPressed(KEY_R)) { diff --git a/examples/core/core_input_actions.c b/examples/core/core_input_actions.c index cbf7e0e92..f4b1156d8 100644 --- a/examples/core/core_input_actions.c +++ b/examples/core/core_input_actions.c @@ -17,7 +17,7 @@ // Simple example for decoding input as actions, allowing remapping of input to different keys or gamepad buttons // For example instead of using `IsKeyDown(KEY_LEFT)`, you can use `IsActionDown(ACTION_LEFT)` -// which can be reassigned to e.g. KEY_A and also assigned to a gamepad button. the action will trigger with either gamepad or keys +// which can be reassigned to e.g. KEY_A and also assigned to a gamepad button. the action will trigger with either gamepad or keys #include "raylib.h" @@ -44,7 +44,7 @@ typedef struct ActionInput { // Global Variables Definition //---------------------------------------------------------------------------------- static int gamepadIndex = 0; // Gamepad default index -static ActionInput actionInputs[MAX_ACTION] = { 0 }; +static ActionInput actionInputs[MAX_ACTION] = { 0 }; //---------------------------------------------------------------------------------- // Module Functions Declaration @@ -67,15 +67,15 @@ int main(void) const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [core] example - input actions"); - - // Set default actions + + // Set default actions char actionSet = 0; SetActionsDefault(); bool releaseAction = false; Vector2 position = (Vector2){ 400.0f, 200.0f }; Vector2 size = (Vector2){ 40.0f, 40.0f }; - + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -85,7 +85,7 @@ int main(void) // Update //---------------------------------------------------------------------------------- gamepadIndex = 0; // Set gamepad being checked - + if (IsActionDown(ACTION_UP)) position.y -= 2; if (IsActionDown(ACTION_DOWN)) position.y += 2; if (IsActionDown(ACTION_LEFT)) position.x -= 2; @@ -95,12 +95,12 @@ int main(void) position.x = (screenWidth-size.x)/2; position.y = (screenHeight-size.y)/2; } - + // Register release action for one frame releaseAction = false; if (IsActionReleased(ACTION_FIRE)) releaseAction = true; - // Switch control scheme by pressing TAB + // Switch control scheme by pressing TAB if (IsKeyPressed(KEY_TAB)) { actionSet = !actionSet; @@ -116,7 +116,7 @@ int main(void) ClearBackground(GRAY); DrawRectangleV(position, size, releaseAction? BLUE : RED); - + DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE); DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN); @@ -140,9 +140,9 @@ int main(void) static bool IsActionPressed(int action) { bool result = false; - + if (action < MAX_ACTION) result = (IsKeyPressed(actionInputs[action].key) || IsGamepadButtonPressed(gamepadIndex, actionInputs[action].button)); - + return result; } @@ -151,20 +151,20 @@ static bool IsActionPressed(int action) static bool IsActionReleased(int action) { bool result = false; - + if (action < MAX_ACTION) result = (IsKeyReleased(actionInputs[action].key) || IsGamepadButtonReleased(gamepadIndex, actionInputs[action].button)); - + return result; } // Check action key/button down // NOTE: Combines key down and gamepad button down in one action -static bool IsActionDown(int action) +static bool IsActionDown(int action) { bool result = false; - + if (action < MAX_ACTION) result = (IsKeyDown(actionInputs[action].key) || IsGamepadButtonDown(gamepadIndex, actionInputs[action].button)); - + return result; } diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c index b64e0c1a0..3c9454318 100644 --- a/examples/core/core_input_gamepad.c +++ b/examples/core/core_input_gamepad.c @@ -50,7 +50,7 @@ int main(void) const float rightStickDeadzoneY = 0.1f; const float leftTriggerDeadzone = -0.9f; const float rightTriggerDeadzone = -0.9f; - + Rectangle vibrateButton = { 0 }; SetTargetFPS(60); // Set our game to run at 60 frames-per-second @@ -97,7 +97,7 @@ int main(void) if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f; if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f; - if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1) || + if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1) || (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)) { DrawTexture(texXboxPad, 0, 0, DARKGRAY); diff --git a/examples/core/core_input_gestures.c b/examples/core/core_input_gestures.c index 168e2a0c3..e9f43ee3b 100644 --- a/examples/core/core_input_gestures.c +++ b/examples/core/core_input_gestures.c @@ -118,6 +118,6 @@ int main(void) //-------------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- - + return 0; } \ No newline at end of file diff --git a/examples/core/core_input_virtual_controls.c b/examples/core/core_input_virtual_controls.c index 6cae4b6c7..db293b993 100644 --- a/examples/core/core_input_virtual_controls.c +++ b/examples/core/core_input_virtual_controls.c @@ -6,7 +6,7 @@ * * Example originally created with raylib 5.0, last time updated with raylib 5.0 * -* Example contributed by GreenSnakeLinux (@GreenSnakeLinux), +* Example contributed by GreenSnakeLinux (@GreenSnakeLinux), * reviewed by Ramon Santamaria (@raysan5), oblerion (@oblerion) and danilwhale (@danilwhale) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, @@ -86,7 +86,7 @@ int main(void) pressedButton = BUTTON_NONE; // Make sure user is pressing left mouse button if they're from desktop - if ((GetTouchPointCount() > 0) || + if ((GetTouchPointCount() > 0) || ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT))) { // Find nearest D-Pad button to the input position @@ -113,7 +113,7 @@ int main(void) default: break; }; //-------------------------------------------------------------------------- - + // Draw //-------------------------------------------------------------------------- BeginDrawing(); diff --git a/examples/core/core_monitor_detector.c b/examples/core/core_monitor_detector.c index 08e06c811..720449d65 100644 --- a/examples/core/core_monitor_detector.c +++ b/examples/core/core_monitor_detector.c @@ -66,25 +66,25 @@ int main(void) for (int i = 0; i < monitorCount; i++) { monitors[i] = (MonitorInfo){ - GetMonitorPosition(i), - GetMonitorName(i), + GetMonitorPosition(i), + GetMonitorName(i), GetMonitorWidth(i), GetMonitorHeight(i), GetMonitorPhysicalWidth(i), GetMonitorPhysicalHeight(i), GetMonitorRefreshRate(i) }; - + if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = -(int)monitors[i].position.x; const int width = (int)monitors[i].position.x + monitors[i].width; const int height = (int)monitors[i].position.y + monitors[i].height; - + if (maxWidth < width) maxWidth = width; if (maxHeight < height) maxHeight = height; } - if (IsKeyPressed(KEY_ENTER) && (monitorCount > 1)) + if (IsKeyPressed(KEY_ENTER) && (monitorCount > 1)) { currentMonitorIndex += 1; @@ -95,8 +95,8 @@ int main(void) } else currentMonitorIndex = GetCurrentMonitor(); // Get currentMonitorIndex if manually moved - float monitorScale = 0.6f; - + float monitorScale = 0.6f; + if (maxHeight > (maxWidth + monitorOffsetX)) monitorScale *= ((float)screenHeight/(float)maxHeight); else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX)); //---------------------------------------------------------------------------------- @@ -125,9 +125,9 @@ int main(void) // Draw monitor name and information inside the rectangle DrawText(TextFormat("[%i] %s", i, monitors[i].name), (int)rec.x + 10, (int)rec.y + (int)(100*monitorScale), (int)(120*monitorScale), BLUE); DrawText( - TextFormat("Resolution: [%ipx x %ipx]\nRefreshRate: [%ihz]\nPhysical Size: [%imm x %imm]\nPosition: %3.0f x %3.0f", - monitors[i].width, - monitors[i].height, + TextFormat("Resolution: [%ipx x %ipx]\nRefreshRate: [%ihz]\nPhysical Size: [%imm x %imm]\nPosition: %3.0f x %3.0f", + monitors[i].width, + monitors[i].height, monitors[i].refreshRate, monitors[i].physicalWidth, monitors[i].physicalHeight, diff --git a/examples/core/core_undo_redo.c b/examples/core/core_undo_redo.c index 45b19e10f..c49ad9e6f 100644 --- a/examples/core/core_undo_redo.c +++ b/examples/core/core_undo_redo.c @@ -22,7 +22,7 @@ #define MAX_UNDO_STATES 26 // Maximum undo states supported for the ring buffer -#define GRID_CELL_SIZE 24 +#define GRID_CELL_SIZE 24 #define MAX_GRID_CELLS_X 30 #define MAX_GRID_CELLS_Y 13 @@ -57,7 +57,7 @@ int main(void) //-------------------------------------------------------------------------------------- const int screenWidth = 800; const int screenHeight = 450; - + // We have multiple options to implement an Undo/Redo system // Probably the most professional one is using the Command pattern to // define Actions and store those actions into an array as the events happen, diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index 3044dd0af..28ee422cd 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -20,7 +20,7 @@ // For itteration purposes and teaching example #define RESOLUTION_COUNT 4 -enum ViewportType +enum ViewportType { // Only upscale, useful for pixel art KEEP_ASPECT_INTEGER, @@ -113,7 +113,7 @@ int main(void) } Vector2 mousePosition = GetMousePosition(); bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT); - + // Check buttons and rescale if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed){ resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1) % RESOLUTION_COUNT; diff --git a/examples/models/models_directional_billboard.c b/examples/models/models_directional_billboard.c index f471da4d0..e2c75c15a 100644 --- a/examples/models/models_directional_billboard.c +++ b/examples/models/models_directional_billboard.c @@ -62,7 +62,7 @@ int main(void) anim_timer += GetFrameTime(); // Update frame index after a certain amount of time (half a second) - if (anim_timer > 0.5f) + if (anim_timer > 0.5f) { anim_timer = 0.0f; anim += 1; diff --git a/examples/models/models_loading_vox.c b/examples/models/models_loading_vox.c index 6675f3fd7..47be07ee4 100644 --- a/examples/models/models_loading_vox.c +++ b/examples/models/models_loading_vox.c @@ -35,122 +35,122 @@ //------------------------------------------------------------------------------------ int main(void) { - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; - const char *voxFileNames[] = { - "resources/models/vox/chr_knight.vox", - "resources/models/vox/chr_sword.vox", - "resources/models/vox/monu9.vox", - "resources/models/vox/fez.vox" - }; + const char *voxFileNames[] = { + "resources/models/vox/chr_knight.vox", + "resources/models/vox/chr_sword.vox", + "resources/models/vox/monu9.vox", + "resources/models/vox/fez.vox" + }; - InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox"); + InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox"); - // Define the camera to look into our 3d world - Camera camera = { 0 }; - camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 0.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 + // Define the camera to look into our 3d world + Camera camera = { 0 }; + camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 0.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 MagicaVoxel files - Model models[MAX_VOX_FILES] = { 0 }; + // Load MagicaVoxel files + Model models[MAX_VOX_FILES] = { 0 }; - for (int i = 0; i < MAX_VOX_FILES; i++) - { - // Load VOX file and measure time - double t0 = GetTime()*1000.0; - models[i] = LoadModel(voxFileNames[i]); - double t1 = GetTime()*1000.0; + for (int i = 0; i < MAX_VOX_FILES; i++) + { + // Load VOX file and measure time + double t0 = GetTime()*1000.0; + models[i] = LoadModel(voxFileNames[i]); + double t1 = GetTime()*1000.0; - TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0)); + TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0)); - // Compute model translation matrix to center model on draw position (0, 0 , 0) - BoundingBox bb = GetModelBoundingBox(models[i]); - Vector3 center = { 0 }; - center.x = bb.min.x + (((bb.max.x - bb.min.x)/2)); - center.z = bb.min.z + (((bb.max.z - bb.min.z)/2)); + // Compute model translation matrix to center model on draw position (0, 0 , 0) + BoundingBox bb = GetModelBoundingBox(models[i]); + Vector3 center = { 0 }; + center.x = bb.min.x + (((bb.max.x - bb.min.x)/2)); + center.z = bb.min.z + (((bb.max.z - bb.min.z)/2)); - Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z); - models[i].transform = matTranslate; - } + Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z); + models[i].transform = matTranslate; + } - int currentModel = 0; - Vector3 modelpos = { 0 }; - Vector3 camerarot = { 0 }; + int currentModel = 0; + Vector3 modelpos = { 0 }; + Vector3 camerarot = { 0 }; - // Load voxel shader - Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION), - TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION)); + // Load voxel shader + Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION), + TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION)); - // Get some required shader locations - shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos"); - // NOTE: "matModel" location name is automatically assigned on shader loading, - // no need to get the location again if using that uniform name - //shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel"); + // Get some required shader locations + shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos"); + // NOTE: "matModel" location name is automatically assigned on shader loading, + // no need to get the location again if using that uniform name + //shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel"); - // Ambient light level (some basic lighting) - int ambientLoc = GetShaderLocation(shader, "ambient"); - SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4); + // Ambient light level (some basic lighting) + int ambientLoc = GetShaderLocation(shader, "ambient"); + SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4); - // Assign out lighting shader to model - for (int i = 0; i < MAX_VOX_FILES; i++) - { - for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader; - } + // Assign out lighting shader to model + for (int i = 0; i < MAX_VOX_FILES; i++) + { + for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader; + } - // Create lights - Light lights[MAX_LIGHTS] = { 0 }; - lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader); - lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader); - lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader); - lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader); + // Create lights + Light lights[MAX_LIGHTS] = { 0 }; + lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader); + lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader); + lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader); + lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader); - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)) - { - const Vector2 mouseDelta = GetMouseDelta(); - camerarot.x = mouseDelta.x*0.05f; - camerarot.y = mouseDelta.y*0.05f; - } - else - { - camerarot.x = 0; - camerarot.y = 0; - } + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)) + { + const Vector2 mouseDelta = GetMouseDelta(); + camerarot.x = mouseDelta.x*0.05f; + camerarot.y = mouseDelta.y*0.05f; + } + else + { + camerarot.x = 0; + camerarot.y = 0; + } - UpdateCameraPro(&camera, - (Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward + UpdateCameraPro(&camera, + (Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left 0.0f }, // Move up-down - camerarot, // Camera rotation - GetMouseWheelMove()*-2.0f); // Move to target (zoom) + camerarot, // Camera rotation + GetMouseWheelMove()*-2.0f); // Move to target (zoom) - // Cycle between models on mouse click - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES; + // Cycle between models on mouse click + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES; - // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f }) - float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; - SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3); + // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f }) + float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; + SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3); - // Update light values (actually, only enable/disable them) - for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]); - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); + // Update light values (actually, only enable/disable them) + for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); ClearBackground(RAYWHITE); @@ -175,17 +175,17 @@ int main(void) DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE); DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY); - EndDrawing(); - //---------------------------------------------------------------------------------- - } + EndDrawing(); + //---------------------------------------------------------------------------------- + } - // De-Initialization - //-------------------------------------------------------------------------------------- - // Unload models data (GPU VRAM) - for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]); + // De-Initialization + //-------------------------------------------------------------------------------------- + // Unload models data (GPU VRAM) + for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]); - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- - return 0; + return 0; } diff --git a/examples/models/models_rotating_cube.c b/examples/models/models_rotating_cube.c index 930dae516..c5b633fea 100644 --- a/examples/models/models_rotating_cube.c +++ b/examples/models/models_rotating_cube.c @@ -5,7 +5,7 @@ * Example complexity rating: [★☆☆☆] 1/4 * * Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev -* +* * Example contributed by Jopestpe (@jopestpe) * * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, @@ -48,7 +48,7 @@ int main(void) model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; float rotation = 0.0f; - + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -59,7 +59,7 @@ int main(void) //---------------------------------------------------------------------------------- rotation += 1.0f; //---------------------------------------------------------------------------------- - + // Draw //---------------------------------------------------------------------------------- BeginDrawing(); @@ -67,13 +67,13 @@ int main(void) ClearBackground(RAYWHITE); BeginMode3D(camera); - - // Draw model defining: position, size, rotation-axis, rotation (degrees), size, and tint-color - DrawModelEx(model, (Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.5f, 1.0f, 0.0f }, + + // Draw model defining: position, size, rotation-axis, rotation (degrees), size, and tint-color + DrawModelEx(model, (Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.5f, 1.0f, 0.0f }, rotation, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE); - + DrawGrid(10, 1.0f); - + EndMode3D(); DrawFPS(10, 10); diff --git a/examples/others/easings_testbed.c b/examples/others/easings_testbed.c index b3ff8a8df..fa4a599ee 100644 --- a/examples/others/easings_testbed.c +++ b/examples/others/easings_testbed.c @@ -221,7 +221,7 @@ int main(void) } -// NoEase function, used when "no easing" is selected for any axis +// 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/shaders/shaders_ascii_rendering.c b/examples/shaders/shaders_ascii_rendering.c index 523b381b2..d3302bf53 100644 --- a/examples/shaders/shaders_ascii_rendering.c +++ b/examples/shaders/shaders_ascii_rendering.c @@ -87,15 +87,15 @@ int main(void) DrawTexture(fudesumi, 500, -30, WHITE); DrawTextureV(raysan, circlePos, WHITE); EndTextureMode(); - + BeginDrawing(); ClearBackground(RAYWHITE); BeginShaderMode(shader); // Draw the scene texture (that we rendered earlier) to the screen // The shader will process every pixel of this texture - DrawTextureRec(target.texture, - (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, + DrawTextureRec(target.texture, + (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE); EndShaderMode(); diff --git a/examples/shaders/shaders_basic_pbr.c b/examples/shaders/shaders_basic_pbr.c index cc8583830..7ee05502d 100644 --- a/examples/shaders/shaders_basic_pbr.c +++ b/examples/shaders/shaders_basic_pbr.c @@ -242,7 +242,7 @@ int main(void) SetShaderValue(shader, emissiveColorLoc, &carEmissiveColor, SHADER_UNIFORM_VEC4); float emissiveIntensity = 0.01f; SetShaderValue(shader, emissiveIntensityLoc, &emissiveIntensity, SHADER_UNIFORM_FLOAT); - + // Set old car metallic and roughness values SetShaderValue(shader, metallicValueLoc, &car.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT); SetShaderValue(shader, roughnessValueLoc, &car.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT); @@ -252,7 +252,7 @@ int main(void) // Draw spheres to show the lights positions for (int i = 0; i < MAX_LIGHTS; i++) { - Color lightColor = (Color){ + Color lightColor = (Color){ (unsigned char)(lights[i].color[0]*255), (unsigned char)(lights[i].color[1] * 255), (unsigned char)(lights[i].color[2] * 255), diff --git a/examples/shaders/shaders_lightmap_rendering.c b/examples/shaders/shaders_lightmap_rendering.c index 51651cfd3..05d9c0e09 100644 --- a/examples/shaders/shaders_lightmap_rendering.c +++ b/examples/shaders/shaders_lightmap_rendering.c @@ -124,7 +124,7 @@ int main(void) ); BeginBlendMode(BLEND_ALPHA); EndTextureMode(); - + // NOTE: To enable trilinear filtering we need mipmaps available for texture GenTextureMipmaps(&lightmap.texture); SetTextureFilter(lightmap.texture, TEXTURE_FILTER_TRILINEAR); @@ -143,7 +143,7 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); BeginMode3D(camera); @@ -155,7 +155,7 @@ int main(void) (Vector2){ 0.0, 0.0 }, 0.0, WHITE); DrawText(TextFormat("LIGHTMAP: %ix%i pixels", MAP_SIZE, MAP_SIZE), GetRenderWidth() - 130, 20 + MAP_SIZE*8, 10, GREEN); - + DrawFPS(10, 10); EndDrawing(); diff --git a/examples/shaders/shaders_shadowmap_rendering.c b/examples/shaders/shaders_shadowmap_rendering.c index 7b75b80e0..a739cdd93 100644 --- a/examples/shaders/shaders_shadowmap_rendering.c +++ b/examples/shaders/shaders_shadowmap_rendering.c @@ -45,7 +45,7 @@ int main(void) // Shadows are a HUGE topic, and this example shows an extremely simple implementation of the shadowmapping algorithm, // which is the industry standard for shadows. This algorithm can be extended in a ridiculous number of ways to improve // realism and also adapt it for different scenes. This is pretty much the simplest possible implementation - + SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [shaders] example - shadowmap rendering"); @@ -59,7 +59,7 @@ int main(void) Shader shadowShader = LoadShader(TextFormat("resources/shaders/glsl%i/shadowmap.vs", GLSL_VERSION), TextFormat("resources/shaders/glsl%i/shadowmap.fs", GLSL_VERSION)); shadowShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shadowShader, "viewPos"); - + Vector3 lightDir = Vector3Normalize((Vector3){ 0.35f, -1.0f, -0.35f }); Color lightColor = WHITE; Vector4 lightColorNormalized = ColorNormalize(lightColor); @@ -83,7 +83,7 @@ int main(void) ModelAnimation *robotAnimations = LoadModelAnimations("resources/models/robot.glb", &animCount); RenderTexture2D shadowMap = LoadShadowmapRenderTexture(SHADOWMAP_RESOLUTION, SHADOWMAP_RESOLUTION); - + // For the shadowmapping algorithm, we will be rendering everything from the light's point of view Camera3D lightCamera = { 0 }; lightCamera.position = Vector3Scale(lightDir, -15.0f); @@ -91,9 +91,9 @@ int main(void) lightCamera.projection = CAMERA_ORTHOGRAPHIC; // Use an orthographic projection for directional lights lightCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; lightCamera.fovy = 20.0f; - + int frameCounter = 0; - + // Store the light matrices Matrix lightView = { 0 }; Matrix lightProj = { 0 }; @@ -136,7 +136,7 @@ int main(void) { if (lightDir.z > -0.6f) lightDir.z -= cameraSpeed*60.0f*deltaTime; } - + lightDir = Vector3Normalize(lightDir); lightCamera.position = Vector3Scale(lightDir, -15.0f); SetShaderValue(shadowShader, lightDirLoc, &lightDir, SHADER_UNIFORM_VEC3); @@ -151,13 +151,13 @@ int main(void) // to determine whether a given point is "visible" to the light BeginTextureMode(shadowMap); ClearBackground(WHITE); - + BeginMode3D(lightCamera); lightView = rlGetMatrixModelview(); lightProj = rlGetMatrixProjection(); DrawScene(cube, robot); EndMode3D(); - + EndTextureMode(); lightViewProj = MatrixMultiply(lightView, lightProj); @@ -167,7 +167,7 @@ int main(void) SetShaderValueMatrix(shadowShader, lightVPLoc, lightViewProj); rlEnableShader(shadowShader.id); - + rlActiveTextureSlot(textureActiveSlot); rlEnableTexture(shadowMap.depth.id); rlSetUniform(shadowMapLoc, &textureActiveSlot, SHADER_UNIFORM_INT, 1); @@ -178,7 +178,7 @@ int main(void) DrawText("Use the arrow keys to rotate the light!", 10, 10, 30, RED); DrawText("Shadows in raylib using the shadowmapping algorithm!", screenWidth - 280, screenHeight - 20, 10, GRAY); - + EndDrawing(); if (IsKeyPressed(KEY_F)) TakeScreenshot("shaders_shadowmap.png"); @@ -200,7 +200,7 @@ int main(void) } // Load render texture for shadowmap projection -// NOTE: Load framebuffer with only a texture depth attachment, +// NOTE: Load framebuffer with only a texture depth attachment, // no color attachment required for shadowmap static RenderTexture2D LoadShadowmapRenderTexture(int width, int height) { diff --git a/examples/shaders/shaders_spotlight_rendering.c b/examples/shaders/shaders_spotlight_rendering.c index c9ee950c1..3678f9796 100644 --- a/examples/shaders/shaders_spotlight_rendering.c +++ b/examples/shaders/shaders_spotlight_rendering.c @@ -239,7 +239,7 @@ int main(void) static void ResetStar(Star *star) { star->position = (Vector2){ GetScreenWidth()/2.0f, GetScreenHeight()/2.0f }; - + star->speed.x = (float)GetRandomValue(-1000, 1000)/100.0f; star->speed.y = (float)GetRandomValue(-1000, 1000)/100.0f; @@ -247,7 +247,7 @@ static void ResetStar(Star *star) { star->speed.x = (float)GetRandomValue(-1000, 1000)/100.0f; star->speed.y = (float)GetRandomValue(-1000, 1000)/100.0f; - } + } star->position = Vector2Add(star->position, Vector2Multiply(star->speed, (Vector2){ 8.0f, 8.0f })); } diff --git a/examples/shapes/shapes_bouncing_ball.c b/examples/shapes/shapes_bouncing_ball.c index 5ae699944..d55c47f56 100644 --- a/examples/shapes/shapes_bouncing_ball.c +++ b/examples/shapes/shapes_bouncing_ball.c @@ -7,7 +7,7 @@ * Example originally created with raylib 2.5, last time updated with raylib 2.5 * * Example contributed by Ramon Santamaria (@raysan5), reviewed by Jopestpe (@jopestpe) -* +* * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * @@ -49,14 +49,14 @@ int main(void) //----------------------------------------------------- if (IsKeyPressed(KEY_G)) useGravity = !useGravity; if (IsKeyPressed(KEY_SPACE)) pause = !pause; - + if (!pause) { ballPosition.x += ballSpeed.x; ballPosition.y += ballSpeed.y; if (useGravity) ballSpeed.y += gravity; - + // Check walls collision for bouncing if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f; if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -0.95f; @@ -72,7 +72,7 @@ int main(void) DrawCircleV(ballPosition, (float)ballRadius, MAROON); DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, LIGHTGRAY); - + if (useGravity) DrawText("GRAVITY: ON (Press G to disable)", 10, GetScreenHeight() - 50, 20, DARKGREEN); else DrawText("GRAVITY: OFF (Press G to enable)", 10, GetScreenHeight() - 50, 20, RED); @@ -80,7 +80,7 @@ int main(void) if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY); DrawFPS(10, 10); - + EndDrawing(); //----------------------------------------------------- } diff --git a/examples/shapes/shapes_clock_of_clocks.c b/examples/shapes/shapes_clock_of_clocks.c index 3fc24aa92..51703a32d 100644 --- a/examples/shapes/shapes_clock_of_clocks.c +++ b/examples/shapes/shapes_clock_of_clocks.c @@ -35,14 +35,14 @@ int main(void) SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - clock of clocks"); - + const Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.75f); const Color handsColor = ColorLerp(YELLOW, RAYWHITE, .25f); - + const float clockFaceSize = 24; const float clockFaceSpacing = 8.0f; const float sectionSpacing = 16.0f; - + const Vector2 TL = (Vector2){ 0.0f, 90.0f }; // Top-left corner const Vector2 TR = (Vector2){ 90.0f, 180.0f }; // Top-right corner const Vector2 BR = (Vector2){ 180.0f, 270.0f }; // Bottom-right corner @@ -50,7 +50,7 @@ int main(void) const Vector2 HH = (Vector2){ 0.0f, 180.0f }; // Horizontal line const Vector2 VV = (Vector2){ 90.0f, 270.0f }; // Vertical line const Vector2 ZZ = (Vector2){ 135.0f, 135.0f }; // Not relevant - + const Vector2 digitAngles[10][24] = { /* 0 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,VV,VV,VV,/* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR }, /* 1 */ { TL,HH,TR,ZZ, /* */ BL,TR,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ TL,BR,BL,TR,/* */ BL,HH,HH,BR }, @@ -65,21 +65,21 @@ int main(void) }; // Time for the hands to move to the new position (in seconds); this must be <1s const float handsMoveDuration = .5f; - + // We store the previous seconds value so we can see if the time has changed int prevSeconds = -1; - + // This represents the real position where the hands are right now Vector2 currentAngles[6][24] = { 0 }; - + // This is the position where the hands were moving from Vector2 srcAngles[6][24] = { 0 }; // This is the position where the hands are moving to Vector2 dstAngles[6][24] = { 0 }; - + // Current animation timer float handsMoveTimer = 0.0f; - + // 12 or 24 hour mode int hourMode = 24; @@ -91,32 +91,32 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - + // Get the current time time_t rawtime; struct tm *timeinfo; time(&rawtime); timeinfo = localtime(&rawtime); - + if (timeinfo->tm_sec != prevSeconds) { // The time has changed, so we need to move the hands to the new positions prevSeconds = timeinfo->tm_sec; - + // Format the current time so we can access the individual digits const char *clockDigits = TextFormat("%02d%02d%02d", timeinfo->tm_hour % hourMode, timeinfo->tm_min, timeinfo->tm_sec); - + // Fetch where we want all the hands to be for (int digit = 0; digit < 6; digit++) { for (int cell = 0; cell < 24; cell++) { srcAngles[digit][cell] = currentAngles[digit][cell]; dstAngles[digit][cell] = digitAngles[ clockDigits[digit] - '0' ][cell]; - + // Quick exception for 12h mode if (digit == 0 && hourMode == 12 && clockDigits[0] == '0') { dstAngles[digit][cell] = ZZ; } - + if (srcAngles[digit][cell].x > dstAngles[digit][cell].x) { srcAngles[digit][cell].x -= 360.0f; } @@ -125,43 +125,43 @@ int main(void) } } } - + // Reset the timer handsMoveTimer = -GetFrameTime(); } - + // Now let's animate all the hands if we need to if (handsMoveTimer < handsMoveDuration) { // Increase the timer but don't go above the maximum handsMoveTimer = Clamp(handsMoveTimer + GetFrameTime(), 0, handsMoveDuration); - + // Calculate the % completion of the animation float t = handsMoveTimer / handsMoveDuration; - + // A little cheeky smoothstep t = t * t * (3.0f - 2.0f * t); - + for (int digit = 0; digit < 6; digit++) { for (int cell = 0; cell < 24; cell++) { currentAngles[digit][cell].x = Lerp(srcAngles[digit][cell].x, dstAngles[digit][cell].x, t); currentAngles[digit][cell].y = Lerp(srcAngles[digit][cell].y, dstAngles[digit][cell].y, t); } } - + if (handsMoveTimer == handsMoveDuration) { // The animation has now finished } } - + // Handle input - + // Toggle between 12 and 24 hour mode with space if (IsKeyPressed(KEY_SPACE)) { hourMode = 36 - hourMode; } - - - + + + //---------------------------------------------------------------------------------- // Draw @@ -169,13 +169,13 @@ int main(void) BeginDrawing(); ClearBackground(bgColor); - + DrawText(TextFormat("%d-h mode, space to change", hourMode), 10, 30, 20, RAYWHITE); - + float xOffset = 4.0f; - + for (int digit = 0; digit < 6; digit++) { - + for (int row = 0; row < 6; row++) { for (int col = 0; col < 4; col++) { Vector2 centre = (Vector2){ @@ -183,7 +183,7 @@ int main(void) 100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f }; DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, DARKGRAY); - + // Big hand DrawRectanglePro( (Rectangle){centre.x, centre.y, clockFaceSize*.5f+4.0f, 4.0f}, @@ -191,7 +191,7 @@ int main(void) currentAngles[digit][row*4+col].x, handsColor ); - + // Little hand DrawRectanglePro( (Rectangle){centre.x, centre.y, clockFaceSize*.5f+2.0f, 4.0f}, @@ -201,20 +201,20 @@ int main(void) ); } } - + xOffset += (clockFaceSize+clockFaceSpacing) * 4; if (digit % 2 == 1) { - + DrawRing((Vector2){xOffset + 4.0f, 160.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor); DrawRing((Vector2){xOffset + 4.0f, 225.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor); - + xOffset += sectionSpacing; - + } } - + DrawFPS(10, 10); - + EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c index 5f55fa836..cca3f3c44 100644 --- a/examples/shapes/shapes_digital_clock.c +++ b/examples/shapes/shapes_digital_clock.c @@ -116,7 +116,7 @@ int main(void) ClearBackground(RAYWHITE); // Draw clock in selected mode - if (clockMode == CLOCK_ANALOG) DrawClockAnalog(clock, (Vector2){ 400, 240 }); + if (clockMode == CLOCK_ANALOG) DrawClockAnalog(clock, (Vector2){ 400, 240 }); else if (clockMode == CLOCK_DIGITAL) { DrawClockDigital(clock, (Vector2){ 30, 60 }); @@ -128,7 +128,7 @@ int main(void) DrawText(clockTime, GetScreenWidth()/2 - MeasureText(clockTime, 150)/2, 300, 150, BLACK); } - DrawText(TextFormat("Press [SPACE] to switch clock mode: %s", + DrawText(TextFormat("Press [SPACE] to switch clock mode: %s", (clockMode == CLOCK_DIGITAL)? "DIGITAL CLOCK" : "ANALOGUE CLOCK"), 10, 10, 20, DARKGRAY); EndDrawing(); @@ -183,13 +183,13 @@ static void DrawClockAnalog(Clock clock, Vector2 position) // Draw clock minutes/seconds lines for (int i = 0; i < 60; i++) { - DrawLineEx((Vector2){ position.x + (clock.second.length + ((i%5)? 10 : 6))*cosf((6.0f*i - 90.0f)*DEG2RAD), - position.y + (clock.second.length + ((i%5)? 10 : 6))*sinf((6.0f*i - 90.0f)*DEG2RAD) }, - (Vector2){ position.x + (clock.second.length + 20)*cosf((6.0f*i - 90.0f)*DEG2RAD), + DrawLineEx((Vector2){ position.x + (clock.second.length + ((i%5)? 10 : 6))*cosf((6.0f*i - 90.0f)*DEG2RAD), + position.y + (clock.second.length + ((i%5)? 10 : 6))*sinf((6.0f*i - 90.0f)*DEG2RAD) }, + (Vector2){ position.x + (clock.second.length + 20)*cosf((6.0f*i - 90.0f)*DEG2RAD), position.y + (clock.second.length + 20)*sinf((6.0f*i - 90.0f)*DEG2RAD) }, ((i%5)? 1.0f : 3.0f), DARKGRAY); - + // Draw seconds numbers - //DrawText(TextFormat("%02i", i), centerPosition.x + (clock.second.length + 50)*cosf((6.0f*i - 90.0f)*DEG2RAD) - 10/2, + //DrawText(TextFormat("%02i", i), centerPosition.x + (clock.second.length + 50)*cosf((6.0f*i - 90.0f)*DEG2RAD) - 10/2, // centerPosition.y + (clock.second.length + 50)*sinf((6.0f*i - 90.0f)*DEG2RAD) - 10/2, 10, GRAY); } @@ -256,25 +256,25 @@ static void Draw7SDisplay(Vector2 position, char segments, Color colorOn, Color float offsetYAdjust = segmentThick*0.3f; // HACK: Adjust gap space between segment limits // Segment A - DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + segmentThick }, + DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + segmentThick }, segmentLen, segmentThick, false, (segments & 0b00000001)? colorOn : colorOff); // Segment B - DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust }, + DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust }, segmentLen, segmentThick, true, (segments & 0b00000010)? colorOn : colorOff); // Segment C - DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust }, + DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust }, segmentLen, segmentThick, true, (segments & 0b00000100)? colorOn : colorOff); // Segment D - DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 5*segmentThick + 2*segmentLen - 4*offsetYAdjust }, + DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 5*segmentThick + 2*segmentLen - 4*offsetYAdjust }, segmentLen, segmentThick, false, (segments & 0b00001000)? colorOn : colorOff); // Segment E - DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust }, + DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust }, segmentLen, segmentThick, true, (segments & 0b00010000)? colorOn : colorOff); // Segment F - DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust }, + DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust }, segmentLen, segmentThick, true, (segments & 0b00100000)? colorOn : colorOff); // Segment G - DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 3*segmentThick + segmentLen - 2*offsetYAdjust }, + DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 3*segmentThick + segmentLen - 2*offsetYAdjust }, segmentLen, segmentThick, false, (segments & 0b01000000)? colorOn : colorOff); } diff --git a/examples/shapes/shapes_kaleidoscope.c b/examples/shapes/shapes_kaleidoscope.c index 7eeadb8aa..be1409a8d 100644 --- a/examples/shapes/shapes_kaleidoscope.c +++ b/examples/shapes/shapes_kaleidoscope.c @@ -51,13 +51,13 @@ int main(void) Vector2 prevMousePos = { 0 }; Vector2 scaleVector = { 1.0f, -1.0f }; Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f }; - + Camera2D camera = { 0 }; camera.target = (Vector2){ 0 }; camera.offset = offset; camera.rotation = 0.0f; camera.zoom = 1.0f; - + int lineCounter = 0; SetTargetFPS(20); @@ -70,10 +70,10 @@ int main(void) //---------------------------------------------------------------------------------- prevMousePos = mousePos; mousePos = GetMousePosition(); - + Vector2 lineStart = Vector2Subtract(mousePos, offset); Vector2 lineEnd = Vector2Subtract(prevMousePos, offset); - + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) { for (int s = 0; (s < symmetry) && (lineCounter < (MAX_DRAW_LINES - 1)); s++) @@ -88,7 +88,7 @@ int main(void) // Store reflective line lines[lineCounter + 1].start = Vector2Multiply(lineStart, scaleVector); lines[lineCounter + 1].end = Vector2Multiply(lineEnd, scaleVector); - + lineCounter += 2; } } @@ -97,9 +97,9 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); - + BeginMode2D(camera); for (int s = 0; s < symmetry; s++) { @@ -110,10 +110,10 @@ int main(void) } } EndMode2D(); - + DrawText(TextFormat("LINES: %i/%i", lineCounter, MAX_DRAW_LINES), 10, screenHeight - 30, 20, MAROON); DrawFPS(10, 10); - + EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/examples/shapes/shapes_lines_drawing.c b/examples/shapes/shapes_lines_drawing.c index 16f59884d..76e81abb5 100644 --- a/examples/shapes/shapes_lines_drawing.c +++ b/examples/shapes/shapes_lines_drawing.c @@ -16,6 +16,7 @@ ********************************************************************************************/ #include "raylib.h" + #include "raymath.h" //------------------------------------------------------------------------------------ @@ -23,122 +24,114 @@ //------------------------------------------------------------------------------------ int main(void) { - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing"); + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing"); - // Hint text that shows before you click the screen - bool startText = true; + // Hint text that shows before you click the screen + bool startText = true; - // The mouse's position on the previous frame - Vector2 mousePositionPrevious = GetMousePosition(); + // The mouse's position on the previous frame + Vector2 mousePositionPrevious = GetMousePosition(); - // The canvas to draw lines on - RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight); + // The canvas to draw lines on + RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight); - // The background color of the canvas - const Color backgroundColor = RAYWHITE; + // The line's thickness + float lineThickness = 8.0f; + // The lines hue (in HSV, from 0-360) + float lineHue = 0.0f; - // The line's thickness - float lineThickness = 8.0f; - // The lines hue (in HSV, from 0-360) - float lineHue = 0.0f; + // Clear the canvas to the background color + BeginTextureMode(canvas); + ClearBackground(RAYWHITE); + EndTextureMode(); - // Clear the canvas to the background color - BeginTextureMode(canvas); - ClearBackground(backgroundColor); - EndTextureMode(); - SetTargetFPS(60); - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - // Disable the hint text once the user clicks - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText) startText = false; + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Disable the hint text once the user clicks + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText) startText = false; - // Clear the canvas when the user middle-clicks - if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) - { - BeginTextureMode(canvas); - ClearBackground(backgroundColor); - EndTextureMode(); - } + // Clear the canvas when the user middle-clicks + if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) + { + BeginTextureMode(canvas); + ClearBackground(RAYWHITE); + EndTextureMode(); + } - // Store whether the left and right buttons are down - bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT); - bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT); + // Store whether the left and right buttons are down + bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT); + bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT); - if (leftButtonDown || rightButtonDown) - { - // The color for the line - Color drawColor = WHITE; + if (leftButtonDown || rightButtonDown) + { + // The color for the line + Color drawColor = WHITE; - if (leftButtonDown) - { - // Increase the hue value by the distance our cursor has moved since the last frame (divided by 3) - lineHue += Vector2Distance(mousePositionPrevious, GetMousePosition())/3.0f; + if (leftButtonDown) + { + // Increase the hue value by the distance our cursor has moved since the last frame (divided by 3) + lineHue += Vector2Distance(mousePositionPrevious, GetMousePosition())/3.0f; - // While the hue is >=360, subtract it to bring it down into the range 0-360 - // This is more visually accurate than resetting to zero - while (lineHue >= 360.0f) lineHue -= 360.0f; + // While the hue is >=360, subtract it to bring it down into the range 0-360 + // This is more visually accurate than resetting to zero + while (lineHue >= 360.0f) lineHue -= 360.0f; - // Create the final color - drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f); - } - else if (rightButtonDown) - { - // Use the background color as an "eraser" - drawColor = backgroundColor; - } + // Create the final color + drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f); + } + else if (rightButtonDown) drawColor = RAYWHITE; // Use the background color as an "eraser" - // Draw the line onto the canvas - BeginTextureMode(canvas); - - // Circles act as "caps", smoothing corners - DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor); - DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor); - DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor); - - EndTextureMode(); - } + // Draw the line onto the canvas + BeginTextureMode(canvas); + // Circles act as "caps", smoothing corners + DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor); + DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor); + DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor); + EndTextureMode(); + } - // Update line thickness based on mousewheel - lineThickness += GetMouseWheelMove(); - lineThickness = Clamp(lineThickness, 1.0, 500.0f); + // Update line thickness based on mousewheel + lineThickness += GetMouseWheelMove(); + lineThickness = Clamp(lineThickness, 1.0, 500.0f); - // Update mouse's previous position - mousePositionPrevious = GetMousePosition(); - //---------------------------------------------------------------------------------- + // Update mouse's previous position + mousePositionPrevious = GetMousePosition(); + //---------------------------------------------------------------------------------- - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - // Draw the render texture to the screen, flipped vertically to make it appear top-side up - DrawTextureRec(canvas.texture, (Rectangle){ 0.0f, 0.0f, (float)canvas.texture.width,(float)-canvas.texture.height }, Vector2Zero(), WHITE); + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); - // Draw the preview circle - if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 }); + // Draw the render texture to the screen, flipped vertically to make it appear top-side up + DrawTextureRec(canvas.texture, (Rectangle){ 0.0f, 0.0f, (float)canvas.texture.width,(float)-canvas.texture.height }, Vector2Zero(), WHITE); - // Draw the hint text - if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY); - EndDrawing(); - //---------------------------------------------------------------------------------- - } + // Draw the preview circle + if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 }); - // De-Initialization - //-------------------------------------------------------------------------------------- - // Unload the canvas render texture - UnloadRenderTexture(canvas); + // Draw the hint text + if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY); - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- + EndDrawing(); + //---------------------------------------------------------------------------------- + } - return 0; + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadRenderTexture(canvas); // Unload the canvas render texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; } \ No newline at end of file diff --git a/examples/shapes/shapes_math_sine_cosine.c b/examples/shapes/shapes_math_sine_cosine.c index d8d13920e..4e5f3fe47 100644 --- a/examples/shapes/shapes_math_sine_cosine.c +++ b/examples/shapes/shapes_math_sine_cosine.c @@ -35,7 +35,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - SetConfigFlags(FLAG_MSAA_4X_HINT); + SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math sine cosine"); Vector2 sinePoints[WAVE_POINTS]; @@ -97,7 +97,7 @@ int main(void) // Base circle and axes DrawCircleLinesV(center, radius, GRAY); - DrawLineEx((Vector2){ center.x, limitMin.y }, (Vector2){ center.x, limitMax.y }, 1.0f, GRAY); + DrawLineEx((Vector2){ center.x, limitMin.y }, (Vector2){ center.x, limitMax.y }, 1.0f, GRAY); DrawLineEx((Vector2){ limitMin.x, center.y }, (Vector2){ limitMax.x, center.y }, 1.f, GRAY); // Wave graph axes @@ -110,17 +110,17 @@ int main(void) DrawText("0", start.x - 8, start.y + start.height/2 - 6, 6, GRAY); DrawText("-1", start.x - 12, start.y + start.height - 8, 6, GRAY); DrawText("0", start.x - 2, start.y + start.height + 4, 6, GRAY); - DrawText("360", start.x + start.width - 8, start.y + start.height + 4, 6, GRAY); + DrawText("360", start.x + start.width - 8, start.y + start.height + 4, 6, GRAY); // Sine (red - vertical) - DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ center.x, point.y }, 2.0f, RED); + DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ center.x, point.y }, 2.0f, RED); DrawLineDashed((Vector2){ point.x, center.y }, (Vector2){ point.x, point.y }, 10.0f, 4.0f, RED); DrawText(TextFormat("Sine %.2f", sinRad), 640, 190, 6, RED); DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-sinRad + 1)*start.height/2.0f) }, 4.0f, RED); DrawSplineLinear(sinePoints, WAVE_POINTS, 1.0f, RED); // Cosine (blue - horizontal) - DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ point.x, center.y }, 2.0f, BLUE); + DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ point.x, center.y }, 2.0f, BLUE); DrawLineDashed((Vector2){ center.x , point.y }, (Vector2){ point.x, point.y }, 10.0f, 4.0f, BLUE); DrawText(TextFormat("Cosine %.2f", cosRad), 640, 210, 6, BLUE); DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-cosRad + 1)*start.height/2.0f) }, 4.0f, BLUE); @@ -135,7 +135,7 @@ int main(void) DrawText(TextFormat("Cotangent %.2f", cotangent), 640, 250, 6, ORANGE); // Complementary angle (beige) - DrawCircleSectorLines(center, radius*0.6f , -angle, -90.f , 36.0f, BEIGE); + DrawCircleSectorLines(center, radius*0.6f , -angle, -90.f , 36.0f, BEIGE); DrawText(TextFormat("Complementary %0.f°",complementary), 640, 150, 6, BEIGE); // Supplementary angle (darkblue) @@ -147,19 +147,19 @@ int main(void) DrawText(TextFormat("Explementary %0.f°",explementary), 640, 170, 6, PINK); // Current angle - arc (lime), radius (black), endpoint (black) - DrawCircleSectorLines(center, radius*0.7f , -angle, 0.f, 36.0f, LIME); + DrawCircleSectorLines(center, radius*0.7f , -angle, 0.f, 36.0f, LIME); DrawLineEx((Vector2){ center.x , center.y }, point, 2.0f, BLACK); DrawCircleV(point, 4.0f, BLACK); // Draw GUI controls //------------------------------------------------------------------------------ GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(GRAY)); - GuiToggle((Rectangle){ 640, 70, 120, 20}, TextFormat("Pause"), &pause); + GuiToggle((Rectangle){ 640, 70, 120, 20}, TextFormat("Pause"), &pause); GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(LIME)); GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.f); // Angle values panel - GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values"); + GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values"); //------------------------------------------------------------------------------ DrawFPS(10, 10); diff --git a/examples/shapes/shapes_mouse_trail.c b/examples/shapes/shapes_mouse_trail.c index e0e5a3c1d..819124220 100644 --- a/examples/shapes/shapes_mouse_trail.c +++ b/examples/shapes/shapes_mouse_trail.c @@ -35,7 +35,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - mouse trail"); // Array to store the history of mouse positions (our fixed-size queue) - Vector2 trailPositions[MAX_TRAIL_LENGTH] = { 0 }; + Vector2 trailPositions[MAX_TRAIL_LENGTH] = { 0 }; SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -62,8 +62,8 @@ int main(void) //---------------------------------------------------------------------------------- BeginDrawing(); - ClearBackground(BLACK); - + ClearBackground(BLACK); + // Draw the trail by looping through the history array for (int i = 0; i < MAX_TRAIL_LENGTH; i++) { @@ -71,22 +71,22 @@ int main(void) if ((trailPositions[i].x != 0.0f) || (trailPositions[i].y != 0.0f)) { // Calculate relative trail strength (ratio is near 1.0 for new, near 0.0 for old) - float ratio = (float)(MAX_TRAIL_LENGTH - i) / MAX_TRAIL_LENGTH; - + float ratio = (float)(MAX_TRAIL_LENGTH - i) / MAX_TRAIL_LENGTH; + // Fade effect: oldest positions are more transparent // Fade (color, alpha) - alpha is 0.5 to 1.0 based on ratio - Color trailColor = Fade(SKYBLUE, ratio*0.5f + 0.5f); - + Color trailColor = Fade(SKYBLUE, ratio*0.5f + 0.5f); + // Size effect: oldest positions are smaller - float trailRadius = 15.0f*ratio; - + float trailRadius = 15.0f*ratio; + DrawCircleV(trailPositions[i], trailRadius, trailColor); } } // Draw a distinct white circle for the current mouse position (Index 0) DrawCircleV(mousePosition, 15.0f, WHITE); - + DrawText("Move the mouse to see the trail effect!", 10, screenHeight - 30, 20, LIGHTGRAY); EndDrawing(); diff --git a/examples/shapes/shapes_pie_chart.c b/examples/shapes/shapes_pie_chart.c index 566e3a4d1..6db7f96da 100644 --- a/examples/shapes/shapes_pie_chart.c +++ b/examples/shapes/shapes_pie_chart.c @@ -67,7 +67,7 @@ int main(void) const Rectangle panelRect = { panelPos.x, panelPos.y, (float)panelWidth, - (float)screenHeight - 2.0f*panelMargin + (float)screenHeight - 2.0f*panelMargin }; // Pie chart geometry @@ -108,13 +108,13 @@ int main(void) for (int i = 0; i < sliceCount; i++) { float sweep = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f; - + if ((angle >= currentAngle) && (angle < (currentAngle + sweep))) { hoveredSlice = i; break; } - + currentAngle += sweep; } } @@ -182,11 +182,11 @@ int main(void) GuiLine((Rectangle){ panelPos.x + 10, (float)panelPos.y + 12 + 170, panelRect.width - 20, 1 }, NULL); // Scrollable area for slice editors - scrollPanelBounds = (Rectangle){ - panelPos.x + panelMargin, - (float)panelPos.y + 12 + 190, - panelRect.width - panelMargin*2, - panelRect.y + panelRect.height - panelPos.y + 12 + 190 - panelMargin + scrollPanelBounds = (Rectangle){ + panelPos.x + panelMargin, + (float)panelPos.y + 12 + 190, + panelRect.width - panelMargin*2, + panelRect.y + panelRect.height - panelPos.y + 12 + 190 - panelMargin }; int contentHeight = sliceCount*35; diff --git a/examples/shapes/shapes_recursive_tree.c b/examples/shapes/shapes_recursive_tree.c index e9cadd8ec..4f1f4d5fd 100644 --- a/examples/shapes/shapes_recursive_tree.c +++ b/examples/shapes/shapes_recursive_tree.c @@ -45,7 +45,7 @@ int main(void) Vector2 start = { (screenWidth/2.0f) - 125.0f, (float)screenHeight }; float angle = 40.0f; - float thick = 1.0f; + float thick = 1.0f; float treeDepth = 10.0f; float branchDecay = 0.66f; float length = 120.0f; @@ -67,21 +67,21 @@ int main(void) Vector2 initialEnd = { start.x + length*sinf(0.0f), start.y - length*cosf(0.0f) }; branches[count++] = (Branch){start, initialEnd, 0.0f, length}; - for (int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { Branch branch = branches[i]; if (branch.length < 2) continue; float nextLength = branch.length*branchDecay; - if (count < maxBranches && nextLength >= 2) + if (count < maxBranches && nextLength >= 2) { Vector2 branchStart = branch.end; float angle1 = branch.angle + theta; Vector2 branchEnd1 = { branchStart.x + nextLength*sinf(angle1), branchStart.y - nextLength*cosf(angle1) }; branches[count++] = (Branch){branchStart, branchEnd1, angle1, nextLength}; - + float angle2 = branch.angle - theta; Vector2 branchEnd2 = { branchStart.x + nextLength*sinf(angle2), branchStart.y - nextLength*cosf(angle2) }; branches[count++] = (Branch){branchStart, branchEnd2, angle2, nextLength}; @@ -94,10 +94,10 @@ int main(void) ClearBackground(RAYWHITE); - for (int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { Branch branch = branches[i]; - if (branch.length >= 2) + if (branch.length >= 2) { if (bezier) DrawLineBezier(branch.start, branch.end, thick, RED); else DrawLineEx(branch.start, branch.end, thick, RED); diff --git a/examples/shapes/shapes_rlgl_triangle.c b/examples/shapes/shapes_rlgl_triangle.c index 37626a5c8..56cdc43bc 100644 --- a/examples/shapes/shapes_rlgl_triangle.c +++ b/examples/shapes/shapes_rlgl_triangle.c @@ -50,7 +50,7 @@ int main(void) // Update //---------------------------------------------------------------------------------- if (IsKeyPressed(KEY_SPACE)) linesMode = !linesMode; - + // Check selected vertex for (unsigned int i = 0; i < 3; i++) { @@ -72,7 +72,7 @@ int main(void) position->x += mouseDelta.x; position->y += mouseDelta.y; } - + // Reset index on release if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) triangleIndex = -1; @@ -139,15 +139,15 @@ int main(void) // Render the vertex handles, reacting to mouse movement/input for (unsigned int i = 0; i < 3; i++) { - // Draw handle fill focused by mouse + // Draw handle fill focused by mouse if (CheckCollisionPointCircle(GetMousePosition(), trianglePositions[i], handleRadius)) DrawCircleV(trianglePositions[i], handleRadius, ColorAlpha(DARKGRAY, 0.5f)); - + // Draw handle fill selected if (i == triangleIndex) DrawCircleV(trianglePositions[i], handleRadius, DARKGRAY); - + // Draw handle outline - DrawCircleLinesV(trianglePositions[i], handleRadius, BLACK); + DrawCircleLinesV(trianglePositions[i], handleRadius, BLACK); } // Draw controls diff --git a/examples/shapes/shapes_simple_particles.c b/examples/shapes/shapes_simple_particles.c index c5d9612c3..7be0c82e4 100644 --- a/examples/shapes/shapes_simple_particles.c +++ b/examples/shapes/shapes_simple_particles.c @@ -36,7 +36,7 @@ static const char particleTypeNames[3][10] = { "WATER", "SMOKE", "FIRE" }; typedef struct Particle { ParticleType type; // Particle type (WATER, SMOKE, FIRE) Vector2 position; // Particle position on screen - Vector2 velocity; // Particle current speed and direction + Vector2 velocity; // Particle current speed and direction float radius; // Particle radius Color color; // Particle color @@ -45,9 +45,9 @@ typedef struct Particle { } Particle; typedef struct CircularBuffer { - int head; // Index for the next write - int tail; // Index for the next read - Particle *buffer; // Particle buffer array + int head; // Index for the next write + int tail; // Index for the next read + Particle *buffer; // Particle buffer array } CircularBuffer; //---------------------------------------------------------------------------------- @@ -73,12 +73,12 @@ int main(void) // Definition of particles Particle *particles = (Particle*)RL_CALLOC(MAX_PARTICLES, sizeof(Particle)); // Particle array - CircularBuffer circularBuffer = { 0, 0, particles }; + CircularBuffer circularBuffer = { 0, 0, particles }; - // Particle emitter parameters + // Particle emitter parameters int emissionRate = -2; // Negative: on average every -X frames. Positive: particles per frame - ParticleType currentType = WATER; - Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.0f }; + ParticleType currentType = WATER; + Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.0f }; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -88,7 +88,7 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // Emit new particles: when emissionRate is 1, emit every frame + // Emit new particles: when emissionRate is 1, emit every frame if (emissionRate < 0) { if (rand()%(-emissionRate) == 0) EmitParticle(&circularBuffer, emitterPosition, currentType); @@ -96,9 +96,9 @@ int main(void) else { for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType); - } + } - // Update the parameters of each particle + // Update the parameters of each particle UpdateParticles(&circularBuffer, screenWidth, screenHeight); // Remove dead particles from the circular buffer @@ -112,7 +112,7 @@ int main(void) if (IsKeyPressed(KEY_RIGHT)) (currentType == FIRE)? (currentType = WATER) : currentType++; if (IsKeyPressed(KEY_LEFT)) (currentType == WATER)? (currentType = FIRE) : currentType--; - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition(); + if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition(); //---------------------------------------------------------------------------------- // Draw @@ -121,7 +121,7 @@ int main(void) ClearBackground(RAYWHITE); - // Call the function with a loop to draw all particles + // Call the function with a loop to draw all particles DrawParticles(&circularBuffer); // Draw UI and Instructions @@ -133,7 +133,7 @@ int main(void) DrawText("LEFT/RIGHT: Change Particle Type (Water, Smoke, Fire)", 15, 55, 10, BLACK); if (emissionRate < 0) DrawText(TextFormat("Particles every %d frames | Type: %s", -emissionRate, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY); - else DrawText(TextFormat("%d Particles per frame | Type: %s", emissionRate + 1, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY); + else DrawText(TextFormat("%d Particles per frame | Type: %s", emissionRate + 1, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY); DrawFPS(screenWidth - 80, 10); @@ -200,12 +200,12 @@ static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer) // Check if buffer full if (((circularBuffer->head + 1)%MAX_PARTICLES) != circularBuffer->tail) { - // Add new particle to the head position and advance head + // Add new particle to the head position and advance head particle = &circularBuffer->buffer[circularBuffer->head]; circularBuffer->head = (circularBuffer->head + 1)%MAX_PARTICLES; } - return particle; + return particle; } static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight) @@ -213,7 +213,7 @@ static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES) { // Update particle life and positions - circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame + circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame switch (circularBuffer->buffer[i].type) { @@ -226,32 +226,32 @@ static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int case SMOKE: { circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x; - circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards + circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y; circularBuffer->buffer[i].radius += 0.5f; // Increment radius: smoke expands - circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades - + circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades + // If alpha transparent, particle dies if (circularBuffer->buffer[i].color.a < 4) circularBuffer->buffer[i].alive = false; } break; case FIRE: { - // Add a little horizontal oscillation to fire particles + // Add a little horizontal oscillation to fire particles circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x + cosf(circularBuffer->buffer[i].lifeTime*215.0f); circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y; - circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks - circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow - + circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks + circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow + // If radius too small, particle dies if (circularBuffer->buffer[i].radius <= 0.02f) circularBuffer->buffer[i].alive = false; } break; default: break; } - // Disable particle when out of screen + // Disable particle when out of screen Vector2 center = circularBuffer->buffer[i].position; - float radius = circularBuffer->buffer[i].radius; + float radius = circularBuffer->buffer[i].radius; if ((center.x < -radius) || (center.x > (screenWidth + radius)) || (center.y < -radius) || (center.y > (screenHeight + radius))) @@ -267,7 +267,7 @@ static void UpdateCircularBuffer(CircularBuffer *circularBuffer) while ((circularBuffer->tail != circularBuffer->head) && !circularBuffer->buffer[circularBuffer->tail].alive) { circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES; - } + } } static void DrawParticles(CircularBuffer *circularBuffer) diff --git a/examples/shapes/shapes_triangle_strip.c b/examples/shapes/shapes_triangle_strip.c index 3172e1f7f..3b44da5e0 100644 --- a/examples/shapes/shapes_triangle_strip.c +++ b/examples/shapes/shapes_triangle_strip.c @@ -39,7 +39,7 @@ int main(void) float insideRadius = 100.0f; float outsideRadius = 150.0f; bool outline = true; - + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -79,14 +79,14 @@ int main(void) float angle1 = i*angleStep; DrawTriangle(c, b, a, ColorFromHSV(angle1*RAD2DEG, 1.0f, 1.0f)); DrawTriangle(d, b, c, ColorFromHSV((angle1 + angleStep/2)*RAD2DEG, 1.0f, 1.0f)); - + if (outline) { DrawTriangleLines(a, b, c, BLACK); DrawTriangleLines(c, b, d, BLACK); } } - + DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 }); DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 }); diff --git a/examples/shapes/shapes_vector_angle.c b/examples/shapes/shapes_vector_angle.c index b5faf4c78..464af1bd1 100644 --- a/examples/shapes/shapes_vector_angle.c +++ b/examples/shapes/shapes_vector_angle.c @@ -25,7 +25,7 @@ int main(void) // Initialization //-------------------------------------------------------------------------------------- const int screenWidth = 800; - + const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [shapes] example - vector angle"); diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c index 0e5e8091f..adedc4056 100644 --- a/examples/text/text_inline_styling.c +++ b/examples/text/text_inline_styling.c @@ -36,11 +36,11 @@ int main(void) const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [text] example - inline styling"); - + Vector2 textSize = { 0 }; // Measure text box for provided font and text Color colRandom = RED; // Random color used on text int frameCounter = 0; // Used to generate a new random color every certain frames - + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -50,7 +50,7 @@ int main(void) // Update //---------------------------------------------------------------------------------- frameCounter++; - + if ((frameCounter%20) == 0) { colRandom.r = (unsigned char)GetRandomValue(0, 255); @@ -67,12 +67,12 @@ int main(void) ClearBackground(RAYWHITE); // Text inline styling strategy used: [ ] delimiters for format - // - Define foreground color: [cRRGGBBAA] + // - Define foreground color: [cRRGGBBAA] // - Define background color: [bRRGGBBAA] // - Reset formating: [r] // Example: [bAA00AAFF][cFF0000FF]red text on gray background[r] normal text - - DrawTextStyled(GetFontDefault(), "This changes the [cFF0000FF]foreground color[r] of provided text!!!", + + DrawTextStyled(GetFontDefault(), "This changes the [cFF0000FF]foreground color[r] of provided text!!!", (Vector2){ 100, 80 }, 20.0f, 2.0f, BLACK); DrawTextStyled(GetFontDefault(), "This changes the [bFF00FFFF]background color[r] of provided text!!!", @@ -80,11 +80,11 @@ int main(void) DrawTextStyled(GetFontDefault(), "This changes the [c00ff00ff][bff0000ff]foreground and background colors[r]!!!", (Vector2){ 100, 160 }, 20.0f, 2.0f, BLACK); - + // Get pointer to formated text const char *text = TextFormat("Let's be [c%02x%02x%02xFF]CREATIVE[r] !!!", colRandom.r, colRandom.g, colRandom.b); DrawTextStyled(GetFontDefault(), text, (Vector2){ 100, 220 }, 40.0f, 2.0f, BLACK); - + textSize = MeasureTextStyled(GetFontDefault(), text, 40.0f, 2.0f); DrawRectangleLines(100, 220, (int)textSize.x, (int)textSize.y, GREEN); @@ -108,13 +108,13 @@ int main(void) static void DrawTextStyled(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color color) { // Text inline styling strategy used: [ ] delimiters for format - // - Define foreground color: [cRRGGBBAA] + // - Define foreground color: [cRRGGBBAA] // - Define background color: [bRRGGBBAA] // - Reset formating: [r] // Example: [bAA00AAFF][cFF0000FF]red text on gray background[r] normal text - + if (font.texture.id == 0) font = GetFontDefault(); - + int textLen = TextLength(text); Color colFront = color; @@ -144,14 +144,14 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float { colFront = color; colBack = BLANK; - + i += 3; // Skip "[r]" continue; // Do not draw characters } else if (((i + 1) < textLen) && ((text[i + 1] == 'c') || (text[i + 1] == 'b'))) { i += 2; // Skip "[c" or "[b" to start parsing color - + // Parse following color char colHexText[9] = { 0 }; const char *textPtr = &text[i]; // Color should start here, let's see... @@ -168,12 +168,12 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float } else break; // Only affects while loop } - + // Convert hex color text into actual Color unsigned int colHexValue = strtoul(colHexText, NULL, 16); if (text[i - 1] == 'c') colFront = GetColor(colHexValue); else if (text[i - 1] == 'b') colBack = GetColor(colHexValue); - + i += (colHexCount + 1); // Skip color value retrieved and ']' continue; // Do not draw characters } @@ -249,7 +249,7 @@ static Vector2 MeasureTextStyled(Font font, const char *text, float fontSize, fl } else break; // Only affects while loop } - + i += (colHexCount + 1); // Skip color value retrieved and ']' continue; // Do not measure characters } @@ -260,7 +260,7 @@ static Vector2 MeasureTextStyled(Font font, const char *text, float fontSize, fl if (font.glyphs[index].advanceX > 0) textWidth += font.glyphs[index].advanceX; else textWidth += (font.recs[index].width + font.glyphs[index].offsetX); - + validCodepointCounter++; i += codepointByteCount; } diff --git a/examples/text/text_unicode_ranges.c b/examples/text/text_unicode_ranges.c index e54c052b1..76ee75f8d 100644 --- a/examples/text/text_unicode_ranges.c +++ b/examples/text/text_unicode_ranges.c @@ -58,7 +58,7 @@ int main(void) // Load font with default Unicode range: Basic ASCII [32-127] font = LoadFont("resources/NotoSansTC-Regular.ttf"); - + // Add required ranges to loaded font switch (unicodeRange) { @@ -128,11 +128,11 @@ int main(void) // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); DrawText("ADD CODEPOINTS: [1][2][3][4]", 20, 20, 20, MAROON); - + // Render test strings in different languages DrawTextEx(font, "> English: Hello World!", (Vector2){ 50, 70 }, 32, 1, DARKGRAY); // English DrawTextEx(font, "> Español: Hola mundo!", (Vector2){ 50, 120 }, 32, 1, DARKGRAY); // Spanish @@ -141,7 +141,7 @@ int main(void) DrawTextEx(font, "> 中文: 你好世界!", (Vector2){ 50, 270 }, 32, 1, DARKGRAY); // Chinese DrawTextEx(font, "> 日本語: こんにちは世界!", (Vector2){ 50, 320 }, 32, 1, DARKGRAY); // Japanese //DrawTextEx(font, "देवनागरी: होला मुंडो!", (Vector2){ 50, 350 }, 32, 1, DARKGRAY); // Devanagari (glyphs not available in font) - + // Draw font texture scaled to screen float atlasScale = 380.0f/font.texture.width; DrawRectangleRec((Rectangle) { 400.0f, 16.0f, font.texture.width* atlasScale, font.texture.height* atlasScale }, BLACK); @@ -161,7 +161,7 @@ int main(void) DrawRectangle(0, 125, screenWidth, 200, GRAY); DrawText("GENERATING FONT ATLAS...", 120, 210, 40, BLACK); } - + EndDrawing(); //---------------------------------------------------------------------------------- } @@ -184,10 +184,10 @@ static void AddCodepointRange(Font *font, const char *fontPath, int start, int s { int rangeSize = stop - start + 1; int currentRangeSize = font->glyphCount; - + // TODO: Load glyphs from provided vector font (if available), // add them to existing font, regenerating font image and texture - + int updatedCodepointCount = currentRangeSize + rangeSize; int *updatedCodepoints = (int *)RL_CALLOC(updatedCodepointCount, sizeof(int)); diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c index 352b3cd37..103e24e59 100644 --- a/examples/text/text_words_alignment.c +++ b/examples/text/text_words_alignment.c @@ -39,25 +39,25 @@ int main(void) const int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [text] example - words alignment"); - + // Define the rectangle we will draw the text in Rectangle textContainerRect = (Rectangle){ screenWidth/2-screenWidth/4, screenHeight/2-screenHeight/3, screenWidth/2, screenHeight*2/3 }; // Some text to display the current alignment const char *textAlignNameH[] = { "Left", "Centre", "Right" }; const char *textAlignNameV[] = { "Top", "Middle", "Bottom" }; - + // Define the text we're going to draw in the rectangle int wordIndex = 0; int wordCount = 0; char **words = TextSplit("raylib is a simple and easy-to-use library to enjoy videogames programming", ' ', &wordCount); - + // Initialize the font size we're going to use int fontSize = 40; - + // And of course the font... Font font = GetFontDefault(); - + // Intialize the alignment variables TextAlignment hAlign = TEXT_ALIGN_CENTRE; TextAlignment vAlign = TEXT_ALIGN_MIDDLE; @@ -70,7 +70,7 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - + if (IsKeyPressed(KEY_LEFT)) { hAlign = hAlign - 1; if (hAlign < 0) hAlign = 0; @@ -87,10 +87,10 @@ int main(void) vAlign = vAlign + 1; if (vAlign > 2) vAlign = 2; } - + // One word per second wordIndex = (int)GetTime() % wordCount; - + //---------------------------------------------------------------------------------- // Draw @@ -103,16 +103,16 @@ int main(void) DrawText(TextFormat("Alignment: Horizontal = %s, Vertical = %s", textAlignNameH[hAlign], textAlignNameV[vAlign]), 20, 40, 20, LIGHTGRAY); DrawRectangleRec(textContainerRect, BLUE); - + // Get the size of the text to draw Vector2 textSize = MeasureTextEx(font, words[wordIndex], fontSize, fontSize*.1f); - + // Calculate the top-left text position based on the rectangle and alignment Vector2 textPos = (Vector2) { textContainerRect.x + Lerp(0.0f, textContainerRect.width - textSize.x, ((float)hAlign) * 0.5f), textContainerRect.y + Lerp(0.0f, textContainerRect.height - textSize.y, ((float)vAlign) * 0.5f) }; - + // Draw the text DrawTextEx(font, words[wordIndex], textPos, fontSize, fontSize*.1f, RAYWHITE); diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c index 4c737901b..98c9a2ad5 100644 --- a/examples/textures/textures_screen_buffer.c +++ b/examples/textures/textures_screen_buffer.c @@ -45,7 +45,7 @@ int main(void) Color palette[MAX_COLORS] = {0}; unsigned char indexBuffer[INDEX_BUFFER_SIZE] = {0}; unsigned char flameRootBuffer[FLAME_WIDTH] = {0}; - + Image screenImage = GenImageColor(imageWidth, imageHeight, BLACK); Texture screenTexture = LoadTextureFromImage(screenImage); GeneretePalette(palette); @@ -74,7 +74,7 @@ int main(void) int i = x + (imageHeight - 1) * imageWidth; indexBuffer[i] = flameRootBuffer[x]; } - + // Clear top row, because it can't move any higher for (int x = 0; x < imageWidth; ++x) { @@ -90,7 +90,7 @@ int main(void) unsigned 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; @@ -115,7 +115,7 @@ int main(void) ImageDrawPixel(&screenImage, x, y, col); } } - + UpdateTexture(screenTexture, screenImage.data); // Draw //---------------------------------------------------------------------------------- From d26435703f7ddbe33de652b92e0b215fed2bb3d2 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:18:13 +0100 Subject: [PATCH 151/189] Update rcore_desktop_win32.c --- 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 ce80eb41b..f832f410b 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -195,8 +195,8 @@ static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 //---------------------------------------------------------------------------------- // Types and Structures Definition From 82ad486e6b9336d1fc154d06d477fe7b5125374a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:18:47 +0100 Subject: [PATCH 152/189] Update rexm.c --- tools/rexm/rexm.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 5c89a9233..e8cb8c93c 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -2598,29 +2598,29 @@ static int AddVSProjectToSolution(const char *slnFile, const char *projFile, con // Add project config lines offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t{%s}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x64.Build.0 = Debug.DLL|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|ARM64.ActiveCfg = Debug|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|ARM64.Build.0 = Debug|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x64.ActiveCfg = Debug|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x64.Build.0 = Debug|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x86.ActiveCfg = Debug|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x86.Build.0 = Debug|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x64.ActiveCfg = Release.DLL|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x64.Build.0 = Release.DLL|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x86.Build.0 = Release.DLL|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|ARM64.ActiveCfg = Release|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|ARM64.Build.0 = Release|ARM64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x64.ActiveCfg = Release|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x64.Build.0 = Release|x64\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x86.ActiveCfg = Release|Win32\n", uuid)); - offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x86.Build.0 = Release|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x64.Build.0 = Debug.DLL|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|ARM64.ActiveCfg = Debug|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|ARM64.Build.0 = Debug|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x64.ActiveCfg = Debug|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x64.Build.0 = Debug|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x86.ActiveCfg = Debug|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x86.Build.0 = Debug|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x64.ActiveCfg = Release.DLL|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x64.Build.0 = Release.DLL|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x86.Build.0 = Release.DLL|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|ARM64.ActiveCfg = Release|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|ARM64.Build.0 = Release|ARM64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x64.ActiveCfg = Release|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x64.Build.0 = Release|x64\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x86.ActiveCfg = Release|Win32\n", uuid)); + offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x86.Build.0 = Release|Win32\n", uuid)); // Write next section directly to avoid copy logic offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tEndGlobalSection\n"); offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tGlobalSection(SolutionProperties) = preSolution\n"); From ee3d65cbc9f0a68c4d1c07ca3784f1c5e211492d Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 13:25:54 +0100 Subject: [PATCH 153/189] Update examples_testing_web.md --- tools/rexm/reports/examples_testing_web.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/rexm/reports/examples_testing_web.md b/tools/rexm/reports/examples_testing_web.md index 2e8cb5fb3..1704b5986 100644 --- a/tools/rexm/reports/examples_testing_web.md +++ b/tools/rexm/reports/examples_testing_web.md @@ -17,7 +17,6 @@ Example automated testing elements validated: | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| | core_monitor_detector | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_lines_drawing | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | textures_screen_buffer | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_sprite_fonts | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | @@ -27,7 +26,6 @@ Example automated testing elements validated: | models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | models_mesh_generation | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_loading_gltf | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | -| models_loading_vox | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | models_bone_socket | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | models_decals | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | shaders_postprocessing | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | @@ -35,6 +33,5 @@ Example automated testing elements validated: | shaders_shadowmap_rendering | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | shaders_basic_pbr | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | audio_module_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| audio_sound_positioning | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | audio_fft_spectrum_visualizer | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | From 1f7f9ab22b707aeb84ccbaa2bb4c9edc042b9fd9 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 19:30:07 +0100 Subject: [PATCH 154/189] Ignore examples binaries on Linux (and automated logs) --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index ddbc5c11d..3a95edc19 100644 --- a/.gitignore +++ b/.gitignore @@ -62,10 +62,14 @@ packages/ emsdk # Ignore wasm data in examples/ +examples/**/* examples/**/*.wasm examples/**/*.data examples/**/*.js examples/**/*.html +!examples/**/*.* +!examples/**/*/ +examples/**/logs/* # Ignore files build by xcode *.mode*v* From 282c4b0eabb41733f2587129a5dd924ce0d2e2d2 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 19:30:25 +0100 Subject: [PATCH 155/189] Minor teaks to run on Linux --- tools/rexm/rexm.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index e8cb8c93c..6aba90f6f 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -51,9 +51,9 @@ #include "raylib.h" -#include // Required for: NULL, calloc(), free() #include // Required for: rename(), remove() #include // Required for: strcmp(), strcpy() +#include // Required for: NULL, calloc(), free() #define SUPPORT_LOG_INFO #if defined(SUPPORT_LOG_INFO) //&& defined(_DEBUG) @@ -1517,7 +1517,7 @@ int main(int argc, char *argv[]) TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); char *srcText = LoadFileText(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); -#define BUILD_TESTING_WEB +//#define BUILD_TESTING_WEB #if defined(BUILD_TESTING_WEB) static const char *mainReplaceText = "#include \n" @@ -1620,8 +1620,9 @@ int main(int argc, char *argv[]) exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); - system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); -#endif + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", + exBasePath, exCategory, exName, exBasePath, exCategory, exName)); + #endif // Restore original source code before continue FileCopy(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName), TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName)); @@ -1630,7 +1631,7 @@ int main(int argc, char *argv[]) // STEP 3: Run example with required arguments // NOTE: Not easy to retrieve process return value from system(), it's platform dependant ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); - system(TextFormat("%s --frames 2 > logs/%s.log", exName, exName)); + system(TextFormat("./%s --frames 2 > logs/%s.log", exName, exName)); #endif } } break; @@ -1712,7 +1713,9 @@ int main(int argc, char *argv[]) char **exTestLogLines = LoadTextLines(exTestLog, &exTestLogLinesCount); for (int k = 0; k < exTestLogLinesCount; k++) { - if (TextFindIndex(exTestLogLines[k], "WARNING: GL: NPOT") >= 0) continue; // Ignore warning +#if defined(BUILD_TESTING_WEB) + if (TextFindIndex(exTestLogLines[k], "WARNING: GL: NPOT") >= 0) continue; // Ignore web-specific warning +#endif if (TextFindIndex(exTestLogLines[k], "WARNING") >= 0) testing[i].warnings++; } UnloadTextLines(exTestLogLines, exTestLogLinesCount); @@ -1842,6 +1845,7 @@ int main(int argc, char *argv[]) printf(" rename : Rename an existing example\n"); printf(" remove : Remove an existing example\n"); printf(" build : Build example for Desktop and Web platforms\n"); + printf(" test : Build and Test example for Desktop and Web platforms\n"); printf(" validate : Validate examples collection, generates report\n"); printf(" update : Validate and update examples collection, generates report\n\n"); printf("OPTIONS:\n\n"); From 5aee9f9d509aced47507381c6f88e259551696fa Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 19:31:17 +0100 Subject: [PATCH 156/189] Create examples_testing_linux.md --- tools/rexm/reports/examples_testing_linux.md | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tools/rexm/reports/examples_testing_linux.md diff --git a/tools/rexm/reports/examples_testing_linux.md b/tools/rexm/reports/examples_testing_linux.md new file mode 100644 index 000000000..983ba1b3d --- /dev/null +++ b/tools/rexm/reports/examples_testing_linux.md @@ -0,0 +1,37 @@ +# EXAMPLES COLLECTION - TESTING REPORT + +## Tested Platform: Linux + +``` +Example automated testing elements validated: + - [CWARN] : Compilation WARNING messages + - [LWARN] : Log WARNING messages count + - [INIT] : Initialization + - [CLOSE] : Closing + - [ASSETS] : Assets loading + - [RLGL] : OpenGL-wrapped initialization + - [PLAT] : Platform initialization + - [FONT] : Font default initialization + - [TIMER] : Timer initialization +``` +| **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | +|:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| core_directory_files | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_clipboard_text | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_compute_hash | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_recursive_tree | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_ring_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_circle_sector_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rounded_rectangle_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_splines_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_triangle_strip | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_pie_chart | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_math_sine_cosine | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| shapes_rlgl_color_wheel | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | +| text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | +| shaders_palette_switch | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| shaders_color_correction | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | + From 646e814baf9c477658ec8306ca346941a5101eee Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 19:41:35 +0100 Subject: [PATCH 157/189] Update Makefile --- examples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Makefile b/examples/Makefile index edddb366e..b2feec0db 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -231,7 +231,7 @@ endif # -Wno-missing-braces ignore invalid warning (GCC bug 53119) # -Wno-unused-value ignore unused return values of some functions (i.e. fread()) # -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec -CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result +CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wno-unused-result ifeq ($(BUILD_MODE),DEBUG) CFLAGS += -g -D_DEBUG From 8fcd99c8ddbaa3e4a130bbff82e7c36c82758cc6 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 19:41:39 +0100 Subject: [PATCH 158/189] Update textures_sprite_stacking.c --- examples/textures/textures_sprite_stacking.c | 50 ++++++++------------ 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/examples/textures/textures_sprite_stacking.c b/examples/textures/textures_sprite_stacking.c index a2cb04d2f..5edc1af6b 100644 --- a/examples/textures/textures_sprite_stacking.c +++ b/examples/textures/textures_sprite_stacking.c @@ -17,7 +17,8 @@ ********************************************************************************************/ #include "raylib.h" -#include "raymath.h" + +#include "raymath.h" // Required for: Clamp() //------------------------------------------------------------------------------------ // Program main entry point @@ -33,18 +34,14 @@ int main(void) Texture2D booth = LoadTexture("resources/booth.png"); - // The overall scale of the stacked sprite - float stackScale = 3.0f; - // The vertical spacing between each layer - float stackSpacing = 2.0f; - // The number of layers. Used for calculating the size of a single slice - unsigned int stackCount = 122; - // The speed to rotate the stacked sprite - float rotationSpeed = 30.0f; - // The current rotation of the stacked sprite - float rotation = 0.0f; - // The amount that speed will change by when the user presses A/D - const float speedChange = 0.25f; + float stackScale = 3.0f; // Overall scale of the stacked sprite + float stackSpacing = 2.0f; // Vertical spacing between each layer + unsigned int stackCount = 122; // Number of layers, used for calculating the size of a single slice + float rotationSpeed = 30.0f; // Stacked sprites rotation speed + float rotation = 0.0f; // Current rotation of the stacked sprite + const float speedChange = 0.25f; // Amount speed will change by when the user presses A/D + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -57,22 +54,16 @@ int main(void) stackSpacing = Clamp(stackSpacing, 0.0f, 5.0f); // Add a positive/negative offset to spin right/left at different speeds - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) - { - rotationSpeed -= speedChange; - } - - if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) - { - rotationSpeed += speedChange; - } - - rotation += rotationSpeed * GetFrameTime(); + if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) rotationSpeed -= speedChange; + if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) rotationSpeed += speedChange; + + rotation += rotationSpeed*GetFrameTime(); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); + ClearBackground(RAYWHITE); // Get the size of a single slice @@ -86,20 +77,19 @@ int main(void) // Draw the stacked sprite, rotated to the correct angle, with an vertical offset applied based on its y location for (int i = stackCount - 1; i >= 0; i--) { - Rectangle source = { 0.0f, (float)i*frameHeight, frameWidth, frameHeight }; // Center vertically + Rectangle source = { 0.0f, (float)i*frameHeight, frameWidth, frameHeight }; Rectangle dest = { screenWidth/2.0f, (screenHeight/2.0f) + (i*stackSpacing) - (stackSpacing*stackCount/2.0f), scaledWidth, scaledHeight }; Vector2 origin = { scaledWidth/2.0f, scaledHeight/2.0f }; DrawTexturePro(booth, source, dest, origin, rotation, WHITE); } - DrawText("a/d to spin\nmouse wheel to change separation (aka 'angle')", 10, 10, 20, DARKGRAY); - const char *spacingText = TextFormat("current spacing: %.01f", stackSpacing); - DrawText(spacingText, 10, 50, 20, DARKGRAY); - const char *speedText = TextFormat("current speed: %.02f", rotationSpeed); - DrawText(speedText, 10, 70, 20, DARKGRAY); + DrawText("A/D to spin\nmouse wheel to change separation (aka 'angle')", 10, 10, 20, DARKGRAY); + DrawText(TextFormat("current spacing: %.01f", stackSpacing), 10, 50, 20, DARKGRAY); + DrawText(TextFormat("current speed: %.02f", rotationSpeed), 10, 70, 20, DARKGRAY); DrawText("redbooth model (c) kluchek under cc 4.0", 10, 420, 20, DARKGRAY); + EndDrawing(); //---------------------------------------------------------------------------------- } From 49868b356f47f2a1eafed7458c2904df139511ae Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 19 Nov 2025 19:41:43 +0100 Subject: [PATCH 159/189] Update examples_testing_linux.md --- tools/rexm/reports/examples_testing_linux.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tools/rexm/reports/examples_testing_linux.md b/tools/rexm/reports/examples_testing_linux.md index 983ba1b3d..8f6c377ee 100644 --- a/tools/rexm/reports/examples_testing_linux.md +++ b/tools/rexm/reports/examples_testing_linux.md @@ -16,22 +16,7 @@ Example automated testing elements validated: ``` | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| -| core_directory_files | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_clipboard_text | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_compute_hash | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_recursive_tree | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_ring_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_circle_sector_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_rounded_rectangle_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_splines_drawing | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_triangle_strip | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_pie_chart | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_math_sine_cosine | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| shapes_rlgl_color_wheel | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| shaders_palette_switch | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | -| shaders_color_correction | 10 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 29173a49784f1a4e06fa93f9fd1f50816f90bca6 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 00:00:51 +0100 Subject: [PATCH 160/189] Update .gitignore --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3a95edc19..e5f6faf4d 100644 --- a/.gitignore +++ b/.gitignore @@ -63,12 +63,13 @@ emsdk # Ignore wasm data in examples/ examples/**/* +!examples/**/*.* +!examples/**/*/ +examples/**/*.exe examples/**/*.wasm examples/**/*.data examples/**/*.js examples/**/*.html -!examples/**/*.* -!examples/**/*/ examples/**/logs/* # Ignore files build by xcode From 67f24b3b41f9d1021cb2161b0f23886185572839 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 00:01:06 +0100 Subject: [PATCH 161/189] Update audio_sound_positioning.c --- examples/audio/audio_sound_positioning.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/audio/audio_sound_positioning.c b/examples/audio/audio_sound_positioning.c index 4d29954f6..9159acf08 100644 --- a/examples/audio/audio_sound_positioning.c +++ b/examples/audio/audio_sound_positioning.c @@ -69,6 +69,7 @@ int main(void) }; SetSoundPosition(camera, sound, spherePos, 20.0f); + if (!IsSoundPlaying(sound)) PlaySound(sound); //---------------------------------------------------------------------------------- @@ -94,6 +95,8 @@ int main(void) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- + + return 0; } //------------------------------------------------------------------------------------ From ba65bd7f994ef9aeecdc155a2918430642bf21d6 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 00:03:03 +0100 Subject: [PATCH 162/189] WARNING: BREAKING: Redesigned `SetSoundPan()` and `SetMusicPan()` #5350 Now it goes from -1.0 (full left) to 1.0 (full right) being 0.0 center --- src/raudio.c | 12 ++++++------ src/raylib.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index de2bf81b2..66e04fad6 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -593,7 +593,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam // Init audio buffer values audioBuffer->volume = 1.0f; audioBuffer->pitch = 1.0f; - audioBuffer->pan = 0.5f; + audioBuffer->pan = 0.0f; // Center audioBuffer->callback = NULL; audioBuffer->processor = NULL; @@ -720,7 +720,7 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch) // Set pan for an audio buffer void SetAudioBufferPan(AudioBuffer *buffer, float pan) { - if (pan < 0.0f) pan = 0.0f; + if (pan < -1.0f) pan = -1.0f; else if (pan > 1.0f) pan = 1.0f; if (buffer != NULL) @@ -985,10 +985,10 @@ Sound LoadSoundAlias(Sound source) audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames; audioBuffer->data = source.stream.buffer->data; - // initalize the buffer as if it was new + // Initalize the buffer as if it was new audioBuffer->volume = 1.0f; audioBuffer->pitch = 1.0f; - audioBuffer->pan = 0.5f; + audioBuffer->pan = 0.0f; // Center sound.frameCount = source.frameCount; sound.stream.sampleRate = AUDIO.System.device.sampleRate; @@ -2605,8 +2605,8 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr if (channels == 2) // We consider panning { - const float left = buffer->pan; - const float right = 1.0f - left; + const float right = (buffer->pan + 1.0f)/2.0f; // Normalize: [-1..1] -> [0..1] + const float left = 1.0f - right; // Fast sine approximation in [0..1] for pan law: y = 0.5f*x*(3 - x*x); const float levels[2] = { localVolume*0.5f*left*(3.0f - left*left), localVolume*0.5f*right*(3.0f - right*right) }; diff --git a/src/raylib.h b/src/raylib.h index 2f9ec2268..67279753a 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1672,7 +1672,7 @@ RLAPI void ResumeSound(Sound sound); // Resume RLAPI bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing RLAPI void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) -RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.5 is center) +RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave RLAPI void WaveCrop(Wave *wave, int initFrame, int finalFrame); // Crop a wave to defined frames range RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format @@ -1693,7 +1693,7 @@ RLAPI void ResumeMusicStream(Music music); // Resume RLAPI void SeekMusicStream(Music music, float position); // Seek music to a position (in seconds) RLAPI void SetMusicVolume(Music music, float volume); // Set volume for music (1.0 is max level) RLAPI void SetMusicPitch(Music music, float pitch); // Set pitch for a music (1.0 is base level) -RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (0.5 is center) +RLAPI void SetMusicPan(Music music, float pan); // Set pan for a music (-1.0 left, 0.0 center, 1.0 right) RLAPI float GetMusicTimeLength(Music music); // Get music time length (in seconds) RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) From 30cd36a8a9feaa81d8dd46a2875a961ed85fd48d Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 00:03:08 +0100 Subject: [PATCH 163/189] Update audio_music_stream.c --- examples/audio/audio_music_stream.c | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/examples/audio/audio_music_stream.c b/examples/audio/audio_music_stream.c index 48be49e42..4533ff30b 100644 --- a/examples/audio/audio_music_stream.c +++ b/examples/audio/audio_music_stream.c @@ -35,6 +35,12 @@ int main(void) float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f] bool pause = false; // Music playing paused + + float pan = 0.0f; // Default audio pan center [-1.0f..1.0f] + SetMusicPan(music, pan); + + float volume = 0.8f; // Default audio volume [0.0f..1.0f] + SetMusicVolume(music, volume); SetTargetFPS(30); // Set our game to run at 30 frames-per-second //-------------------------------------------------------------------------------------- @@ -61,6 +67,34 @@ int main(void) if (pause) PauseMusicStream(music); else ResumeMusicStream(music); } + + // Set audio pan + if (IsKeyDown(KEY_LEFT)) + { + pan -= 0.05f; + if (pan < -1.0f) pan = -1.0f; + SetMusicPan(music, pan); + } + else if (IsKeyDown(KEY_RIGHT)) + { + pan += 0.05f; + if (pan > 1.0f) pan = 1.0f; + SetMusicPan(music, pan); + } + + // Set audio volume + if (IsKeyDown(KEY_DOWN)) + { + volume -= 0.05f; + if (volume < 0.0f) volume = 0.0f; + SetMusicVolume(music, volume); + } + else if (IsKeyDown(KEY_UP)) + { + volume += 0.05f; + if (volume > 1.0f) volume = 1.0f; + SetMusicVolume(music, volume); + } // Get normalized time played for current music stream timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music); @@ -75,6 +109,11 @@ int main(void) ClearBackground(RAYWHITE); DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY); + + 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(200, 200, 400, 12, LIGHTGRAY); DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON); @@ -82,6 +121,11 @@ int main(void) DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY); DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY); + + 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); EndDrawing(); //---------------------------------------------------------------------------------- From 8161475c28760238b274e41f3433193edb137366 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 23:03:27 +0000 Subject: [PATCH 164/189] rlparser: update raylib_api.* by CI --- tools/rlparser/output/raylib_api.json | 4 ++-- tools/rlparser/output/raylib_api.lua | 4 ++-- tools/rlparser/output/raylib_api.txt | 4 ++-- tools/rlparser/output/raylib_api.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index c0bc88681..e5815854c 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -11897,7 +11897,7 @@ }, { "name": "SetSoundPan", - "description": "Set pan for a sound (0.5 is center)", + "description": "Set pan for a sound (-1.0 left, 0.0 center, 1.0 right)", "returnType": "void", "params": [ { @@ -12150,7 +12150,7 @@ }, { "name": "SetMusicPan", - "description": "Set pan for a music (0.5 is center)", + "description": "Set pan for a music (-1.0 left, 0.0 center, 1.0 right)", "returnType": "void", "params": [ { diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index 5cb3c1d55..eb3e6567b 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -8105,7 +8105,7 @@ return { }, { name = "SetSoundPan", - description = "Set pan for a sound (0.5 is center)", + description = "Set pan for a sound (-1.0 left, 0.0 center, 1.0 right)", returnType = "void", params = { {type = "Sound", name = "sound"}, @@ -8268,7 +8268,7 @@ return { }, { name = "SetMusicPan", - description = "Set pan for a music (0.5 is center)", + description = "Set pan for a music (-1.0 left, 0.0 center, 1.0 right)", returnType = "void", params = { {type = "Music", name = "music"}, diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index 9be8e517c..76d223d97 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -4554,7 +4554,7 @@ Function 556: SetSoundPitch() (2 input parameters) Function 557: SetSoundPan() (2 input parameters) Name: SetSoundPan Return type: void - Description: Set pan for a sound (0.5 is center) + 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) @@ -4660,7 +4660,7 @@ Function 575: SetMusicPitch() (2 input parameters) Function 576: SetMusicPan() (2 input parameters) Name: SetMusicPan Return type: void - Description: Set pan for a music (0.5 is center) + 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) diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index 96dbdbf64..512c4c6df 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -3043,7 +3043,7 @@ - + @@ -3111,7 +3111,7 @@ - + From c0179288baa4b662fed182e5e0532d02a7d12790 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 00:59:28 +0100 Subject: [PATCH 165/189] REXM: TEST: Support testing running on `PLATFORM_DRM` --- tools/rexm/rexm.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 6aba90f6f..19f52d3aa 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -931,23 +931,28 @@ int main(int argc, char *argv[]) #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); +#elif defined(PLATFORM_DRM) + LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName); + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", + exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); #endif +#if !defined(PLATFORM_DRM) // Build example for PLATFORM_WEB // Build: raylib.com/examples//_example_name.html // Build: raylib.com/examples//_example_name.data // Build: raylib.com/examples//_example_name.wasm // Build: raylib.com/examples//_example_name.js -#if defined(_WIN32) + #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); -#else + #else LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName)); -#endif + #endif // Update generated .html metadata LOG("INFO: [%s] Updating HTML Metadata...\n", TextFormat("%s.html", exName)); UpdateWebMetadata(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName), @@ -963,6 +968,7 @@ int main(int argc, char *argv[]) TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName)); FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName), TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName)); +#endif // !PLATFORM_DRM // Once example processed, free memory from list RL_FREE(exBuildList[i]); @@ -1618,6 +1624,10 @@ int main(int argc, char *argv[]) LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); + #elif defined(PLATFORM_DRM) + LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName); + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", + exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", @@ -1631,7 +1641,12 @@ int main(int argc, char *argv[]) // STEP 3: Run example with required arguments // NOTE: Not easy to retrieve process return value from system(), it's platform dependant ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); + + #if defined(_WIN32) + system(TextFormat("%s --frames 2 > logs/%s.log", exName, exName)); + #else system(TextFormat("./%s --frames 2 > logs/%s.log", exName, exName)); + #endif #endif } } break; @@ -1715,6 +1730,11 @@ int main(int argc, char *argv[]) { #if defined(BUILD_TESTING_WEB) if (TextFindIndex(exTestLogLines[k], "WARNING: GL: NPOT") >= 0) continue; // Ignore web-specific warning +#endif +#if defined(PLATFORM_DRM) + if (TextFindIndex(exTestLogLines[k], "WARNING: DISPLAY: No graphic") >= 0) continue; // Ignore specific warning + if (TextFindIndex(exTestLogLines[k], "WARNING: GetCurrentMonitor()") >= 0) continue; // Ignore specific warning + if (TextFindIndex(exTestLogLines[k], "WARNING: SetWindowPosition()") >= 0) continue; // Ignore specific warning #endif if (TextFindIndex(exTestLogLines[k], "WARNING") >= 0) testing[i].warnings++; } @@ -1758,7 +1778,7 @@ int main(int argc, char *argv[]) |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| | core_basic window | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | */ - LOG("INFO: [examples_testing.md] Generating examples testing report...\n"); + LOG("INFO: [examples_testing_os.md] Generating examples testing report...\n"); char *report = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); From c6f4c8e3e02cf18e79edb32d5541a66a50fc372c Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 00:59:43 +0100 Subject: [PATCH 166/189] FIX: Issue on PLATFORM_DRM --- examples/shaders/resources/shaders/glsl100/raymarching.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/shaders/resources/shaders/glsl100/raymarching.fs b/examples/shaders/resources/shaders/glsl100/raymarching.fs index ce9a2faca..58cd41059 100644 --- a/examples/shaders/resources/shaders/glsl100/raymarching.fs +++ b/examples/shaders/resources/shaders/glsl100/raymarching.fs @@ -1,9 +1,9 @@ #version 100 -precision mediump float; - #extension GL_OES_standard_derivatives : enable +precision mediump float; + // Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; varying vec4 fragColor; From 0747e9b5c14eb414932839283b7c463f35f44243 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 01:00:02 +0100 Subject: [PATCH 167/189] Create examples_testing_drm.md --- tools/rexm/reports/examples_testing_drm.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tools/rexm/reports/examples_testing_drm.md diff --git a/tools/rexm/reports/examples_testing_drm.md b/tools/rexm/reports/examples_testing_drm.md new file mode 100644 index 000000000..dba721a10 --- /dev/null +++ b/tools/rexm/reports/examples_testing_drm.md @@ -0,0 +1,21 @@ +# EXAMPLES COLLECTION - TESTING REPORT + +## Tested Platform: DRM + +``` +Example automated testing elements validated: + - [CWARN] : Compilation WARNING messages + - [LWARN] : Log WARNING messages count + - [INIT] : Initialization + - [CLOSE] : Closing + - [ASSETS] : Assets loading + - [RLGL] : OpenGL-wrapped initialization + - [PLAT] : Platform initialization + - [FONT] : Font default initialization + - [TIMER] : Timer initialization +``` +| **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | +|:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | From 90af210712e430e4bb411eb0139fdda417838ecb Mon Sep 17 00:00:00 2001 From: Jeffery Myers Date: Wed, 19 Nov 2025 23:00:23 -0800 Subject: [PATCH 168/189] include malloc.h so the win32 platform can build in MSVC (#5365) --- src/platforms/rcore_desktop_win32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index f832f410b..37f3fbac4 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -72,6 +72,8 @@ #include #include +#include // Required for alloca() + #if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE) #include #endif From 4ad9e09bb2d9a4b7667fcafc9f52d7c32582af9b Mon Sep 17 00:00:00 2001 From: Mae Brooks <138945353+MaeBrooks@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:10:47 -0800 Subject: [PATCH 169/189] Ran rexm testing for macos (#5366) --- tools/rexm/reports/examples_testing_macos.md | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tools/rexm/reports/examples_testing_macos.md diff --git a/tools/rexm/reports/examples_testing_macos.md b/tools/rexm/reports/examples_testing_macos.md new file mode 100644 index 000000000..1fa686ee6 --- /dev/null +++ b/tools/rexm/reports/examples_testing_macos.md @@ -0,0 +1,24 @@ +# EXAMPLES COLLECTION - TESTING REPORT + +## Tested Platform: macOS + +``` +Example automated testing elements validated: + - [CWARN] : Compilation WARNING messages + - [LWARN] : Log WARNING messages count + - [INIT] : Initialization + - [CLOSE] : Closing + - [ASSETS] : Assets loading + - [RLGL] : OpenGL-wrapped initialization + - [PLAT] : Platform initialization + - [FONT] : Font default initialization + - [TIMER] : Timer initialization +``` +| **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | +|:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| +| text_font_loading | 0 | 10 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_codepoints_loading | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| models_animation_playing | 0 | 1 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | +| shaders_palette_switch | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| shaders_hybrid_rendering | 0 | 4 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | + From 6820ff61f1c9f3f9d0dbf04163f2e7486742d905 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 20 Nov 2025 21:33:43 +0100 Subject: [PATCH 170/189] REVIEWED: example: `shaders_hybrid_rendering`, shaders issues --- .../shaders/glsl100/hybrid_raster.fs | 3 +- .../shaders/glsl100/hybrid_raymarch.fs | 13 ++- .../shaders/glsl330/hybrid_raster.fs | 6 +- .../shaders/glsl330/hybrid_raymarch.fs | 91 ++++++++++--------- examples/shaders/shaders_hybrid_rendering.c | 3 +- 5 files changed, 64 insertions(+), 52 deletions(-) diff --git a/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs b/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs index 35bc75d30..9658b3819 100644 --- a/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs +++ b/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs @@ -1,6 +1,7 @@ #version 100 -#extension GL_EXT_frag_depth : enable // Extension required for writing depth +#extension GL_EXT_frag_depth : enable // Extension required for writing depth + precision mediump float; // Precision required for OpenGL ES2 (WebGL) varying vec2 fragTexCoord; diff --git a/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs index 44233b3bb..8f9fa0907 100644 --- a/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs +++ b/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs @@ -2,6 +2,9 @@ #extension GL_EXT_frag_depth : enable //Extension required for writing depth #extension GL_OES_standard_derivatives : enable //Extension used for fwidth() + +#define ZERO 0 + precision mediump float; // Precision required for OpenGL ES2 (WebGL) // Input vertex attributes (from vertex shader) @@ -17,8 +20,6 @@ uniform vec3 camPos; uniform vec3 camDir; uniform vec2 screenCenter; -#define ZERO 0 - // SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing float CalcDepth(in vec3 rd, in float Idist) { @@ -128,7 +129,7 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax) float res = 1.0; float t = mint; - for (int i=ZERO; i<24; i++) + for (int i = ZERO; i < 24; i++) { float h = map(ro + rd*t).x; float s = clamp(8.0*h/t,0.0,1.0); @@ -156,7 +157,7 @@ float calcAO(in vec3 pos, in vec3 nor) { float occ = 0.0; float sca = 1.0; - for (int i=ZERO; i<5; i++) + for (int i = ZERO; i < 5; i++) { float h = 0.01 + 0.12*float(i)/4.0; float d = map(pos + h*nor).x; @@ -257,7 +258,8 @@ vec4 render(in vec3 ro, in vec3 rd) return vec4(vec3(clamp(col,0.0,1.0)),t); } -vec3 CalcRayDir(vec2 nCoord){ +vec3 CalcRayDir(vec2 nCoord) +{ vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0))); vec3 vertical = normalize(cross(horizontal,camDir)); return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y); @@ -287,6 +289,7 @@ void main() color = res.xyz; depth = CalcDepth(rd,res.w); } + gl_FragColor = vec4(color , 1.0); gl_FragDepthEXT = depth; } \ No newline at end of file diff --git a/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs b/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs index 12409d137..0b94dbdef 100644 --- a/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs +++ b/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs @@ -9,7 +9,7 @@ uniform sampler2D texture0; uniform vec4 colDiffuse; // Output fragment color -//out vec4 finalColor; +out vec4 finalColor; // NOTE: Add your custom variables here @@ -17,6 +17,6 @@ void main() { vec4 texelColor = texture(texture0, fragTexCoord); - gl_FragColor = texelColor*colDiffuse*fragColor; - gl_FragDepth = gl_FragCoord.z; + finalColor = texelColor*colDiffuse*fragColor; + gl_FragDepth = finalColor.z; } \ No newline at end of file diff --git a/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs index 2edb625ad..f1fafc640 100644 --- a/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs +++ b/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs @@ -1,5 +1,7 @@ # version 330 +#define ZERO 0 + // Input vertex attributes (from vertex shader) in vec2 fragTexCoord; in vec4 fragColor; @@ -13,10 +15,12 @@ uniform vec3 camPos; uniform vec3 camDir; uniform vec2 screenCenter; -#define ZERO 0 +// Output fragment color +out vec4 finalColor; // https://learnopengl.com/Advanced-OpenGL/Depth-testing -float CalcDepth(in vec3 rd, in float Idist){ +float CalcDepth(in vec3 rd, in float Idist) +{ float local_z = dot(normalize(camDir),rd)*Idist; return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01); } @@ -26,15 +30,13 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w) { p.x = abs(p.x); float l = length(p.xy); - p.xy = mat2(-c.x, c.y, - c.y, c.x)*p.xy; - p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), - (p.x>0.0)?p.y:l); - p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); + p.xy = mat2(-c.x, c.y, c.y, c.x)*p.xy; + p.xy = vec2(((p.y > 0.0) || (p.x > 0.0))? p.x : l*sign(-c.x), (p.x>0.0)? p.y : l); + p.xy = vec2(p.x, abs(p.y - r)) - vec2(le, 0.0); - vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); + vec2 q = vec2(length(max(p.xy, 0.0)) + min(0.0, max(p.x, p.y)), p.z); vec2 d = abs(q) - w; - return min(max(d.x,d.y),0.0) + length(max(d,0.0)); + return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)); } // r = sphere's radius @@ -44,17 +46,16 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t) { // Six way symetry Transformation vec3 ap = abs(p); - if (ap.x < max(ap.y, ap.z)){ + if (ap.x < max(ap.y, ap.z)) + { if (ap.y < ap.z) ap.xz = ap.zx; else ap.xy = ap.yx; } vec2 q = vec2(length(ap.yz), ap.x); - float w = sqrt(r*r-h*h); - return ((h*q.x0.0) + if (tp1 > 0.0) { tmax = min(tmax, tp1); res = vec2(tp1, 1.0); } float t = tmin; - for (int i=0; i<70 ; i++) + for (int i = 0; i < 70 ; i++) { - if (t>tmax) break; - vec2 h = map(ro+rd*t); - if (abs(h.x)<(0.0001*t)) + if (t > tmax) break; + vec2 h = map(ro + rd*t); + if (abs(h.x )< (0.0001*t)) { - res = vec2(t,h.y); + res = vec2(t, h.y); break; } t += h.x; @@ -111,28 +115,28 @@ vec2 raycast(in vec3 ro, in vec3 rd){ return res; } - // https://iquilezles.org/articles/rmshadows float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax) { // bounding volume - float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp); + float tp = (0.8 - ro.y)/rd.y; if (tp > 0.0) tmax = min(tmax, tp); float res = 1.0; float t = mint; - for (int i=ZERO; i<24; i++) + for (int i = ZERO; i < 24; i++) { float h = map(ro + rd*t).x; - float s = clamp(8.0*h/t,0.0,1.0); + float s = clamp(8.0*h/t, 0.0, 1.0); res = min(res, s); t += clamp(h, 0.01, 0.2); - if (res<0.004 || t>tmax) break; + if ((res < 0.004) || (t > tmax)) break; } + res = clamp(res, 0.0, 1.0); + return res*res*(3.0-2.0*res); } - // https://iquilezles.org/articles/normalsSDF vec3 calcNormal(in vec3 pos) { @@ -148,7 +152,7 @@ float calcAO(in vec3 pos, in vec3 nor) { float occ = 0.0; float sca = 1.0; - for (int i=ZERO; i<5; i++) + for (int i = ZERO; i < 5; i++) { float h = 0.01 + 0.12*float(i)/4.0; float d = map(pos + h*nor).x; @@ -156,6 +160,7 @@ float calcAO(in vec3 pos, in vec3 nor) sca *= 0.95; if (occ>0.35) break; } + return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y); } @@ -165,9 +170,9 @@ float checkersGradBox(in vec2 p) // filter kernel vec2 w = fwidth(p) + 0.001; // analytical integral (box filter) - vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w; + vec2 i = 2.0*(abs(fract((p - 0.5*w)*0.5)-0.5) - abs(fract((p + 0.5*w)*0.5) - 0.5))/w; // xor pattern - return 0.5 - 0.5*i.x*i.y; + return (0.5 - 0.5*i.x*i.y); } // https://www.shadertoy.com/view/tdS3DG @@ -180,7 +185,7 @@ vec4 render(in vec3 ro, in vec3 rd) vec2 res = raycast(ro,rd); float t = res.x; float m = res.y; - if (m>-0.5) + if (m > -0.5) { vec3 pos = ro + t*rd; vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos); @@ -190,7 +195,7 @@ vec4 render(in vec3 ro, in vec3 rd) col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0)); float ks = 1.0; - if (m<1.5) + if (m < 1.5) { float f = checkersGradBox(3.0*pos.xz); col = 0.15 + f*vec3(0.05); @@ -207,14 +212,14 @@ vec4 render(in vec3 ro, in vec3 rd) vec3 lig = normalize(vec3(-0.5, 0.4, -0.6)); vec3 hal = normalize(lig-rd); float dif = clamp(dot(nor, lig), 0.0, 1.0); - //if (dif>0.0001) + //if (dif>0.0001) dif *= calcSoftshadow(pos, lig, 0.02, 2.5); float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0); spe *= dif; spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); //spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0); lin += col*2.20*dif*vec3(1.30,1.00,0.70); - lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; + lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; } // sky { @@ -249,7 +254,8 @@ vec4 render(in vec3 ro, in vec3 rd) return vec4(vec3(clamp(col,0.0,1.0)),t); } -vec3 CalcRayDir(vec2 nCoord){ +vec3 CalcRayDir(vec2 nCoord) +{ vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0))); vec3 vertical = normalize(cross(horizontal,camDir)); return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y); @@ -279,6 +285,7 @@ void main() color = res.xyz; depth = CalcDepth(rd,res.w); } - gl_FragColor = vec4(color , 1.0); + + finalColor = vec4(color , 1.0); gl_FragDepth = depth; } \ No newline at end of file diff --git a/examples/shaders/shaders_hybrid_rendering.c b/examples/shaders/shaders_hybrid_rendering.c index ec6b8b0a6..e523a91c8 100644 --- a/examples/shaders/shaders_hybrid_rendering.c +++ b/examples/shaders/shaders_hybrid_rendering.c @@ -118,7 +118,7 @@ int main(void) // Raymarch Scene rlEnableDepthTest(); // Manually enable Depth Test to handle multiple rendering methods BeginShaderMode(shdrRaymarch); - DrawRectangleRec((Rectangle){0,0, (float)screenWidth, (float)screenHeight},WHITE); + DrawRectangleRec((Rectangle){ 0,0, (float)screenWidth, (float)screenHeight },WHITE); EndShaderMode(); // Rasterize Scene @@ -138,6 +138,7 @@ int main(void) ClearBackground(RAYWHITE); DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE); + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- From dddc94dc7a763d165a43c47c6ce1ce3c59f0652f Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Nov 2025 20:14:29 +0100 Subject: [PATCH 171/189] Update examples_testing_web.md --- tools/rexm/reports/examples_testing_web.md | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/rexm/reports/examples_testing_web.md b/tools/rexm/reports/examples_testing_web.md index 1704b5986..1f6ed58b3 100644 --- a/tools/rexm/reports/examples_testing_web.md +++ b/tools/rexm/reports/examples_testing_web.md @@ -17,7 +17,6 @@ Example automated testing elements validated: | **EXAMPLE NAME** | [CWARN] | [LWARN] | [INIT] | [CLOSE] | [ASSETS] | [RLGL] | [PLAT] | [FONT] | [TIMER] | |:---------------------------------|:-------:|:-------:|:------:|:-------:|:--------:|:------:|:------:|:------:|:-------:| | core_monitor_detector | 0 | 1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| textures_screen_buffer | 0 | 0 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | textures_sprite_stacking | 0 | 0 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_sprite_fonts | 0 | 0 | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | | text_font_loading | 0 | 3 | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | From 12cce1766fed3c4fd555a636f15b63eeff897aab Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Nov 2025 20:14:41 +0100 Subject: [PATCH 172/189] Update textures_screen_buffer.c --- examples/textures/textures_screen_buffer.c | 107 +++++++++------------ 1 file changed, 48 insertions(+), 59 deletions(-) diff --git a/examples/textures/textures_screen_buffer.c b/examples/textures/textures_screen_buffer.c index 98c9a2ad5..e620aab31 100644 --- a/examples/textures/textures_screen_buffer.c +++ b/examples/textures/textures_screen_buffer.c @@ -17,16 +17,10 @@ #include "raylib.h" -#define MAX_COLORS 256 -#define SCREEN_WIDTH 800 -#define SCREEN_HEIGHT 450 -#define SCALE_FACTOR 2 -// buffer size at least for screenImage pixel count -#define INDEX_BUFFER_SIZE ((SCREEN_WIDTH * SCREEN_HEIGHT) / SCALE_FACTOR) -#define FLAME_WIDTH (SCREEN_WIDTH / SCALE_FACTOR) +#include // Required for: calloc(), free() -static void GeneretePalette(Color *palette); -static void ClearIndexBuffer(unsigned char *buffer, int count); +#define MAX_COLORS 256 +#define SCALE_FACTOR 2 //------------------------------------------------------------------------------------ // Program main entry point @@ -35,22 +29,31 @@ int main(void) { // Initialization //-------------------------------------------------------------------------------------- - const int screenWidth = SCREEN_WIDTH; - const int screenHeight = SCREEN_HEIGHT; - const int pixelScale = SCALE_FACTOR; - const int imageWidth = screenWidth / pixelScale; - const int imageHeight = screenHeight / pixelScale; + const int screenWidth = 800; + const int screenHeight = 450; + InitWindow(screenWidth, screenHeight, "raylib [textures] example - screen buffer"); - Color palette[MAX_COLORS] = {0}; - unsigned char indexBuffer[INDEX_BUFFER_SIZE] = {0}; - unsigned char flameRootBuffer[FLAME_WIDTH] = {0}; + int imageWidth = screenWidth/SCALE_FACTOR; + int imageHeight = screenHeight/SCALE_FACTOR; + int flameWidth = screenWidth/SCALE_FACTOR; + + Color palette[MAX_COLORS] = { 0 }; + unsigned char *indexBuffer = RL_CALLOC(imageWidth*imageWidth, sizeof(unsigned char)); + unsigned char *flameRootBuffer = RL_CALLOC(flameWidth, sizeof(unsigned char)); Image screenImage = GenImageColor(imageWidth, imageHeight, BLACK); Texture screenTexture = LoadTextureFromImage(screenImage); - GeneretePalette(palette); - ClearIndexBuffer(indexBuffer, INDEX_BUFFER_SIZE); - ClearIndexBuffer(flameRootBuffer, FLAME_WIDTH); + + // Generate flame color palette + for (int i = 0; i < MAX_COLORS; i++) + { + float t = (float)i/(float)(MAX_COLORS - 1); + float hue = t*t; + float saturation = t; + float value = t; + palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value); + } SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -58,8 +61,10 @@ int main(void) // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { + // Update + //---------------------------------------------------------------------------------- // Grow flameRoot - for (int x = 2; x < FLAME_WIDTH; ++x) + for (int x = 2; x < flameWidth; x++) { unsigned short flame = flameRootBuffer[x]; if (flame == 255) continue; @@ -68,26 +73,26 @@ int main(void) flameRootBuffer[x] = flame; } - // transfer flameRoot to indexBuffer - for (int x = 0; x < FLAME_WIDTH; ++x) + // Transfer flameRoot to indexBuffer + for (int x = 0; x < flameWidth; x++) { - int i = x + (imageHeight - 1) * imageWidth; + int i = x + (imageHeight - 1)*imageWidth; indexBuffer[i] = flameRootBuffer[x]; } // Clear top row, because it can't move any higher - for (int x = 0; x < imageWidth; ++x) + for (int x = 0; x < imageWidth; x++) { if (indexBuffer[x] == 0) continue; indexBuffer[x] = 0; } // Skip top row, it is already cleared - for (int y = 1; y < imageHeight; ++y) + for (int y = 1; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; ++x) + for (int x = 0; x < imageWidth; x++) { - unsigned i = x + y * imageWidth; + unsigned int i = x + y*imageWidth; unsigned char colorIndex = indexBuffer[i]; if (colorIndex == 0) continue; @@ -97,19 +102,19 @@ int main(void) int newX = x + moveX; if (newX < 0 || newX >= imageWidth) continue; - unsigned i_above = i - imageWidth + moveX; + unsigned int iabove = i - imageWidth + moveX; int decay = GetRandomValue(0, 3); - colorIndex -= (decay < colorIndex) ? decay : colorIndex; - indexBuffer[i_above] = colorIndex; + colorIndex -= (decay < colorIndex)? decay : colorIndex; + indexBuffer[iabove] = colorIndex; } } // Update screenImage with palette colors - for (int y = 1; y < imageHeight; ++y) + for (int y = 1; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; ++x) + for (int x = 0; x < imageWidth; x++) { - unsigned i = x + y * imageWidth; + unsigned int i = x + y*imageWidth; unsigned char colorIndex = indexBuffer[i]; Color col = palette[colorIndex]; ImageDrawPixel(&screenImage, x, y, col); @@ -117,19 +122,24 @@ int main(void) } UpdateTexture(screenTexture, screenImage.data); + //---------------------------------------------------------------------------------- + // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - const Vector2 origin = (Vector2){0, 0}; - const float rotation = 0.f; - DrawTextureEx(screenTexture, origin, rotation, pixelScale, WHITE); + + ClearBackground(RAYWHITE); + + DrawTextureEx(screenTexture, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE); + EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - + RL_FREE(indexBuffer); + RL_FREE(flameRootBuffer); UnloadTexture(screenTexture); UnloadImage(screenImage); @@ -138,24 +148,3 @@ int main(void) return 0; } - -static void GeneretePalette(Color *palette) -{ - for (int i = 0; i < MAX_COLORS; ++i) - { - float t = (float)i/(float)(MAX_COLORS - 1); - float hue = t * t; - float saturation = t; - float value = t; - palette[i] = ColorFromHSV(250.f + 150.f * hue, saturation, value); - } -} - -static void ClearIndexBuffer(unsigned char *buffer, int count) -{ - // Use memset to set to ZERO, but for demonstration a plain for loop is used - for (int i = 0; i < count; ++i) - { - buffer[i] = 0; - } -} \ No newline at end of file From 6c3ef8d9b4cef36e7358686065ce5d7106f555c2 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Nov 2025 20:15:50 +0100 Subject: [PATCH 173/189] Remove trailing spaces --- src/raudio.c | 2 +- src/rtextures.c | 4 ++-- tools/rexm/rexm.c | 22 +++++++++++----------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 66e04fad6..1d9edca0a 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -593,7 +593,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam // Init audio buffer values audioBuffer->volume = 1.0f; audioBuffer->pitch = 1.0f; - audioBuffer->pan = 0.0f; // Center + audioBuffer->pan = 0.0f; // Center audioBuffer->callback = NULL; audioBuffer->processor = NULL; diff --git a/src/rtextures.c b/src/rtextures.c index 00554e418..299ab6793 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3343,7 +3343,7 @@ void ImageClearBackground(Image *dst, Color color) int bytesPerPixel = GetPixelDataSize(1, 1, dst->format); int totalPixels = dst->width * dst->height; - // Repeat the first pixel data throughout the image, + // Repeat the first pixel data throughout the image, // doubling the pixels copied on each iteration for (int i = 1; i < totalPixels; i *= 2) { @@ -3727,7 +3727,7 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) unsigned char *pSrcPixel = (unsigned char *)dst->data + bytesOffset; // Repeat the first pixel data throughout the row - for (int x = 1; x < (int)rec.width; x *= 2) + for (int x = 1; x < (int)rec.width; x *= 2) { int pixelsToCopy = MIN(x, (int)rec.width - x); memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, pixelsToCopy * bytesPerPixel); diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 19f52d3aa..72b962874 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -418,7 +418,7 @@ int main(int argc, char *argv[]) // Support building/testing not only individual examples but multiple: ALL/ int exBuildListInfoCount = 0; rlExampleInfo *exBuildListInfo = LoadExampleData(argv[2], false, &exBuildListInfoCount); - + for (int i = 0; i < exBuildListInfoCount; i++) { if (!TextIsEqual(exBuildListInfo[i].category, "others")) @@ -428,9 +428,9 @@ int main(int argc, char *argv[]) exBuildListCount++; } } - + UnloadExampleData(exBuildListInfo); - + if (exBuildListCount == 0) LOG("WARNING: BUILD: Example requested not available in the collection\n"); else { @@ -933,7 +933,7 @@ int main(int argc, char *argv[]) system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName)); #elif defined(PLATFORM_DRM) LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName); - system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); @@ -1495,7 +1495,7 @@ int main(int argc, char *argv[]) strncpy(exCategory, exName, TextFindIndex(exName, "_")); // Skip some examples from building - if ((strcmp(exName, "core_custom_logging") == 0) || + if ((strcmp(exName, "core_custom_logging") == 0) || (strcmp(exName, "core_window_should_close") == 0) || (strcmp(exName, "core_custom_frame_control") == 0)) continue; @@ -1512,7 +1512,7 @@ int main(int argc, char *argv[]) // STEP 3: Run example with arguments: --frames 2 > .out.log // STEP 4: Load .out.log and check "WARNING:" messages -> Some could maybe be ignored // STEP 5: Generate report with results - + // STEP 1: Load example and inject required code // PROBLEM: As we need to modify the example source code for building, we need to keep a copy or something // WARNING: If we make a copy and something fails, it could not be restored at the end @@ -1572,7 +1572,7 @@ int main(int argc, char *argv[]) // Build: raylib.com/examples//_example_name.js #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1", + system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_WEB (Host: POSIX)\n", exName); @@ -1622,15 +1622,15 @@ int main(int argc, char *argv[]) // Build example for PLATFORM_DESKTOP #if defined(_WIN32) LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: Win32)\n", exName); - system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", + system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #elif defined(PLATFORM_DRM) LOG("INFO: [%s] Building example for PLATFORM_DRM (Host: POSIX)\n", exName); - system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DRM -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #else LOG("INFO: [%s] Building example for PLATFORM_DESKTOP (Host: POSIX)\n", exName); - system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", + system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B > %s/%s/logs/%s.build.log 2>&1", exBasePath, exCategory, exName, exBasePath, exCategory, exName)); #endif // Restore original source code before continue @@ -1814,7 +1814,7 @@ int main(int argc, char *argv[]) if ((testing[i].buildwarns > 0) || (testing[i].warnings > 0) || (testing[i].status > 0)) { repIndex += sprintf(report + repIndex, "| %-32s | %i | %i | %s | %s | %s | %s | %s | %s | %s |\n", - exBuildList[i], + exBuildList[i], testing[i].buildwarns, testing[i].warnings, (testing[i].status & TESTING_FAIL_INIT)? "❌" : "✔", From 727a90c5d15f82016774b6ccc3a7384edda67f8e Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Nov 2025 20:16:33 +0100 Subject: [PATCH 174/189] REVIEWED: Formatting to follow raylib conventions --- .../audio/audio_fft_spectrum_visualizer.c | 13 +- examples/audio/audio_music_stream.c | 20 +- examples/audio/audio_raw_stream.c | 2 +- examples/audio/audio_sound_positioning.c | 2 +- examples/core/core_highdpi_testbed.c | 12 +- examples/core/core_input_gestures_testbed.c | 2 +- examples/core/core_input_multitouch.c | 4 +- examples/core/core_monitor_detector.c | 2 +- examples/core/core_undo_redo.c | 4 +- examples/core/core_viewport_scaling.c | 266 ++++++++---------- examples/core/core_window_flags.c | 3 +- examples/models/models_loading_vox.c | 2 +- examples/shaders/shaders_basic_pbr.c | 6 +- examples/shaders/shaders_color_correction.c | 2 +- examples/shaders/shaders_hybrid_rendering.c | 2 +- examples/shapes/shapes_bullet_hell.c | 2 +- examples/shapes/shapes_clock_of_clocks.c | 101 +++---- examples/shapes/shapes_double_pendulum.c | 2 +- examples/shapes/shapes_math_angle_rotation.c | 18 +- examples/shapes/shapes_math_sine_cosine.c | 17 +- examples/shapes/shapes_mouse_trail.c | 2 +- examples/shapes/shapes_rectangle_advanced.c | 2 +- examples/shapes/shapes_recursive_tree.c | 2 +- examples/shapes/shapes_rlgl_color_wheel.c | 16 +- examples/shapes/shapes_simple_particles.c | 2 +- examples/shapes/shapes_triangle_strip.c | 4 +- examples/text/text_3d_drawing.c | 4 +- examples/text/text_inline_styling.c | 2 +- examples/text/text_unicode_emojis.c | 4 +- examples/text/text_words_alignment.c | 25 +- examples/textures/textures_mouse_painting.c | 2 +- examples/textures/textures_sprite_stacking.c | 2 +- examples/textures/textures_tiled_drawing.c | 2 +- 33 files changed, 248 insertions(+), 303 deletions(-) diff --git a/examples/audio/audio_fft_spectrum_visualizer.c b/examples/audio/audio_fft_spectrum_visualizer.c index 5993186ab..cad683462 100644 --- a/examples/audio/audio_fft_spectrum_visualizer.c +++ b/examples/audio/audio_fft_spectrum_visualizer.c @@ -148,7 +148,7 @@ int main(void) CaptureFrame(&fft, audioSamples); RenderFrame(&fft, &fftImage); UpdateTexture(fftTexture, fftImage.data); - //------------------------------------------------------------------------------ + //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- @@ -269,7 +269,7 @@ static void CaptureFrame(FFTData *fftData, const float *audioSamples) fftData->lastFftTime = GetTime(); memcpy(fftData->fftHistory[fftData->historyPos], smoothedSpectrum, sizeof(smoothedSpectrum)); - fftData->historyPos = (fftData->historyPos + 1) % fftData->fftHistoryLen; + fftData->historyPos = (fftData->historyPos + 1)%fftData->fftHistoryLen; } static void RenderFrame(const FFTData *fftData, Image *fftImage) @@ -277,12 +277,9 @@ static void RenderFrame(const FFTData *fftData, Image *fftImage) double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME); framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1); - int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback) % fftData->fftHistoryLen; - if (historyPosition < 0) - historyPosition += fftData->fftHistoryLen; + int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen; + if (historyPosition < 0) historyPosition += fftData->fftHistoryLen; const float *amplitude = fftData->fftHistory[historyPosition]; - for (int bin = 0; bin < BUFFER_SIZE; bin++) { - ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL })); - } + for (int bin = 0; bin < BUFFER_SIZE; bin++) ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL })); } \ No newline at end of file diff --git a/examples/audio/audio_music_stream.c b/examples/audio/audio_music_stream.c index 4533ff30b..05ec1c2d6 100644 --- a/examples/audio/audio_music_stream.c +++ b/examples/audio/audio_music_stream.c @@ -35,10 +35,10 @@ int main(void) float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f] bool pause = false; // Music playing paused - + float pan = 0.0f; // Default audio pan center [-1.0f..1.0f] SetMusicPan(music, pan); - + float volume = 0.8f; // Default audio volume [0.0f..1.0f] SetMusicVolume(music, volume); @@ -67,29 +67,29 @@ int main(void) if (pause) PauseMusicStream(music); else ResumeMusicStream(music); } - + // Set audio pan - if (IsKeyDown(KEY_LEFT)) + if (IsKeyDown(KEY_LEFT)) { pan -= 0.05f; if (pan < -1.0f) pan = -1.0f; SetMusicPan(music, pan); } - else if (IsKeyDown(KEY_RIGHT)) + else if (IsKeyDown(KEY_RIGHT)) { pan += 0.05f; if (pan > 1.0f) pan = 1.0f; SetMusicPan(music, pan); } - + // Set audio volume - if (IsKeyDown(KEY_DOWN)) + if (IsKeyDown(KEY_DOWN)) { volume -= 0.05f; if (volume < 0.0f) volume = 0.0f; SetMusicVolume(music, volume); } - else if (IsKeyDown(KEY_UP)) + else if (IsKeyDown(KEY_UP)) { volume += 0.05f; if (volume > 1.0f) volume = 1.0f; @@ -109,7 +109,7 @@ int main(void) ClearBackground(RAYWHITE); DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY); - + DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE); DrawRectangle(300, 100, 200, 12, LIGHTGRAY); DrawRectangleLines(300, 100, 200, 12, GRAY); @@ -121,7 +121,7 @@ int main(void) DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY); DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY); - + DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN); DrawRectangle(300, 360, 200, 12, LIGHTGRAY); DrawRectangleLines(300, 360, 200, 12, GRAY); diff --git a/examples/audio/audio_raw_stream.c b/examples/audio/audio_raw_stream.c index 4deae2090..b327e92af 100644 --- a/examples/audio/audio_raw_stream.c +++ b/examples/audio/audio_raw_stream.c @@ -166,7 +166,7 @@ int main(void) memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short)); // Update cursors and loop audio - readCursor = (readCursor + writeLength) % waveLength; + readCursor = (readCursor + writeLength)%waveLength; writeCursor += writeLength; } diff --git a/examples/audio/audio_sound_positioning.c b/examples/audio/audio_sound_positioning.c index 9159acf08..34b15c07b 100644 --- a/examples/audio/audio_sound_positioning.c +++ b/examples/audio/audio_sound_positioning.c @@ -95,7 +95,7 @@ int main(void) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- - + return 0; } diff --git a/examples/core/core_highdpi_testbed.c b/examples/core/core_highdpi_testbed.c index 5cd2a7dc7..a341d081c 100644 --- a/examples/core/core_highdpi_testbed.c +++ b/examples/core/core_highdpi_testbed.c @@ -27,9 +27,10 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; + SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE); InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed"); - // TODO: Load resources / Initialize variables at this point + int gridSpacing = 40; // Grid spacing in pixels SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -48,11 +49,12 @@ int main(void) ClearBackground(RAYWHITE); - // TODO: Draw everything that requires to be drawn at this point + // Draw grid + for (int h = 0; h < 20; h++) DrawLine(0, h*gridSpacing, GetRenderWidth(), h*gridSpacing, LIGHTGRAY); + for (int v = 0; v < 40; v++) DrawLine(v*gridSpacing, 0, v*gridSpacing, GetScreenHeight(), LIGHTGRAY); - DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED); - DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED); - DrawText("example base code template", 260, 400, 20, LIGHTGRAY); + // Draw UI info + DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 10, 10, 20, BLACK); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/core/core_input_gestures_testbed.c b/examples/core/core_input_gestures_testbed.c index f318ab4a4..e0ffeb13f 100644 --- a/examples/core/core_input_gestures_testbed.c +++ b/examples/core/core_input_gestures_testbed.c @@ -202,7 +202,7 @@ int main(void) DrawText("Log", (int)gestureLogPosition.x, (int)gestureLogPosition.y, 20, BLACK); // Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle) - for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], (int)gestureLogPosition.x, (int)gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY)); + for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1)%GESTURE_LOG_SIZE) DrawText(gestureLog[ii], (int)gestureLogPosition.x, (int)gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY)); Color logButton1Color, logButton2Color; switch (logMode) { diff --git a/examples/core/core_input_multitouch.c b/examples/core/core_input_multitouch.c index 01dd90fae..47ad91d66 100644 --- a/examples/core/core_input_multitouch.c +++ b/examples/core/core_input_multitouch.c @@ -46,7 +46,7 @@ int main(void) // Clamp touch points available ( set the maximum touch points allowed ) if (tCount > MAX_TOUCH_POINTS) tCount = MAX_TOUCH_POINTS; // Get touch points positions - for (int i = 0; i < tCount; ++i) touchPositions[i] = GetTouchPosition(i); + for (int i = 0; i < tCount; i++) touchPositions[i] = GetTouchPosition(i); //---------------------------------------------------------------------------------- // Draw @@ -55,7 +55,7 @@ int main(void) ClearBackground(RAYWHITE); - for (int i = 0; i < tCount; ++i) + for (int i = 0; i < tCount; i++) { // Make sure point is not (0, 0) as this means there is no touch for it if ((touchPositions[i].x > 0) && (touchPositions[i].y > 0)) diff --git a/examples/core/core_monitor_detector.c b/examples/core/core_monitor_detector.c index 720449d65..ab65d8042 100644 --- a/examples/core/core_monitor_detector.c +++ b/examples/core/core_monitor_detector.c @@ -142,7 +142,7 @@ int main(void) Vector2 windowPosition = (Vector2){ (GetWindowPosition().x + monitorOffsetX)*monitorScale + 140, GetWindowPosition().y*monitorScale + 80 }; // Draw window position based on monitors - DrawRectangleV(windowPosition, (Vector2){screenWidth * monitorScale, screenHeight * monitorScale}, Fade(GREEN, 0.5)); + DrawRectangleV(windowPosition, (Vector2){screenWidth*monitorScale, screenHeight*monitorScale}, Fade(GREEN, 0.5)); } else DrawRectangleLinesEx(rec, 5, GRAY); } diff --git a/examples/core/core_undo_redo.c b/examples/core/core_undo_redo.c index c49ad9e6f..78971e689 100644 --- a/examples/core/core_undo_redo.c +++ b/examples/core/core_undo_redo.c @@ -187,7 +187,7 @@ int main(void) if (lastUndoIndex > firstUndoIndex) { for (int i = firstUndoIndex; i < currentUndoIndex; i++) - DrawRectangleRec((Rectangle){gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE, + DrawRectangleRec((Rectangle){gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE, GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY); } else if (firstUndoIndex > lastUndoIndex) @@ -195,7 +195,7 @@ int main(void) if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex)) { for (int i = firstUndoIndex; i < currentUndoIndex; i++) - DrawRectangleRec((Rectangle) { gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE, + DrawRectangleRec((Rectangle) { gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE, GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY); } else diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index 28ee422cd..adcd51ea3 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -17,11 +17,9 @@ #include "raylib.h" -// For itteration purposes and teaching example -#define RESOLUTION_COUNT 4 +#define RESOLUTION_COUNT 4 // For iteration purposes and teaching example -enum ViewportType -{ +typedef enum { // Only upscale, useful for pixel art KEEP_ASPECT_INTEGER, KEEP_HEIGHT_INTEGER, @@ -32,24 +30,28 @@ enum ViewportType KEEP_WIDTH, // For itteration purposes and as a teaching example VIEWPORT_TYPE_COUNT, +} ViewportType; + +// For displaying on GUI +const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = { + "KEEP_ASPECT_INTEGER", + "KEEP_HEIGHT_INTEGER", + "KEEP_WIDTH_INTEGER", + "KEEP_ASPECT", + "KEEP_HEIGHT", + "KEEP_WIDTH", }; //-------------------------------------------------------------------------------------- // Module Functions Declaration //-------------------------------------------------------------------------------------- static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); - static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); - static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); - static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); - static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); - static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect); - -static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target); +static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target); // Example how to calculate position on RenderTexture static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect); @@ -61,91 +63,89 @@ int main(void) { // Initialization //--------------------------------------------------------- - // Preset resolutions that could be created by subdividing screen resolution - Vector2 resolutionList[RESOLUTION_COUNT] = { - (Vector2){64, 64}, - (Vector2){256, 240}, - (Vector2){320, 180}, - // 4K doesn't work with integer scaling but included for example purposes with non-integer scaling - (Vector2){3840, 2160}, - }; - int resolutionIndex = 0; - int screenWidth = 800; int screenHeight = 450; - int gameWidth = 64; - int gameHeight = 64; - - RenderTexture2D target = (RenderTexture2D){0}; - Rectangle sourceRect = (Rectangle){0}; - Rectangle destRect = (Rectangle){0}; - - // For displaying on GUI - const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = { - "KEEP_ASPECT_INTEGER", - "KEEP_HEIGHT_INTEGER", - "KEEP_WIDTH_INTEGER", - "KEEP_ASPECT", - "KEEP_HEIGHT", - "KEEP_WIDTH", - }; - enum ViewportType viewportType = KEEP_ASPECT_INTEGER; SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(screenWidth, screenHeight, "raylib [core] example - viewport scaling"); + + // Preset resolutions that could be created by subdividing screen resolution + Vector2 resolutionList[RESOLUTION_COUNT] = { + (Vector2){ 64, 64 }, + (Vector2){ 256, 240 }, + (Vector2){ 320, 180 }, + // 4K doesn't work with integer scaling but included for example purposes with non-integer scaling + (Vector2){ 3840, 2160 }, + }; + + int resolutionIndex = 0; + int gameWidth = 64; + int gameHeight = 64; + + RenderTexture2D target = (RenderTexture2D){ 0 }; + Rectangle sourceRect = (Rectangle){ 0 }; + Rectangle destRect = (Rectangle){ 0 }; + + ViewportType viewportType = KEEP_ASPECT_INTEGER; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + // Button rectangles + Rectangle decreaseResolutionButton = (Rectangle){ 200, 30, 10, 10 }; + Rectangle increaseResolutionButton = (Rectangle){ 215, 30, 10, 10 }; + Rectangle decreaseTypeButton = (Rectangle){ 200, 45, 10, 10 }; + Rectangle increaseTypeButton = (Rectangle){ 215, 45, 10, 10 }; + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //---------------------------------------------------------- - // Button rectangles - Rectangle decreaseResolutionButton = (Rectangle){200, 30, 10, 10}; - Rectangle increaseResolutionButton = (Rectangle){215, 30, 10, 10}; - Rectangle decreaseTypeButton = (Rectangle){200, 45, 10, 10}; - Rectangle increaseTypeButton = (Rectangle){215, 45, 10, 10}; // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update - //----------------------------------------------------- - if (IsWindowResized()){ - ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); - } + //---------------------------------------------------------------------------------- + if (IsWindowResized()) ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); + Vector2 mousePosition = GetMousePosition(); bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT); // Check buttons and rescale - if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed){ - resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1) % RESOLUTION_COUNT; + if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed) + { + resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT; gameWidth = resolutionList[resolutionIndex].x; gameHeight = resolutionList[resolutionIndex].y; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); } - if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed){ - resolutionIndex = (resolutionIndex + 1) % RESOLUTION_COUNT; + + if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed) + { + resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT; gameWidth = resolutionList[resolutionIndex].x; gameHeight = resolutionList[resolutionIndex].y; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); } - if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed){ - viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1) % VIEWPORT_TYPE_COUNT; + + if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed) + { + viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1)%VIEWPORT_TYPE_COUNT; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); } - if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed){ - viewportType = (viewportType + 1) % VIEWPORT_TYPE_COUNT; + + if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed) + { + viewportType = (viewportType + 1)%VIEWPORT_TYPE_COUNT; ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target); } Vector2 textureMousePosition = Screen2RenderTexturePosition(mousePosition, &sourceRect, &destRect); + //---------------------------------------------------------------------------------- // Draw - //----------------------------------------------------- + //---------------------------------------------------------------------------------- // Draw our scene to the render texture BeginTextureMode(target); ClearBackground(WHITE); - DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.f, LIME); - - + DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.0f, LIME); EndTextureMode(); // Draw render texture to main framebuffer @@ -153,9 +153,7 @@ int main(void) ClearBackground(BLACK); // Draw our render texture with rotation applied - const Vector2 ORIGIN_POSITION = (Vector2){ 0.0f, 0.0f }; - const float ROTATION = 0.f; - DrawTexturePro(target.texture, sourceRect, destRect, ORIGIN_POSITION, ROTATION, WHITE); + DrawTexturePro(target.texture, sourceRect, destRect, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE); // Draw Native resolution (GUI or anything) // Draw info box @@ -167,15 +165,10 @@ int main(void) DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK); DrawText(TextFormat("Type: %s", ViewportTypeNames[viewportType]), 15, 45, 10, BLACK); - Vector2 scaleRatio = (Vector2){destRect.width / sourceRect.width, destRect.height / -sourceRect.height}; - if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f) - { - DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK); - } - else - { - DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK); - } + Vector2 scaleRatio = (Vector2){destRect.width/sourceRect.width, -destRect.height/sourceRect.height}; + if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f) DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK); + else DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK); + DrawText(TextFormat("Source size: %.2f x %.2f", sourceRect.width, -sourceRect.height), 15, 75, 10, BLACK); DrawText(TextFormat("Destination size: %.2f x %.2f", destRect.width, destRect.height), 15, 90, 10, BLACK); @@ -190,13 +183,13 @@ int main(void) DrawText(">", increaseResolutionButton.x + 3, increaseResolutionButton.y + 1, 10, BLACK); EndDrawing(); - //----------------------------------------------------- + //---------------------------------------------------------------------------------- } // De-Initialization - //--------------------------------------------------------- + //---------------------------------------------------------------------------------- CloseWindow(); // Close window and OpenGL context - //---------------------------------------------------------- + //---------------------------------------------------------------------------------- return 0; } @@ -206,54 +199,54 @@ int main(void) //-------------------------------------------------------------------------------------- static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { - sourceRect->x = 0.f; + sourceRect->x = 0.0f; sourceRect->y = (float)gameHeight; sourceRect->width = (float)gameWidth; sourceRect->height = (float)-gameHeight; const int ratio_x = (screenWidth/gameWidth); const int ratio_y = (screenHeight/gameHeight); - const float resizeRatio = (float)(ratio_x < ratio_y ? ratio_x : ratio_y); + const float resizeRatio = (float)((ratio_x < ratio_y)? ratio_x : ratio_y); - destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); - destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); - destRect->width = (float)(int)(gameWidth * resizeRatio); - destRect->height = (float)(int)(gameHeight * resizeRatio); + destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f); + destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f); + destRect->width = (float)(int)(gameWidth*resizeRatio); + destRect->height = (float)(int)(gameHeight*resizeRatio); } static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { const float resizeRatio = (float)(screenHeight/gameHeight); - sourceRect->x = 0.f; - sourceRect->y = 0.f; - sourceRect->width = (float)(int)(screenWidth / resizeRatio); + sourceRect->x = 0.0f; + sourceRect->y = 0.0f; + sourceRect->width = (float)(int)(screenWidth/resizeRatio); sourceRect->height = (float)-gameHeight; - destRect->x = (float)(int)((screenWidth - (sourceRect->width * resizeRatio)) * 0.5); - destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); - destRect->width = (float)(int)(sourceRect->width * resizeRatio); - destRect->height = (float)(int)(gameHeight * resizeRatio); + destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f); + destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f); + destRect->width = (float)(int)(sourceRect->width*resizeRatio); + destRect->height = (float)(int)(gameHeight*resizeRatio); } static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { const float resizeRatio = (float)(screenWidth/gameWidth); - sourceRect->x = 0.f; - sourceRect->y = 0.f; + sourceRect->x = 0.0f; + sourceRect->y = 0.0f; sourceRect->width = (float)gameWidth; - sourceRect->height = (float)(int)(screenHeight / resizeRatio); + sourceRect->height = (float)(int)(screenHeight/resizeRatio); - destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); - destRect->y = (float)(int)((screenHeight - (sourceRect->height * resizeRatio)) * 0.5); - destRect->width = (float)(int)(gameWidth * resizeRatio); - destRect->height = (float)(int)(sourceRect->height * resizeRatio); + destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f); + destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f); + destRect->width = (float)(int)(gameWidth*resizeRatio); + destRect->height = (float)(int)(sourceRect->height*resizeRatio); - sourceRect->height *= -1.f; + sourceRect->height *= -1.0f; } static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { - sourceRect->x = 0.f; + sourceRect->x = 0.0f; sourceRect->y = (float)gameHeight; sourceRect->width = (float)gameWidth; sourceRect->height = (float)-gameHeight; @@ -262,81 +255,58 @@ static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, const float ratio_y = ((float)screenHeight/(float)gameHeight); const float resizeRatio = (ratio_x < ratio_y ? ratio_x : ratio_y); - destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); - destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); - destRect->width = (float)(int)(gameWidth * resizeRatio); - destRect->height = (float)(int)(gameHeight * resizeRatio); + destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f); + destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f); + destRect->width = (float)(int)(gameWidth*resizeRatio); + destRect->height = (float)(int)(gameHeight*resizeRatio); } static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { const float resizeRatio = ((float)screenHeight/(float)gameHeight); - sourceRect->x = 0.f; - sourceRect->y = 0.f; - sourceRect->width = (float)(int)((float)screenWidth / resizeRatio); + sourceRect->x = 0.0f; + sourceRect->y = 0.0f; + sourceRect->width = (float)(int)((float)screenWidth/resizeRatio); sourceRect->height = (float)-gameHeight; - destRect->x = (float)(int)((screenWidth - (sourceRect->width * resizeRatio)) * 0.5); - destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5); - destRect->width = (float)(int)(sourceRect->width * resizeRatio); - destRect->height = (float)(int)(gameHeight * resizeRatio); + destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f); + destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f); + destRect->width = (float)(int)(sourceRect->width*resizeRatio); + destRect->height = (float)(int)(gameHeight*resizeRatio); } static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { const float resizeRatio = ((float)screenWidth/(float)gameWidth); - sourceRect->x = 0.f; - sourceRect->y = 0.f; + sourceRect->x = 0.0f; + sourceRect->y = 0.0f; sourceRect->width = (float)gameWidth; - sourceRect->height = (float)(int)((float)screenHeight / resizeRatio); + sourceRect->height = (float)(int)((float)screenHeight/resizeRatio); - destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5); - destRect->y = (float)(int)((screenHeight - (sourceRect->height * resizeRatio)) * 0.5); - destRect->width = (float)(int)(gameWidth * resizeRatio); - destRect->height = (float)(int)(sourceRect->height * resizeRatio); + destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f); + destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f); + destRect->width = (float)(int)(gameWidth*resizeRatio); + destRect->height = (float)(int)(sourceRect->height*resizeRatio); sourceRect->height *= -1.f; } -static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target) +static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target) { *screenWidth = GetScreenWidth(); *screenHeight = GetScreenHeight(); switch(viewportType) { - case KEEP_ASPECT_INTEGER: - { - KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); - break; - } - case KEEP_HEIGHT_INTEGER: - { - KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); - break; - } - case KEEP_WIDTH_INTEGER: - { - KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); - break; - } - case KEEP_ASPECT: - { - KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); - break; - } - case KEEP_HEIGHT: - { - KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); - break; - } - case KEEP_WIDTH: - { - KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); - break; - } - default: {} + case KEEP_ASPECT_INTEGER: KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break; + case KEEP_HEIGHT_INTEGER: KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break; + case KEEP_WIDTH_INTEGER: KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break; + case KEEP_ASPECT: KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break; + case KEEP_HEIGHT: KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break; + case KEEP_WIDTH: KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break; + default: break; } + UnloadRenderTexture(*target); *target = LoadRenderTexture(sourceRect->width, -sourceRect->height); } @@ -345,7 +315,7 @@ static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, i static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect) { Vector2 relativePosition = {point.x - scaledRect->x, point.y - scaledRect->y}; - Vector2 ratio = {textureRect->width / scaledRect->width, -textureRect->height / scaledRect->height}; + Vector2 ratio = {textureRect->width/scaledRect->width, -textureRect->height/scaledRect->height}; - return (Vector2){relativePosition.x * ratio.x, relativePosition.y * ratio.x}; + return (Vector2){relativePosition.x*ratio.x, relativePosition.y*ratio.x}; } \ No newline at end of file diff --git a/examples/core/core_window_flags.c b/examples/core/core_window_flags.c index 048d2d245..a8096eeb4 100644 --- a/examples/core/core_window_flags.c +++ b/examples/core/core_window_flags.c @@ -97,7 +97,8 @@ int main(void) if (IsWindowState(FLAG_WINDOW_MINIMIZED)) { framesCounter++; - if (framesCounter >= 240) { + if (framesCounter >= 240) + { RestoreWindow(); // Restore window after 3 seconds framesCounter = 0; } diff --git a/examples/models/models_loading_vox.c b/examples/models/models_loading_vox.c index 47be07ee4..06dc651d7 100644 --- a/examples/models/models_loading_vox.c +++ b/examples/models/models_loading_vox.c @@ -138,7 +138,7 @@ int main(void) GetMouseWheelMove()*-2.0f); // Move to target (zoom) // Cycle between models on mouse click - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES; + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES; // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f }) float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; diff --git a/examples/shaders/shaders_basic_pbr.c b/examples/shaders/shaders_basic_pbr.c index 7ee05502d..dd5f871da 100644 --- a/examples/shaders/shaders_basic_pbr.c +++ b/examples/shaders/shaders_basic_pbr.c @@ -254,9 +254,9 @@ int main(void) { Color lightColor = (Color){ (unsigned char)(lights[i].color[0]*255), - (unsigned char)(lights[i].color[1] * 255), - (unsigned char)(lights[i].color[2] * 255), - (unsigned char)(lights[i].color[3] * 255) }; + (unsigned char)(lights[i].color[1]*255), + (unsigned char)(lights[i].color[2]*255), + (unsigned char)(lights[i].color[3]*255) }; if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lightColor); else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lightColor, 0.3f)); diff --git a/examples/shaders/shaders_color_correction.c b/examples/shaders/shaders_color_correction.c index 3abf29840..826baecc7 100644 --- a/examples/shaders/shaders_color_correction.c +++ b/examples/shaders/shaders_color_correction.c @@ -138,7 +138,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - for (int i = 0; i < MAX_TEXTURES; ++i) UnloadTexture(texture[i]); + for (int i = 0; i < MAX_TEXTURES; i++) UnloadTexture(texture[i]); UnloadShader(shdrColorCorrection); CloseWindow(); // Close window and OpenGL context diff --git a/examples/shaders/shaders_hybrid_rendering.c b/examples/shaders/shaders_hybrid_rendering.c index e523a91c8..439965fd6 100644 --- a/examples/shaders/shaders_hybrid_rendering.c +++ b/examples/shaders/shaders_hybrid_rendering.c @@ -138,7 +138,7 @@ int main(void) ClearBackground(RAYWHITE); DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE); - + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/shapes/shapes_bullet_hell.c b/examples/shapes/shapes_bullet_hell.c index 95abc4dc9..2ff3be14b 100644 --- a/examples/shapes/shapes_bullet_hell.c +++ b/examples/shapes/shapes_bullet_hell.c @@ -107,7 +107,7 @@ int main(void) float bulletDirection = baseDirection + (degreesPerRow*row); - // Bullet speed * bullet direction, this will determine how much pixels will be incremented/decremented + // Bullet speed*bullet direction, this will determine how much pixels will be incremented/decremented // from the bullet position every frame. Since the bullets doesn't change its direction and speed, // only need to calculate it at the spawning time // 0 degrees = right, 90 degrees = down, 180 degrees = left and 270 degrees = up, basically clockwise diff --git a/examples/shapes/shapes_clock_of_clocks.c b/examples/shapes/shapes_clock_of_clocks.c index 51703a32d..d87ec6411 100644 --- a/examples/shapes/shapes_clock_of_clocks.c +++ b/examples/shapes/shapes_clock_of_clocks.c @@ -14,9 +14,6 @@ * Copyright (c) 2025 JP Mortiboys (@themushroompirates) * ********************************************************************************************/ -#if defined(WIN32) -#define _CRT_SECURE_NO_WARNINGS -#endif #include "raylib.h" @@ -63,24 +60,16 @@ int main(void) /* 8 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR }, /* 9 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR }, }; + // Time for the hands to move to the new position (in seconds); this must be <1s - const float handsMoveDuration = .5f; + const float handsMoveDuration = 0.5f; - // We store the previous seconds value so we can see if the time has changed int prevSeconds = -1; - - // This represents the real position where the hands are right now Vector2 currentAngles[6][24] = { 0 }; - - // This is the position where the hands were moving from Vector2 srcAngles[6][24] = { 0 }; - // This is the position where the hands are moving to Vector2 dstAngles[6][24] = { 0 }; - // Current animation timer float handsMoveTimer = 0.0f; - - // 12 or 24 hour mode int hourMode = 24; SetTargetFPS(60); // Set our game to run at 60 frames-per-second @@ -91,7 +80,6 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - // Get the current time time_t rawtime; struct tm *timeinfo; @@ -99,30 +87,26 @@ int main(void) time(&rawtime); timeinfo = localtime(&rawtime); - if (timeinfo->tm_sec != prevSeconds) { + if (timeinfo->tm_sec != prevSeconds) + { // The time has changed, so we need to move the hands to the new positions prevSeconds = timeinfo->tm_sec; // Format the current time so we can access the individual digits - const char *clockDigits = TextFormat("%02d%02d%02d", timeinfo->tm_hour % hourMode, timeinfo->tm_min, timeinfo->tm_sec); + const char *clockDigits = TextFormat("%02d%02d%02d", timeinfo->tm_hour%hourMode, timeinfo->tm_min, timeinfo->tm_sec); // Fetch where we want all the hands to be - for (int digit = 0; digit < 6; digit++) { - for (int cell = 0; cell < 24; cell++) { + for (int digit = 0; digit < 6; digit++) + { + for (int cell = 0; cell < 24; cell++) + { srcAngles[digit][cell] = currentAngles[digit][cell]; - dstAngles[digit][cell] = digitAngles[ clockDigits[digit] - '0' ][cell]; + dstAngles[digit][cell] = digitAngles[clockDigits[digit] - '0'][cell]; // Quick exception for 12h mode - if (digit == 0 && hourMode == 12 && clockDigits[0] == '0') { - dstAngles[digit][cell] = ZZ; - } - - if (srcAngles[digit][cell].x > dstAngles[digit][cell].x) { - srcAngles[digit][cell].x -= 360.0f; - } - if (srcAngles[digit][cell].y > dstAngles[digit][cell].y) { - srcAngles[digit][cell].y -= 360.0f; - } + if ((digit == 0) && (hourMode == 12) && (clockDigits[0] == '0')) dstAngles[digit][cell] = ZZ; + if (srcAngles[digit][cell].x > dstAngles[digit][cell].x) srcAngles[digit][cell].x -= 360.0f; + if (srcAngles[digit][cell].y > dstAngles[digit][cell].y) srcAngles[digit][cell].y -= 360.0f; } } @@ -131,37 +115,29 @@ int main(void) } // Now let's animate all the hands if we need to - if (handsMoveTimer < handsMoveDuration) { + if (handsMoveTimer < handsMoveDuration) + { // Increase the timer but don't go above the maximum handsMoveTimer = Clamp(handsMoveTimer + GetFrameTime(), 0, handsMoveDuration); - // Calculate the % completion of the animation - float t = handsMoveTimer / handsMoveDuration; + // Calculate the%completion of the animation + float t = handsMoveTimer/handsMoveDuration; // A little cheeky smoothstep - t = t * t * (3.0f - 2.0f * t); + t = t*t*(3.0f - 2.0f*t); - for (int digit = 0; digit < 6; digit++) { - for (int cell = 0; cell < 24; cell++) { + for (int digit = 0; digit < 6; digit++) + { + for (int cell = 0; cell < 24; cell++) + { currentAngles[digit][cell].x = Lerp(srcAngles[digit][cell].x, dstAngles[digit][cell].x, t); currentAngles[digit][cell].y = Lerp(srcAngles[digit][cell].y, dstAngles[digit][cell].y, t); } } - - if (handsMoveTimer == handsMoveDuration) { - // The animation has now finished - } } // Handle input - - // Toggle between 12 and 24 hour mode with space - if (IsKeyPressed(KEY_SPACE)) { - hourMode = 36 - hourMode; - } - - - + if (IsKeyPressed(KEY_SPACE)) hourMode = 36 - hourMode; // Toggle between 12 and 24 hour mode with space //---------------------------------------------------------------------------------- // Draw @@ -174,19 +150,22 @@ int main(void) float xOffset = 4.0f; - for (int digit = 0; digit < 6; digit++) { - - for (int row = 0; row < 6; row++) { - for (int col = 0; col < 4; col++) { + for (int digit = 0; digit < 6; digit++) + { + for (int row = 0; row < 6; row++) + { + for (int col = 0; col < 4; col++) + { Vector2 centre = (Vector2){ - xOffset + col*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f, - 100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f + xOffset + col*(clockFaceSize+clockFaceSpacing) + clockFaceSize*0.5f, + 100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize*0.5f }; - DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, DARKGRAY); + + DrawRing(centre, clockFaceSize*0.5f - 2.0f, clockFaceSize*0.5f, 0, 360, 24, DARKGRAY); // Big hand DrawRectanglePro( - (Rectangle){centre.x, centre.y, clockFaceSize*.5f+4.0f, 4.0f}, + (Rectangle){centre.x, centre.y, clockFaceSize*0.5f+4.0f, 4.0f}, (Vector2){ 2.0f, 2.0f }, currentAngles[digit][row*4+col].x, handsColor @@ -194,7 +173,7 @@ int main(void) // Little hand DrawRectanglePro( - (Rectangle){centre.x, centre.y, clockFaceSize*.5f+2.0f, 4.0f}, + (Rectangle){centre.x, centre.y, clockFaceSize*0.5f+2.0f, 4.0f}, (Vector2){ 2.0f, 2.0f }, currentAngles[digit][row*4+col].y, handsColor @@ -202,27 +181,23 @@ int main(void) } } - xOffset += (clockFaceSize+clockFaceSpacing) * 4; - if (digit % 2 == 1) { - + xOffset += (clockFaceSize+clockFaceSpacing)*4; + if (digit%2 == 1) + { DrawRing((Vector2){xOffset + 4.0f, 160.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor); DrawRing((Vector2){xOffset + 4.0f, 225.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor); - xOffset += sectionSpacing; - } } DrawFPS(10, 10); - EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c index 4bcac02f9..cbf487f93 100644 --- a/examples/shapes/shapes_double_pendulum.c +++ b/examples/shapes/shapes_double_pendulum.c @@ -76,7 +76,7 @@ int main(void) float step = dt/SIMULATION_STEPS, step2 = step*step; // Update Physics - larger steps = better approximation - for (int i = 0; i < SIMULATION_STEPS; ++i) + for (int i = 0; i < SIMULATION_STEPS; i++) { float delta = theta1 - theta2; float sinD = sinf(delta), cosD = cosf(delta), cos2D = cosf(2*delta); diff --git a/examples/shapes/shapes_math_angle_rotation.c b/examples/shapes/shapes_math_angle_rotation.c index f895026f5..63c9aaa91 100644 --- a/examples/shapes/shapes_math_angle_rotation.c +++ b/examples/shapes/shapes_math_angle_rotation.c @@ -31,7 +31,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math angle rotation"); SetTargetFPS(60); - Vector2 center = { screenWidth / 2.0f, screenHeight / 2.0f }; + Vector2 center = { screenWidth/2.0f, screenHeight/2.0f }; const float lineLength = 150.0f; // Predefined angles for fixed lines @@ -60,9 +60,9 @@ int main(void) // Draw fixed-angle lines with colorful gradient for (int i = 0; i < numAngles; i++) { - float rad = angles[i] * DEG2RAD; - Vector2 end = { center.x + cosf(rad) * lineLength, - center.y + sinf(rad) * lineLength }; + float rad = angles[i]*DEG2RAD; + Vector2 end = { center.x + cosf(rad)*lineLength, + center.y + sinf(rad)*lineLength }; // Gradient color from green → cyan → blue → magenta Color col; @@ -78,15 +78,15 @@ int main(void) DrawLineEx(center, end, 5.0f, col); // Draw angle label slightly offset along the line - Vector2 textPos = { center.x + cosf(rad) * (lineLength + 20), - center.y + sinf(rad) * (lineLength + 20) }; + Vector2 textPos = { center.x + cosf(rad)*(lineLength + 20), + center.y + sinf(rad)*(lineLength + 20) }; DrawText(TextFormat("%d°", angles[i]), (int)textPos.x, (int)textPos.y, 20, col); } // Draw animated rotating line with changing color - float animRad = totalAngle * DEG2RAD; - Vector2 animEnd = { center.x + cosf(animRad) * lineLength, - center.y + sinf(animRad) * lineLength }; + float animRad = totalAngle*DEG2RAD; + Vector2 animEnd = { center.x + cosf(animRad)*lineLength, + center.y + sinf(animRad)*lineLength }; // Cycle through HSV colors for animated line Color animCol = ColorFromHSV(fmodf(totalAngle, 360.0f), 0.8f, 0.9f); diff --git a/examples/shapes/shapes_math_sine_cosine.c b/examples/shapes/shapes_math_sine_cosine.c index 4e5f3fe47..c3646cabd 100644 --- a/examples/shapes/shapes_math_sine_cosine.c +++ b/examples/shapes/shapes_math_sine_cosine.c @@ -40,8 +40,8 @@ int main(void) Vector2 sinePoints[WAVE_POINTS]; Vector2 cosPoints[WAVE_POINTS]; - Vector2 center = { (screenWidth/2.0f) - 30.f, screenHeight/2.0f }; - Rectangle start = { 20.f, screenHeight - 120.f , 200.0f, 100.0f}; + Vector2 center = { (screenWidth/2.0f) - 30.0f, screenHeight/2.0f }; + Rectangle start = { 20.0f, screenHeight - 120.f , 200.0f, 100.0f}; float radius = 130.0f; float angle = 0.0f; bool pause = false; @@ -98,7 +98,7 @@ int main(void) // Base circle and axes DrawCircleLinesV(center, radius, GRAY); DrawLineEx((Vector2){ center.x, limitMin.y }, (Vector2){ center.x, limitMax.y }, 1.0f, GRAY); - DrawLineEx((Vector2){ limitMin.x, center.y }, (Vector2){ limitMax.x, center.y }, 1.f, GRAY); + DrawLineEx((Vector2){ limitMin.x, center.y }, (Vector2){ limitMax.x, center.y }, 1.0f, GRAY); // Wave graph axes DrawLineEx((Vector2){ start.x , start.y }, (Vector2){ start.x , start.y + start.height }, 2.0f, GRAY); @@ -135,19 +135,19 @@ int main(void) DrawText(TextFormat("Cotangent %.2f", cotangent), 640, 250, 6, ORANGE); // Complementary angle (beige) - DrawCircleSectorLines(center, radius*0.6f , -angle, -90.f , 36.0f, BEIGE); + DrawCircleSectorLines(center, radius*0.6f , -angle, -90.0f , 36.0f, BEIGE); DrawText(TextFormat("Complementary %0.f°",complementary), 640, 150, 6, BEIGE); // Supplementary angle (darkblue) - DrawCircleSectorLines(center, radius*0.5f , -angle, -180.f , 36.0f, DARKBLUE); + DrawCircleSectorLines(center, radius*0.5f , -angle, -180.0f , 36.0f, DARKBLUE); DrawText(TextFormat("Supplementary %0.f°",supplementary), 640, 130, 6, DARKBLUE); // Explementary angle (pink) - DrawCircleSectorLines(center, radius*0.4f , -angle, -360.f , 36.0f, PINK); + DrawCircleSectorLines(center, radius*0.4f , -angle, -360.0f , 36.0f, PINK); DrawText(TextFormat("Explementary %0.f°",explementary), 640, 170, 6, PINK); // Current angle - arc (lime), radius (black), endpoint (black) - DrawCircleSectorLines(center, radius*0.7f , -angle, 0.f, 36.0f, LIME); + DrawCircleSectorLines(center, radius*0.7f , -angle, 0.0f, 36.0f, LIME); DrawLineEx((Vector2){ center.x , center.y }, point, 2.0f, BLACK); DrawCircleV(point, 4.0f, BLACK); @@ -156,11 +156,12 @@ int main(void) GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(GRAY)); GuiToggle((Rectangle){ 640, 70, 120, 20}, TextFormat("Pause"), &pause); GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(LIME)); - GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.f); + GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.0f); // Angle values panel GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values"); //------------------------------------------------------------------------------ + DrawFPS(10, 10); EndDrawing(); diff --git a/examples/shapes/shapes_mouse_trail.c b/examples/shapes/shapes_mouse_trail.c index 819124220..3dd0fbd7f 100644 --- a/examples/shapes/shapes_mouse_trail.c +++ b/examples/shapes/shapes_mouse_trail.c @@ -71,7 +71,7 @@ int main(void) if ((trailPositions[i].x != 0.0f) || (trailPositions[i].y != 0.0f)) { // Calculate relative trail strength (ratio is near 1.0 for new, near 0.0 for old) - float ratio = (float)(MAX_TRAIL_LENGTH - i) / MAX_TRAIL_LENGTH; + float ratio = (float)(MAX_TRAIL_LENGTH - i)/MAX_TRAIL_LENGTH; // Fade effect: oldest positions are more transparent // Fade (color, alpha) - alpha is 0.5 to 1.0 based on ratio diff --git a/examples/shapes/shapes_rectangle_advanced.c b/examples/shapes/shapes_rectangle_advanced.c index 15487ee55..c274cb6f8 100644 --- a/examples/shapes/shapes_rectangle_advanced.c +++ b/examples/shapes/shapes_rectangle_advanced.c @@ -184,7 +184,7 @@ static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, fl } // End one even segments - if ( segments % 2) + if ( segments%2) { rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); rlVertex2f(center.x, center.y); diff --git a/examples/shapes/shapes_recursive_tree.c b/examples/shapes/shapes_recursive_tree.c index 4f1f4d5fd..f15758773 100644 --- a/examples/shapes/shapes_recursive_tree.c +++ b/examples/shapes/shapes_recursive_tree.c @@ -112,7 +112,7 @@ int main(void) GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f", angle), &angle, 0, 180); GuiSliderBar((Rectangle){ 640, 70, 120, 20 }, "Length", TextFormat("%.0f", length), &length, 12.0f, 240.0f); GuiSliderBar((Rectangle){ 640, 100, 120, 20}, "Decay", TextFormat("%.2f", branchDecay), &branchDecay, 0.1f, 0.78f); - GuiSliderBar((Rectangle){ 640, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.f); + GuiSliderBar((Rectangle){ 640, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.0f); GuiSliderBar((Rectangle){ 640, 160, 120, 20}, "Thick", TextFormat("%.0f", thick), &thick, 1, 8); GuiCheckBox((Rectangle){ 640, 190, 20, 20 }, "Bezier", &bezier); //------------------------------------------------------------------------------ diff --git a/examples/shapes/shapes_rlgl_color_wheel.c b/examples/shapes/shapes_rlgl_color_wheel.c index 47ae5f7a4..f02226a83 100644 --- a/examples/shapes/shapes_rlgl_color_wheel.c +++ b/examples/shapes/shapes_rlgl_color_wheel.c @@ -122,11 +122,11 @@ int main(void) } float distance = Vector2Distance(center, circlePosition)/pointScale; - float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f) / 2.0f); + float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f)/2.0f); if (distance > 1.0f) { - circlePosition = Vector2Add((Vector2){ sinf(angle*(PI * 2.0f)) * pointScale, -cosf(angle*(PI*2.0f))*pointScale }, center); + circlePosition = Vector2Add((Vector2){ sinf(angle*(PI*2.0f))*pointScale, -cosf(angle*(PI*2.0f))*pointScale }, center); } } @@ -152,21 +152,15 @@ int main(void) // If the slider or the wheel was clicked, update the current color if (settingColor || sliderClicked) { - if (settingColor) { - circlePosition = GetMousePosition(); - } + if (settingColor) circlePosition = GetMousePosition(); - float distance = Vector2Distance(center, circlePosition) / pointScale; + float distance = Vector2Distance(center, circlePosition)/pointScale; float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f)/2.0f); - if (settingColor && distance > 1.0f) { - circlePosition = Vector2Add((Vector2){ sinf(angle*(PI*2.0f))*pointScale, -cosf(angle*(PI* 2.0f))*pointScale }, center); - } + if (settingColor && distance > 1.0f) circlePosition = Vector2Add((Vector2){ sinf(angle*(PI*2.0f))*pointScale, -cosf(angle*(PI* 2.0f))*pointScale }, center); float angle360 = angle*360.0f; - float valueActual = Clamp(distance, 0.0f, 1.0f); - color = ColorLerp((Color){ (int)(value*255.0f), (int)(value*255.0f), (int)(value*255.0f), 255 }, ColorFromHSV(angle360, Clamp(distance, 0.0f, 1.0f), 1.0f), valueActual); } //---------------------------------------------------------------------------------- diff --git a/examples/shapes/shapes_simple_particles.c b/examples/shapes/shapes_simple_particles.c index 7be0c82e4..f8151e7ad 100644 --- a/examples/shapes/shapes_simple_particles.c +++ b/examples/shapes/shapes_simple_particles.c @@ -95,7 +95,7 @@ int main(void) } else { - for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType); + for (int i = 0; i <= emissionRate; i++) EmitParticle(&circularBuffer, emitterPosition, currentType); } // Update the parameters of each particle diff --git a/examples/shapes/shapes_triangle_strip.c b/examples/shapes/shapes_triangle_strip.c index 3b44da5e0..de712270c 100644 --- a/examples/shapes/shapes_triangle_strip.c +++ b/examples/shapes/shapes_triangle_strip.c @@ -34,7 +34,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - triangle strip"); Vector2 points[122] = { 0 }; - Vector2 center = { (screenWidth/2.0f) - 125.f, screenHeight/2.0f }; + Vector2 center = { (screenWidth/2.0f) - 125.0f, screenHeight/2.0f }; float segments = 6.0f; float insideRadius = 100.0f; float outsideRadius = 150.0f; @@ -92,7 +92,7 @@ int main(void) // Draw GUI controls //------------------------------------------------------------------------------ - GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Segments", TextFormat("%.0f", segments), &segments, 6.0f, 60.f); + GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Segments", TextFormat("%.0f", segments), &segments, 6.0f, 60.0f); GuiCheckBox((Rectangle){ 640, 70, 20, 20 }, "Outline", &outline); //------------------------------------------------------------------------------ diff --git a/examples/text/text_3d_drawing.c b/examples/text/text_3d_drawing.c index 202494bf7..80b617b2e 100644 --- a/examples/text/text_3d_drawing.c +++ b/examples/text/text_3d_drawing.c @@ -231,7 +231,7 @@ int main(void) if (multicolor) { // Fill color array with random colors - for (int i = 0; i < TEXT_MAX_LAYERS; ++i) + for (int i = 0; i < TEXT_MAX_LAYERS; i++) { multi[i] = GenerateRandomColor(0.5f, 0.8f); multi[i].a = GetRandomValue(0, 255); @@ -296,7 +296,7 @@ int main(void) rlRotatef(90.0f, 1.0f, 0.0f, 0.0f); rlRotatef(90.0f, 0.0f, 0.0f, -1.0f); - for (int i = 0; i < layers; ++i) + for (int i = 0; i < layers; i++) { Color clr = light; if (multicolor) clr = multi[i]; diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c index adedc4056..aeebe0abc 100644 --- a/examples/text/text_inline_styling.c +++ b/examples/text/text_inline_styling.c @@ -186,7 +186,7 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float else increaseX += ((float)font.glyphs[index].advanceX*scaleFactor + spacing); // Draw background rectangle color (if required) - if (colBack.a > 0) DrawRectangleRec((Rectangle) { position.x + textOffsetX, position.y + textOffsetY - backRecPadding, increaseX, fontSize + 2 * backRecPadding }, colBack); + if (colBack.a > 0) DrawRectangleRec((Rectangle) { position.x + textOffsetX, position.y + textOffsetY - backRecPadding, increaseX, fontSize + 2*backRecPadding }, colBack); if ((codepoint != ' ') && (codepoint != '\t')) { diff --git a/examples/text/text_unicode_emojis.c b/examples/text/text_unicode_emojis.c index 30fcaa8b7..00712745d 100644 --- a/examples/text/text_unicode_emojis.c +++ b/examples/text/text_unicode_emojis.c @@ -210,7 +210,7 @@ int main(void) // Draw random emojis in the background //------------------------------------------------------------------------------ - for (int i = 0; i < SIZEOF(emoji); ++i) + for (int i = 0; i < SIZEOF(emoji); i++) { const char *txt = &emojiCodepoints[emoji[i].index]; Rectangle emojiRect = { position.x, position.y, (float)fontEmoji.baseSize, (float)fontEmoji.baseSize }; @@ -316,7 +316,7 @@ static void RandomizeEmoji(void) hovered = selected = -1; int start = GetRandomValue(45, 360); - for (int i = 0; i < SIZEOF(emoji); ++i) + for (int i = 0; i < SIZEOF(emoji); i++) { // 0-179 emoji codepoints (from emoji char array) each 4bytes + null char emoji[i].index = GetRandomValue(0, 179)*5; diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c index 103e24e59..6cfd2a85c 100644 --- a/examples/text/text_words_alignment.c +++ b/examples/text/text_words_alignment.c @@ -70,27 +70,32 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - - if (IsKeyPressed(KEY_LEFT)) { + if (IsKeyPressed(KEY_LEFT)) + { hAlign = hAlign - 1; if (hAlign < 0) hAlign = 0; } - if (IsKeyPressed(KEY_RIGHT)) { + + if (IsKeyPressed(KEY_RIGHT)) + { hAlign = hAlign + 1; if (hAlign > 2) hAlign = 2; } - if (IsKeyPressed(KEY_UP)) { + + if (IsKeyPressed(KEY_UP)) + { vAlign = vAlign - 1; if (vAlign < 0) vAlign = 0; } - if (IsKeyPressed(KEY_DOWN)) { + + if (IsKeyPressed(KEY_DOWN)) + { vAlign = vAlign + 1; if (vAlign > 2) vAlign = 2; } // One word per second - wordIndex = (int)GetTime() % wordCount; - + wordIndex = (int)GetTime()%wordCount; //---------------------------------------------------------------------------------- // Draw @@ -108,9 +113,9 @@ int main(void) Vector2 textSize = MeasureTextEx(font, words[wordIndex], fontSize, fontSize*.1f); // Calculate the top-left text position based on the rectangle and alignment - Vector2 textPos = (Vector2) { - textContainerRect.x + Lerp(0.0f, textContainerRect.width - textSize.x, ((float)hAlign) * 0.5f), - textContainerRect.y + Lerp(0.0f, textContainerRect.height - textSize.y, ((float)vAlign) * 0.5f) + Vector2 textPos = (Vector2){ + textContainerRect.x + Lerp(0.0f, textContainerRect.width - textSize.x, ((float)hAlign)*0.5f), + textContainerRect.y + Lerp(0.0f, textContainerRect.height - textSize.y, ((float)vAlign)*0.5f) }; // Draw the text diff --git a/examples/textures/textures_mouse_painting.c b/examples/textures/textures_mouse_painting.c index 2575c4450..6996ddac4 100644 --- a/examples/textures/textures_mouse_painting.c +++ b/examples/textures/textures_mouse_painting.c @@ -179,7 +179,7 @@ int main(void) ClearBackground(RAYWHITE); // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) - DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2) { 0, 0 }, WHITE); + DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2) { 0, 0 }, WHITE); // Draw drawing circle for reference if (mousePos.y > 50) diff --git a/examples/textures/textures_sprite_stacking.c b/examples/textures/textures_sprite_stacking.c index 5edc1af6b..b20474711 100644 --- a/examples/textures/textures_sprite_stacking.c +++ b/examples/textures/textures_sprite_stacking.c @@ -56,7 +56,7 @@ int main(void) // Add a positive/negative offset to spin right/left at different speeds if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) rotationSpeed -= speedChange; if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) rotationSpeed += speedChange; - + rotation += rotationSpeed*GetFrameTime(); //---------------------------------------------------------------------------------- diff --git a/examples/textures/textures_tiled_drawing.c b/examples/textures/textures_tiled_drawing.c index 39a168850..9e5285035 100644 --- a/examples/textures/textures_tiled_drawing.c +++ b/examples/textures/textures_tiled_drawing.c @@ -100,7 +100,7 @@ int main(void) } // Check to see which color was clicked and set it as the active color - for (int i = 0; i < MAX_COLORS; ++i) + for (int i = 0; i < MAX_COLORS; i++) { if (CheckCollisionPointRec(mouse, colorRec[i])) { From 84737a9fc19669b04ce86eb458033b81089bbddc Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Nov 2025 20:25:42 +0100 Subject: [PATCH 175/189] Update CONVENTIONS.md --- CONVENTIONS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 58cfa6270..86044193c 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -41,6 +41,7 @@ while (!WindowShouldClose()) } +// Always use accumulators as `x++` instead of `++x` for (int i = 0; i < NUM_VALUES; i++) printf("%i", i); // Be careful with the switch formatting! From f1719480e0f61418bf5f5e2a2c2f8bc20b1c3074 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 23 Nov 2025 13:21:31 +0100 Subject: [PATCH 176/189] Minor format tweaks --- src/platforms/rcore_desktop_sdl.c | 8 ++++---- src/platforms/rcore_drm.c | 6 +++--- src/platforms/rcore_web.c | 4 ++-- src/rmodels.c | 2 +- src/rtextures.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index d6c7fd476..f3da04fa4 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1188,7 +1188,7 @@ Image GetClipboardImage(void) size_t dataSize = 0; void *fileData = NULL; - for (int i = 0; i < SDL_arraysize(imageFormats); ++i) + for (int i = 0; i < SDL_arraysize(imageFormats); i++) { // NOTE: This pointer should be free with SDL_free() at some point fileData = SDL_GetClipboardData(imageFormats[i], &dataSize); @@ -1395,7 +1395,7 @@ void PollInputEvents(void) //----------------------------------------------------------------------------- // WARNING: Indexes into this array are obtained by using SDL_Scancode values, not SDL_Keycode values //const Uint8 *keys = SDL_GetKeyboardState(NULL); - //for (int i = 0; i < 256; ++i) CORE.Input.Keyboard.currentKeyState[i] = keys[i]; + //for (int i = 0; i < 256; i++) CORE.Input.Keyboard.currentKeyState[i] = keys[i]; CORE.Window.resizedLastFrame = false; @@ -1562,7 +1562,7 @@ void PollInputEvents(void) case SDL_KEYDOWN: { #if defined(USING_VERSION_SDL3) - // SDL3 Migration: The following structures have been removed: * SDL_Keysym + // SDL3 Migration: The following structures have been removed: SDL_Keysym KeyboardKey key = ConvertScancodeToKey(event.key.scancode); #else KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode); @@ -1697,7 +1697,7 @@ void PollInputEvents(void) int jid = event.jdevice.which; // Joystick device index // check if already added at InitPlatform - for (int i = 0; i < MAX_GAMEPADS; ++i) + for (int i = 0; i < MAX_GAMEPADS; i++) { if (jid == platform.gamepadId[i]) { diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index c0fa5a5f3..fa20b9039 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1456,7 +1456,7 @@ int InitPlatform(void) // find the EGL config that matches the previously setup GBM format int found = 0; - for (EGLint i = 0; i < matchingNumConfigs; ++i) + for (EGLint i = 0; i < matchingNumConfigs; i++) { EGLint id = 0; if (!eglGetConfigAttrib(platform.device, configs[i], EGL_NATIVE_VISUAL_ID, &id)) @@ -1878,7 +1878,7 @@ static void InitEvdevInput(void) platform.mouseFd = -1; // Reset variables - for (int i = 0; i < MAX_TOUCH_POINTS; ++i) + for (int i = 0; i < MAX_TOUCH_POINTS; i++) { CORE.Input.Touch.position[i].x = -1; CORE.Input.Touch.position[i].y = -1; @@ -2463,7 +2463,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt continue; } - const int unusedPixels = (mode->hdisplay - width) * (mode->vdisplay - height); + const int unusedPixels = (mode->hdisplay - width)*(mode->vdisplay - height); const int fpsDiff = mode->vrefresh - fps; if ((unusedPixels < minUnusedPixels) || diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 5f8afd7e4..97a4b3f29 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -1671,8 +1671,8 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE 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++) 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)) diff --git a/src/rmodels.c b/src/rmodels.c index c09a94652..e3800b575 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -3289,7 +3289,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) for (int z = 0; z < cubicmap.height; ++z) { - for (int x = 0; x < cubicmap.width; ++x) + for (int x = 0; x < cubicmap.width; x++) { // Define the 8 vertex of the cube, we will combine them accordingly later... Vector3 v1 = { w*(x - 0.5f), h2, h*(z - 0.5f) }; diff --git a/src/rtextures.c b/src/rtextures.c index 299ab6793..3e4666572 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3341,14 +3341,14 @@ void ImageClearBackground(Image *dst, Color color) unsigned char *pSrcPixel = (unsigned char *)dst->data; int bytesPerPixel = GetPixelDataSize(1, 1, dst->format); - int totalPixels = dst->width * dst->height; + int totalPixels = dst->width*dst->height; // Repeat the first pixel data throughout the image, // doubling the pixels copied on each iteration for (int i = 1; i < totalPixels; i *= 2) { int pixelsToCopy = MIN(i, totalPixels - i); - memcpy(pSrcPixel + i * bytesPerPixel, pSrcPixel, pixelsToCopy * bytesPerPixel); + memcpy(pSrcPixel + i*bytesPerPixel, pSrcPixel, pixelsToCopy*bytesPerPixel); } } @@ -3730,7 +3730,7 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color) for (int x = 1; x < (int)rec.width; x *= 2) { int pixelsToCopy = MIN(x, (int)rec.width - x); - memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, pixelsToCopy * bytesPerPixel); + memcpy(pSrcPixel + x*bytesPerPixel, pSrcPixel, pixelsToCopy*bytesPerPixel); } // Repeat the first row data for all other rows From cf5e84c3c4a984457c9ad6c0353acf0c50a714ba Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 23 Nov 2025 21:37:35 +0100 Subject: [PATCH 177/189] Update models_skybox_rendering.c --- examples/models/models_skybox_rendering.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/examples/models/models_skybox_rendering.c b/examples/models/models_skybox_rendering.c index ddce6a28f..9359e03dc 100644 --- a/examples/models/models_skybox_rendering.c +++ b/examples/models/models_skybox_rendering.c @@ -54,7 +54,8 @@ int main(void) Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); Model skybox = LoadModelFromMesh(cube); - // Set this to true to use an HDR Texture, Note that raylib must be built with HDR Support for this to work SUPPORT_FILEFORMAT_HDR + // Set this to true to use an HDR Texture + // NOTE: raylib must be built with HDR Support for this to work: SUPPORT_FILEFORMAT_HDR bool useHDR = false; // Load skybox shader and set required locations @@ -63,8 +64,8 @@ int main(void) TextFormat("resources/shaders/glsl%i/skybox.fs", GLSL_VERSION)); SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MATERIAL_MAP_CUBEMAP }, SHADER_UNIFORM_INT); - SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]) { useHDR ? 1 : 0 }, SHADER_UNIFORM_INT); - SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR ? 1 : 0 }, SHADER_UNIFORM_INT); + SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]){ useHDR? 1 : 0 }, SHADER_UNIFORM_INT); + SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR? 1 : 0 }, SHADER_UNIFORM_INT); // Load cubemap shader and setup required shader locations Shader shdrCubemap = LoadShader(TextFormat("resources/shaders/glsl%i/cubemap.vs", GLSL_VERSION), @@ -91,9 +92,11 @@ int main(void) } else { - Image img = LoadImage("resources/skybox.png"); - skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT); // CUBEMAP_LAYOUT_PANORAMA - UnloadImage(img); + // TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image + // and generate the required cubemap image to be passed to rlLoadTextureCubemap() + Image image = LoadImage("resources/skybox.png"); + skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT); + UnloadImage(image); } DisableCursor(); // Limit cursor to relative movement inside the window @@ -132,9 +135,9 @@ int main(void) } else { - Image img = LoadImage(droppedFiles.paths[0]); - skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT); - UnloadImage(img); + Image image = LoadImage(droppedFiles.paths[0]); + skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT); + UnloadImage(image); } TextCopy(skyboxFileName, droppedFiles.paths[0]); From e1b9857b14e216b8d33136a0d2c06886b4bcb330 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 23 Nov 2025 21:40:39 +0100 Subject: [PATCH 178/189] Some TODOs and format reviews --- src/config.h | 8 ++-- src/external/rlsw.h | 54 ++++++++++++-------------- src/platforms/rcore_android.c | 59 ++++++++++------------------- src/platforms/rcore_desktop_glfw.c | 12 +++--- src/platforms/rcore_desktop_rgfw.c | 28 ++++++++------ src/platforms/rcore_desktop_sdl.c | 20 +++++----- src/platforms/rcore_desktop_win32.c | 8 +++- src/platforms/rcore_drm.c | 22 +++++------ src/platforms/rcore_web.c | 39 +++++++++---------- src/raudio.c | 6 +-- src/rcore.c | 45 ++++++++++------------ src/rlgl.h | 12 +++--- src/rmodels.c | 9 ++--- src/rshapes.c | 4 +- src/rtext.c | 2 +- src/rtextures.c | 17 +++------ 16 files changed, 154 insertions(+), 191 deletions(-) diff --git a/src/config.h b/src/config.h index 9152acc8c..89b32d0fe 100644 --- a/src/config.h +++ b/src/config.h @@ -49,10 +49,10 @@ #define SUPPORT_RPRAND_GENERATOR 1 // Mouse gestures are directly mapped like touches and processed by gestures system #define SUPPORT_MOUSE_GESTURES 1 -// Reconfigure standard input to receive key inputs, works with SSH connection. +// Reconfigure standard input to receive key inputs, works with SSH connection #define SUPPORT_SSH_KEYBOARD_RPI 1 -// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions. -// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often. +// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions +// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often #define SUPPORT_WINMM_HIGHRES_TIMER 1 // Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used //#define SUPPORT_BUSY_WAIT_LOOP 1 @@ -225,7 +225,7 @@ // On font atlas image generation [GenImageFontAtlas()], add a 3x3 pixels white rectangle // at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow -// drawing text and shapes with a single draw call [SetShapesTexture()]. +// drawing text and shapes with a single draw call [SetShapesTexture()] #define SUPPORT_FONT_ATLAS_WHITE_REC 1 // Support conservative font atlas size estimation diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 318d77334..d78da3ff8 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -145,7 +145,7 @@ #define SW_MAX_TEXTURES 128 #endif -// Under normal circumstances, clipping a polygon can add at most one vertex per clipping plane. +// Under normal circumstances, clipping a polygon can add at most one vertex per clipping plane // Considering the largest polygon involved is a quadrilateral (4 vertices), // and that clipping occurs against both the frustum (6 planes) and the scissors (4 planes), // the maximum number of vertices after clipping is: @@ -1530,7 +1530,7 @@ DEFINE_FRAMEBUFFER_COPY_BEGIN(R5G5B5A1, uint16_t) uint8_t r5 = (color[0]*31 + 127)/255; uint8_t g5 = (color[1]*31 + 127)/255; uint8_t b5 = (color[2]*31 + 127)/255; - uint8_t a1 = color[3] >= 128 ? 1 : 0; + uint8_t a1 = (color[3] >= 128)? 1 : 0; #if SW_GL_FRAMEBUFFER_COPY_BGRA uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1; @@ -1661,7 +1661,7 @@ DEFINE_FRAMEBUFFER_BLIT_BEGIN(R5G5B5A1, uint16_t) uint8_t r5 = (color[0]*31 + 127)/255; uint8_t g5 = (color[1]*31 + 127)/255; uint8_t b5 = (color[2]*31 + 127)/255; - uint8_t a1 = color[3] >= 128 ? 1 : 0; + uint8_t a1 = (color[3] >= 128)? 1 : 0; #if SW_GL_FRAMEBUFFER_COPY_BGRA uint16_t pixel = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1; @@ -1919,7 +1919,7 @@ 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. + // number of operations here, but for now it works fine float xf = (u*tex->width) - 0.5f; float yf = (v*tex->height) - 0.5f; @@ -2203,13 +2203,13 @@ 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. + // 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). + // 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. + // even with negative w values // Preload homogeneous coordinates into local variables const float *h0 = RLSW.vertexBuffer[0].homogeneous; @@ -2221,7 +2221,7 @@ static inline bool sw_triangle_face_culling(void) // This is the determinant of the matrix formed by the (x, y, w) components // of the vertices, which correctly captures the winding order in homogeneous // space and its relationship to the projected 2D winding order, even with - // negative w values. + // negative w values // The determinant formula used here is: // h0.x*(h1.y*h2.w - h2.y*h1.w) + // h1.x*(h2.y*h0.w - h0.y*h2.w) + @@ -2233,20 +2233,18 @@ static inline bool sw_triangle_face_culling(void) h2[0]*(h0[1]*h1[3] - h1[1]*h0[3]); // Discard the triangle if its winding order (determined by the sign - // of the homogeneous area/determinant) matches the culled direction. + // of the homogeneous area/determinant) matches the culled direction // A positive hSgnArea typically corresponds to a counter-clockwise // winding in the projected space when all w > 0. // This test is robust for points with w > 0 or w < 0, correctly - // capturing the change in orientation when crossing the w=0 plane. + // capturing the change in orientation when crossing the w=0 plane - // The culling logic remains the same based on the signed area/determinant. + // The culling logic remains the same based on the signed area/determinant // A value of 0 for hSgnArea means the points are collinear in (x, y, w) // space, which corresponds to a degenerate triangle projection. // Such triangles are typically not culled by this test (0 < 0 is false, 0 > 0 is false) - // and should be handled by the clipper if necessary. - return (RLSW.cullFace == SW_FRONT) - ? (hSgnArea < 0) // Cull if winding is "clockwise" in the projected sense - : (hSgnArea > 0); // Cull if winding is "counter-clockwise" in the projected sense + // and should be handled by the clipper if necessary + return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0) : (hSgnArea > 0); // Cull if winding is "clockwise" : "counter-clockwise" } static inline void sw_triangle_clip_and_project(void) @@ -2559,14 +2557,14 @@ 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. + // 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). + // 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. + // winding test on this first triangle // Preload homogeneous coordinates into local variables const float *h0 = RLSW.vertexBuffer[0].homogeneous; @@ -2578,11 +2576,11 @@ static inline bool sw_quad_face_culling(void) // Compute a value proportional to the signed area of the triangle P0 P1 P2 // in the projected 2D plane, calculated directly using homogeneous coordinates - // BEFORE division by w. + // BEFORE division by w // This is the determinant of the matrix formed by the (x, y, w) components // of the vertices P0, P1, and P2. Its sign correctly indicates the winding order // in homogeneous space and its relationship to the projected 2D winding order, - // even with negative w values. + // even with negative w values // The determinant formula used here is: // h0.x*(h1.y*h2.w - h2.y*h1.w) + // h1.x*(h2.y*h0.w - h0.y*h2.w) + @@ -2594,21 +2592,19 @@ static inline bool sw_quad_face_culling(void) h2[0]*(h0[1]*h1[3] - h1[1]*h0[3]); // Perform face culling based on the winding order determined by the sign - // of the homogeneous area/determinant of triangle P0 P1 P2. + // of the homogeneous area/determinant of triangle P0 P1 P2 // This test is robust for points with w > 0 or w < 0 within the triangle, - // correctly capturing the change in orientation when crossing the w=0 plane. + // correctly capturing the change in orientation when crossing the w=0 plane // A positive hSgnArea typically corresponds to a counter-clockwise - // winding in the projected space when all w > 0. + // winding in the projected space when all w > 0 // A value of 0 for hSgnArea means P0, P1, P2 are collinear in (x, y, w) - // space, which corresponds to a degenerate triangle projection. + // space, which corresponds to a degenerate triangle projection // Such quads might also be degenerate or non-planar. They are typically // not culled by this test (0 < 0 is false, 0 > 0 is false) // and should be handled by the clipper if necessary. - return (RLSW.cullFace == SW_FRONT) - ? (hSgnArea < 0.0f) // Cull if winding is "clockwise" in the projected sense - : (hSgnArea > 0.0f); // Cull if winding is "counter-clockwise" in the projected sense + return (RLSW.cullFace == SW_FRONT)? (hSgnArea < 0.0f) : (hSgnArea > 0.0f); // Cull if winding is "clockwise" : "counter-clockwise" } static inline void sw_quad_clip_and_project(void) @@ -4596,8 +4592,8 @@ void swDrawElements(SWdraw mode, int count, int type, const void *indices) for (int i = 0; i < count; i++) { - int index = indicesUb ? indicesUb[i] : - (indicesUs ? indicesUs[i] : indicesUi[i]); + int index = indicesUb? indicesUb[i] : + (indicesUs? indicesUs[i] : indicesUi[i]); float u, v; if (texcoords) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 4f106ee3b..88b3b4bba 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -623,10 +623,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. -// 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 +// 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 @@ -687,7 +686,7 @@ void SetMouseCursor(int cursor) TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); } -// Get physical key name. +// Get physical key name const char *GetKeyName(int key) { TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); @@ -748,9 +747,9 @@ void PollInputEvents(void) // Process this event if (platform.source != NULL) platform.source->process(platform.app, platform.source); - // NOTE: Allow closing the window in case a configuration change happened. + // NOTE: Allow closing the window in case a configuration change happened // The android_main function should be allowed to return to its caller in order for the - // Android OS to relaunch the activity. + // Android OS to relaunch the activity if (platform.app->destroyRequested != 0) { CORE.Window.shouldClose = true; @@ -829,13 +828,13 @@ 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 we reach TIMEOUT, which indicates no more events queued while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT)) { // Process this event if (platform.source != NULL) platform.source->process(platform.app, platform.source); - // NOTE: It's highly likely destroyRequested will never be non-zero at the start of the activity lifecycle. + // NOTE: It's highly likely destroyRequested will never be non-zero at the start of the activity lifecycle //if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true; } } @@ -869,8 +868,9 @@ void ClosePlatform(void) platform.device = EGL_NO_DISPLAY; } - // NOTE: Reset global state in case the activity is being relaunched. - if (platform.app->destroyRequested != 0) { + // NOTE: Reset global state in case the activity is being relaunched + if (platform.app->destroyRequested != 0) + { CORE = (CoreData){0}; platform = (PlatformData){0}; } @@ -925,7 +925,7 @@ static int InitGraphicsDevice(void) // Initialize the EGL device connection if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE) { - // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred. + // If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device"); return -1; } @@ -1081,21 +1081,6 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Initialize random seed SetRandomSeed((unsigned int)time(NULL)); - - // TODO: GPU assets reload in case of lost focus (lost context) - // NOTE: This problem has been solved just unbinding and rebinding context from display - /* - if (assetsReloadRequired) - { - for (int i = 0; i < assetCount; i++) - { - // TODO: Unload old asset if required - - // Load texture again to pointed texture - (*textureAsset + i) = LoadTexture(assetPath[i]); - } - } - */ } } } break; @@ -1115,7 +1100,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) case APP_CMD_TERM_WINDOW: { // Detach OpenGL context and destroy display surface - // NOTE 1: This case is used when the user exits the app without closing it. We detach the context to ensure everything is recoverable upon resuming. + // NOTE 1: This case is used when the user exits the app without closing it, context is detached to ensure everything is recoverable upon resuming // NOTE 2: Detaching context before destroying display surface avoids losing our resources (textures, shaders, VBOs...) // NOTE 3: In some cases (too many context loaded), OS could unload context automatically... :( if (platform.device != EGL_NO_DISPLAY) @@ -1179,8 +1164,8 @@ static GamepadButton AndroidTranslateGamepadButton(int button) static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) { // If additional inputs are required check: - // https://developer.android.com/ndk/reference/group/input - // https://developer.android.com/training/game-controllers/controller-input + // Ref: https://developer.android.com/ndk/reference/group/input + // Ref: https://developer.android.com/training/game-controllers/controller-input int type = AInputEvent_getType(event); int source = AInputEvent_getSource(event); @@ -1290,7 +1275,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) { // Let the OS handle input to avoid app stuck. Behaviour: CMD_PAUSE -> CMD_SAVE_STATE -> CMD_STOP -> CMD_CONFIG_CHANGED -> CMD_LOST_FOCUS // Resuming Behaviour: CMD_START -> CMD_RESUME -> CMD_CONFIG_CHANGED -> CMD_CONFIG_CHANGED -> CMD_GAINED_FOCUS - // It seems like locking mobile, screen size (CMD_CONFIG_CHANGED) is affected. + // It seems like locking mobile, screen size (CMD_CONFIG_CHANGED) is affected // NOTE: AndroidManifest.xml must have // Before that change, activity was calling CMD_TERM_WINDOW and CMD_DESTROY when locking mobile, so that was not a normal behaviour return 0; @@ -1419,15 +1404,9 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1; else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0; - // Stores the previous position of touch[0] only while it's active to calculate the delta. - if (flags == AMOTION_EVENT_ACTION_MOVE) - { - CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; - } - else - { - CORE.Input.Mouse.previousPosition = CORE.Input.Touch.position[0]; - } + // Stores the previous position of touch[0] only while it's active to calculate the delta + if (flags == AMOTION_EVENT_ACTION_MOVE) CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; + else CORE.Input.Mouse.previousPosition = CORE.Input.Touch.position[0]; // Map touch[0] as mouse input for convenience CORE.Input.Mouse.currentPosition = CORE.Input.Touch.position[0]; diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 746dc8a3c..d7f76b9a8 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1220,9 +1220,9 @@ void PollInputEvents(void) // Map touch position to mouse position for convenience // WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed! - // TODO: GLFW does not support multi-touch input just yet - // https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch - // https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages + // TODO: GLFW does not support multi-touch input yet + // Ref: https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch + // Ref: https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; // Check if gamepads are ready @@ -1334,7 +1334,7 @@ void PollInputEvents(void) // Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform() // We need to provide these because GLFWallocator expects function pointers with specific signatures // Similar wrappers exist in utils.c but we cannot reuse them here due to declaration mismatch -// https://www.glfw.org/docs/latest/intro_guide.html#init_allocator +// Ref: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator static void *AllocateWrapper(size_t size, void *user) { (void)user; @@ -1592,8 +1592,8 @@ int InitPlatform(void) 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; + int creationWidth = (CORE.Window.screen.width != 0)? CORE.Window.screen.width : 1; + int creationHeight = (CORE.Window.screen.height != 0)? CORE.Window.screen.height : 1; platform.handle = glfwCreateWindow(creationWidth, creationHeight, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL); if (!platform.handle) diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 09712a706..a1b13856b 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -870,17 +870,27 @@ 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. -// 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 +// NOTE: This function is only safe to use if you control the URL given +// A user could craft a malicious string performing another action 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 { - // TODO: Open URL implementation + char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char)); +#if defined(_WIN32) + sprintf(cmd, "explorer \"%s\"", url); +#endif +#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) + sprintf(cmd, "xdg-open '%s'", url); // Alternatives: firefox, x-www-browser +#endif +#if defined(__APPLE__) + sprintf(cmd, "open '%s'", url); +#endif + int result = system(cmd); + if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created"); + RL_FREE(cmd); } } @@ -915,7 +925,7 @@ void SetMouseCursor(int cursor) RGFW_window_setMouseStandard(platform.window, cursor); } -// Get physical key name. +// Get physical key name const char *GetKeyName(int key) { TRACELOG(LOG_WARNING, "GetKeyName() unsupported on target platform"); @@ -1095,11 +1105,7 @@ void PollInputEvents(void) CORE.Input.Keyboard.currentKeyState[key] = 1; } - // TODO: Put exitKey verification outside the switch? - if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) - { - CORE.Window.shouldClose = true; - } + if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) CORE.Window.shouldClose = true; // NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int) // Check if there is space available in the queue diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index f3da04fa4..36235a6c8 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1129,7 +1129,7 @@ Vector2 GetWindowScaleDPI(void) #ifndef USING_VERSION_SDL3 // NOTE: SDL_GetWindowDisplayScale was only added on SDL3 - // see https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale + // Ref: https://wiki.libsdl.org/SDL3/SDL_GetWindowDisplayScale // TODO: Implement the window scale factor calculation manually TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform"); #else @@ -1425,8 +1425,10 @@ void PollInputEvents(void) CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); #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. + // 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 strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data); #else strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file); @@ -1458,7 +1460,7 @@ void PollInputEvents(void) // 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. 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 case SDL_WINDOWEVENT: { switch (event.window.event) @@ -1582,11 +1584,9 @@ void PollInputEvents(void) if (event.key.repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1; - // TODO: Put exitKey verification outside the switch? - if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) - { - CORE.Window.shouldClose = true; - } + // Check for registered exit key to request exit game loop on next iteration + if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) CORE.Window.shouldClose = true; + } break; case SDL_KEYUP: @@ -2080,7 +2080,7 @@ int InitPlatform(void) // Disable mouse events being interpreted as touch events // NOTE: This is wanted because there are SDL_FINGER* events available which provide unique data - // Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES + // Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); SDL_EventState(SDL_DROPFILE, SDL_ENABLE); diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 37f3fbac4..b3cbd515d 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -939,7 +939,7 @@ void SetWindowIcon(Image image) // Set icon for window void SetWindowIcons(Image *images, int count) { - // TODO. + // TODO: Implement SetWindowIcons() } void SetWindowTitle(const char *title) @@ -1246,7 +1246,11 @@ void OpenURL(const char *url) if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); else { - TRACELOG(LOG_WARNING, "OpenURL not implemented"); + char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char)); + sprintf(cmd, "explorer \"%s\"", url); + int result = system(cmd); + if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created"); + RL_FREE(cmd); } } diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index fa20b9039..881f96034 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -220,7 +220,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = { 248, 0, 0, 0, 0, 0, 0, 0, // Gamepads are mapped according to: - // https://www.kernel.org/doc/html/next/input/gamepad.html + // Ref: https://www.kernel.org/doc/html/next/input/gamepad.html // Those mappings are standardized, but that doesn't mean people follow // the standards, so this is more of an approximation [BTN_DPAD_UP] = GAMEPAD_BUTTON_LEFT_FACE_UP, @@ -637,7 +637,7 @@ static uint32_t GetOrCreateFbForBo(struct gbm_bo *bo) } // Renders a blank frame to allocate initial buffers -// TODO: WARNING: Platform layers do not include OpenGL code! +// TODO: WARNING: Platform backend should not include OpenGL code void RenderBlankFrame() { glClearColor(0, 0, 0, 1); @@ -1213,9 +1213,9 @@ int InitPlatform(void) TRACELOG(LOG_TRACE, "DISPLAY: Connector %i modes detected: %i", i, con->count_modes); TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i, - (con->connection == DRM_MODE_CONNECTED) ? "CONNECTED" : - (con->connection == DRM_MODE_DISCONNECTED) ? "DISCONNECTED" : - (con->connection == DRM_MODE_UNKNOWNCONNECTION) ? "UNKNOWN" : "OTHER"); + (con->connection == DRM_MODE_CONNECTED)? "CONNECTED" : + (con->connection == DRM_MODE_DISCONNECTED)? "DISCONNECTED" : + (con->connection == DRM_MODE_UNKNOWNCONNECTION)? "UNKNOWN" : "OTHER"); // In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected // This might be a hardware or software limitation like on Raspberry Pi Zero with composite output @@ -1298,7 +1298,7 @@ int InitPlatform(void) } const bool allowInterlaced = FLAG_IS_SET(CORE.Window.flags, FLAG_INTERLACED_HINT); - const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60; + const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60; // Try to find an exact matching mode platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced); @@ -1345,7 +1345,7 @@ int InitPlatform(void) platform.connector->modes[0].name, platform.connector->modes[0].hdisplay, platform.connector->modes[0].vdisplay, - (platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p', + (platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p', platform.connector->modes[0].vrefresh); } else @@ -1740,10 +1740,10 @@ static void InitKeyboard(void) else { // Reconfigure keyboard mode to get: - // - scancodes (K_RAW) - // - keycodes (K_MEDIUMRAW) - // - ASCII chars (K_XLATE) - // - UNICODE chars (K_UNICODE) + // - scancodes (K_RAW) + // - keycodes (K_MEDIUMRAW) + // - ASCII chars (K_XLATE) + // - UNICODE chars (K_UNICODE) ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); // ASCII chars } diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 97a4b3f29..2d2f8d1c0 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -159,7 +159,7 @@ static const char *GetCanvasId(void); bool WindowShouldClose(void) { // Emscripten Asyncify is required to run synchronous code in asynchronous JS - // REF: https://emscripten.org/docs/porting/asyncify.html + // Ref: https://emscripten.org/docs/porting/asyncify.html // WindowShouldClose() is not called on a web-ready raylib application if using emscripten_set_main_loop() // and encapsulating one frame execution on a UpdateDrawFrame() function, @@ -309,8 +309,8 @@ void ToggleBorderlessWindowed(void) if (enterBorderless) { - // NOTE: 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 + // 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() @@ -866,7 +866,6 @@ void EnableCursor(void) // Disables cursor (lock cursor) void DisableCursor(void) { - // TODO: figure out how not to hard code the canvas ID here. emscripten_request_pointerlock(GetCanvasId(), 1); // Set cursor position in the middle @@ -893,10 +892,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. -// 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 +// 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 @@ -1090,10 +1088,6 @@ void PollInputEvents(void) } CORE.Window.resizedLastFrame = false; - - // TODO: This code does not seem to do anything?? - //if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused) - //else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) --> WARNING: Where is key input reset? } //---------------------------------------------------------------------------------- @@ -1161,8 +1155,8 @@ int InitPlatform(void) } // NOTE: When asking for an OpenGL context version, most drivers provide the highest supported version - // with backward compatibility to older OpenGL versions. - // For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context. + // with backward compatibility to older OpenGL versions + // For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context // Check selection OpenGL version if (rlGetVersion() == RL_OPENGL_21) @@ -1172,10 +1166,12 @@ int InitPlatform(void) } else if (rlGetVersion() == RL_OPENGL_33) { - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint) - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint) - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above! - // Values: GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint) + 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_FORWARD_COMPAT, GLFW_FALSE); // Forward Compatibility Hint: Only 3.3 and above! // glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context } @@ -1198,7 +1194,6 @@ int InitPlatform(void) } else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context { - // TODO: It seems WebGL 2.0 context is not set despite being requested glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); @@ -1217,8 +1212,8 @@ int InitPlatform(void) // 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, 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; } @@ -1714,7 +1709,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 we detect a single touch 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 1d9edca0a..2416f0849 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2092,9 +2092,7 @@ float GetMusicTimePlayed(Music music) int framesInFirstBuffer = music.stream.buffer->isSubBufferProcessed[0]? 0 : subBufferSize; int framesInSecondBuffer = music.stream.buffer->isSubBufferProcessed[1]? 0 : subBufferSize; int framesInBuffers = framesInFirstBuffer + framesInSecondBuffer; - if ((unsigned int)framesInBuffers > music.frameCount) { - if (!music.looping) framesInBuffers = music.frameCount; - } + if (((unsigned int)framesInBuffers > music.frameCount) && !music.looping) framesInBuffers = music.frameCount; int framesSentToMix = music.stream.buffer->frameCursorPos%subBufferSize; int framesPlayed = (framesProcessed - framesInBuffers + framesSentToMix)%(int)music.frameCount; if (framesPlayed < 0) framesPlayed += music.frameCount; @@ -2125,7 +2123,7 @@ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, un if (deviceBitsPerSample > 4) deviceBitsPerSample = 4; deviceBitsPerSample *= AUDIO.System.device.playback.channels; - unsigned int subBufferSize = (AUDIO.Buffer.defaultSize == 0) ? (AUDIO.System.device.sampleRate/30*deviceBitsPerSample) : AUDIO.Buffer.defaultSize; + unsigned int subBufferSize = (AUDIO.Buffer.defaultSize == 0)? (AUDIO.System.device.sampleRate/30*deviceBitsPerSample) : AUDIO.Buffer.defaultSize; if (subBufferSize < periodSize) subBufferSize = periodSize; diff --git a/src/rcore.c b/src/rcore.c index be1c7a34b..8c5e0d3db 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -30,7 +30,7 @@ * - Windows (Win32, Win64) * CONFIGURATION: * #define SUPPORT_DEFAULT_FONT (default) -* Default font is loaded on window initialization to be available for the user to render simple text. +* Default font is loaded on window initialization to be available for the user to render simple text * NOTE: If enabled, uses external module functions to load default raylib font (module: text) * * #define SUPPORT_CAMERA_SYSTEM @@ -41,7 +41,7 @@ * Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag * * #define SUPPORT_MOUSE_GESTURES -* Mouse gestures are directly mapped like touches and processed by gestures system. +* Mouse gestures are directly mapped like touches and processed by gestures system * * #define SUPPORT_BUSY_WAIT_LOOP * Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used @@ -423,7 +423,7 @@ typedef enum AutomationEventType { } AutomationEventType; // Event type to config events flags -// TODO: Not used at the moment +// WARNING: Not used at the moment typedef enum { EVENT_INPUT_KEYBOARD = 0, EVENT_INPUT_MOUSE = 1, @@ -534,12 +534,10 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab // Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined // #if !defined(STBI_REQUIRED) // #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard" - // #endif - #endif // SUPPORT_CLIPBOARD_IMAGE // Include platform-specific submodules -#if defined(PLATFORM_DESKTOP_GLFW) +#if defined(PLATFORM_MEM) #include "platforms/rcore_desktop_glfw.c" #elif defined(PLATFORM_DESKTOP_SDL) #include "platforms/rcore_desktop_sdl.c" @@ -611,7 +609,9 @@ void InitWindow(int width, int height, const char *title) { TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); -#if defined(PLATFORM_DESKTOP_GLFW) +#if defined(PLATFORM_MEM) + TRACELOG(LOG_INFO, "Platform backend: NONE (Memory Buffer)"); +#elif defined(PLATFORM_DESKTOP_GLFW) TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)"); #elif defined(PLATFORM_DESKTOP_SDL) TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)"); @@ -1267,14 +1267,14 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode) { // After custom shader loading, we TRY to set default location names // Default shader attribute locations have been binded before linking: - // vertex position location = 0 - // vertex texcoord location = 1 - // vertex normal location = 2 - // vertex color location = 3 - // vertex tangent location = 4 - // vertex texcoord2 location = 5 - // vertex boneIds location = 6 - // vertex boneWeights location = 7 + // - vertex position location = 0 + // - vertex texcoord location = 1 + // - vertex normal location = 2 + // - vertex color location = 3 + // - vertex tangent location = 4 + // - vertex texcoord2 location = 5 + // - vertex boneIds location = 6 + // - vertex boneWeights location = 7 // NOTE: If any location is not found, loc point becomes -1 @@ -1543,8 +1543,6 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh // Calculate view matrix from camera look at (and transpose it) Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); - // TODO: Why not use Vector3Transform(Vector3 v, Matrix mat)? - // Convert world position vector to quaternion Quaternion worldPos = { position.x, position.y, position.z, 1.0f }; @@ -2484,8 +2482,6 @@ bool IsFileNameValid(const char *fileName) // Check non-glyph characters if ((unsigned char)fileName[i] < 32) { valid = false; break; } - // TODO: Check trailing periods/spaces? - // Check if filename is not all periods if (fileName[i] != '.') allPeriods = false; } @@ -3210,7 +3206,7 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName) */ // Export events as text - // TODO: Save to memory buffer and SaveFileText() + // NOTE: Save to memory buffer and SaveFileText() char *txtData = (char *)RL_CALLOC(256*list.count + 2048, sizeof(char)); // 256 characters per line plus some header int byteCount = 0; @@ -3279,7 +3275,7 @@ void PlayAutomationEvent(AutomationEvent event) #if defined(SUPPORT_AUTOMATION_EVENTS) // WARNING: When should event be played? After/before/replace PollInputEvents()? -> Up to the user! - if (!automationEventRecording) // TODO: Allow recording events while playing? + if (!automationEventRecording) { switch (event.type) { @@ -3716,7 +3712,6 @@ int GetTouchY(void) } // Get touch position XY for a touch point index (relative to screen size) -// TODO: Touch position should be scaled depending on display size and render size Vector2 GetTouchPosition(int index) { Vector2 position = { -1.0f, -1.0f }; @@ -4015,13 +4010,11 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi #if defined(SUPPORT_AUTOMATION_EVENTS) // Automation event recording +// Checking events in current frame and save them into currentEventList // NOTE: Recording is by default done at EndDrawing(), before PollInputEvents() static void RecordAutomationEvent(void) { - // Checking events in current frame and save them into currentEventList - // TODO: How important is the current frame? Could it be modified? - - if (currentEventList->count == currentEventList->capacity) return; // Security check + if (currentEventList->count == currentEventList->capacity) return; // Keyboard input events recording //------------------------------------------------------------------------------------- diff --git a/src/rlgl.h b/src/rlgl.h index 6cdf8a317..cf4156b7e 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -903,6 +903,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi // provided headers (despite being defined in official Khronos GLES2 headers) + // TODO: Avoid raylib platform-dependant code on rlgl, it should be a completely portable library #if defined(PLATFORM_DRM) typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); @@ -2921,7 +2922,7 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) batch.bufferCount = numBuffers; // Record buffer count batch.drawCounter = 1; // Reset draws counter - batch.currentDepth = -1.0f; // Reset depth value + batch.currentDepth = -1.0f; // Reset depth value //-------------------------------------------------------------------------------------------- #endif @@ -2982,7 +2983,8 @@ void rlDrawRenderBatch(rlRenderBatch *batch) // 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 --> No need to re-update GPU arrays (use a change detector flag?) + // 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 @@ -3900,7 +3902,7 @@ void rlUnloadFramebuffer(unsigned int id) // TODO: Review warning retrieving object name in WebGL // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name - // https://registry.khronos.org/webgl/specs/latest/1.0/ + // Ref: https://registry.khronos.org/webgl/specs/latest/1.0/ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); unsigned int depthIdU = (unsigned int)depthId; @@ -4427,8 +4429,6 @@ void rlSetUniform(int locIndex, const void *value, int uniformType, int count) #endif case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized"); - - // TODO: Support glUniform1uiv(), glUniform2uiv(), glUniform3uiv(), glUniform4uiv() } #endif } @@ -4469,7 +4469,7 @@ void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count) glUniformMatrix4fv(locIndex, count, true, (const float *)matrices); #elif defined(GRAPHICS_API_OPENGL_ES2) // WARNING: WebGL does not support Matrix transpose ("true" parameter) - // REF: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix + // Ref: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix glUniformMatrix4fv(locIndex, count, false, (const float *)matrices); #endif } diff --git a/src/rmodels.c b/src/rmodels.c index e3800b575..8d6802eb7 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -3845,7 +3845,6 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float // Draw a model points // WARNING: OpenGL ES 2.0 does not support point mode drawing -// TODO: gate these properly for non es 2.0 versions only void DrawModelPoints(Model model, Vector3 position, float scale, Color tint) { rlEnablePointMode(); @@ -5021,7 +5020,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou animations[a].framePoses = (Transform **)RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here TRACELOG(LOG_INFO, "IQM Anim %s", animations[a].name); - // animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? + //animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? for (unsigned int j = 0; j < iqmHeader->num_poses; j++) { @@ -5029,7 +5028,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou if (iqmHeader->num_joints > 0) memcpy(animations[a].bones[j].name, fileDataPtr + iqmHeader->ofs_text + joints[j].name, BONE_NAME_LENGTH*sizeof(char)); else - strcpy(animations[a].bones[j].name, "ANIMJOINTNAME"); // default bone name otherwise + strcpy(animations[a].bones[j].name, "ANIMJOINTNAME"); // Default bone name otherwise animations[a].bones[j].parent = poses[j].parent; } @@ -5875,8 +5874,8 @@ static Model LoadGLTF(const char *fileName) //---------------------------------------------------------------------------------------------------- // Load animation data - // REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins - // REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes + // Ref: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins + // Ref: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes // // LIMITATIONS: // - Only supports 1 armature per file, and skips loading it if there are multiple armatures diff --git a/src/rshapes.c b/src/rshapes.c index 2b5854f86..528a362d5 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -1169,9 +1169,9 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co } // Draw rectangle with rounded edges -// TODO: This function should be refactored to use RL_LINES, for consistency with other Draw*Lines() 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 DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color); } @@ -1395,7 +1395,6 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f { // Use LINES to draw the outline rlBegin(RL_LINES); - // Draw all the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop { @@ -1418,7 +1417,6 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f rlVertex2f(point[i].x, point[i].y); rlVertex2f(point[i + 1].x, point[i + 1].y); } - rlEnd(); } } diff --git a/src/rtext.c b/src/rtext.c index 009aba044..8a3961a00 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1701,7 +1701,7 @@ char *GetTextBetween(const char *text, const char *begin, const char *end) // Replace text string // REQUIRES: strstr(), strncpy(), strcpy() -// TODO: If (replacement == NULL) remove "search" text +// TODO: If (replacement == "") remove "search" text // WARNING: Allocated memory must be manually freed char *TextReplace(const char *text, const char *search, const char *replacement) { diff --git a/src/rtextures.c b/src/rtextures.c index 3e4666572..7bc5bdf4b 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -514,7 +514,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]); image.width = desc.width; image.height = desc.height; - image.format = desc.channels == 4 ? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8; + image.format = (desc.channels == 4)? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8; image.mipmaps = 1; } } @@ -4001,9 +4001,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color // [x] Consider fast path: no alpha blending required cases (src has no alpha) // [x] Consider fast path: same src/dst format with no alpha -> direct line copy // [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend() - // [ ] Support f32bit channels drawing - - // TODO: Support PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and PIXELFORMAT_UNCOMPRESSED_R1616B16A16 + // [ ] TODO: Support 16bit and 32bit (float) channels drawing Color colSrc, colDst, blend; bool blendRequired = true; @@ -4201,7 +4199,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) } /*else if (layout == CUBEMAP_LAYOUT_PANORAMA) { - // TODO: implement panorama by converting image to square faces... + // TODO: Implement panorama by converting image to square faces... // Ref: https://github.com/denivip/panorama/blob/master/panorama.cpp } */ else @@ -4227,6 +4225,7 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) } // Convert image data to 6 faces in a vertical column, that's the optimum layout for loading + // NOTE: Image formatting does not work with compressed textures faces = GenImageColor(size, size*6, MAGENTA); ImageFormat(&faces, image.format); @@ -4239,8 +4238,6 @@ TextureCubemap LoadTextureCubemap(Image image, int layout) } #endif - // NOTE: Image formatting does not work with compressed textures - for (int i = 0; i < 6; i++) ImageDraw(&faces, mipmapped, faceRecs[i], (Rectangle){ 0, (float)size*i, (float)size, (float)size }, WHITE); UnloadImage(mipmapped); @@ -4309,13 +4306,11 @@ bool IsTextureValid(Texture2D texture) { bool result = false; - // TODO: Validate maximum texture size supported by GPU - if ((texture.id > 0) && // Validate OpenGL id (texture uplaoded to GPU) (texture.width > 0) && // Validate texture width (texture.height > 0) && // Validate texture height (texture.format > 0) && // Validate texture pixel format - (texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level) + (texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level) return result; } @@ -5412,7 +5407,7 @@ int GetPixelDataSize(int width, int height, int format) // Module Internal Functions Definition //---------------------------------------------------------------------------------- // Convert half-float (stored as unsigned short) to float -// REF: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 +// Ref: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 static float HalfToFloat(unsigned short x) { float result = 0.0f; From aaa893f668a9b7386e9adb3c1985024ce60fefd6 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 23 Nov 2025 22:58:10 +0100 Subject: [PATCH 179/189] Update rcore.c --- src/rcore.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 8c5e0d3db..85adf134f 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -609,9 +609,7 @@ void InitWindow(int width, int height, const char *title) { TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); -#if defined(PLATFORM_MEM) - TRACELOG(LOG_INFO, "Platform backend: NONE (Memory Buffer)"); -#elif defined(PLATFORM_DESKTOP_GLFW) +#if defined(PLATFORM_DESKTOP_GLFW) TRACELOG(LOG_INFO, "Platform backend: DESKTOP (GLFW)"); #elif defined(PLATFORM_DESKTOP_SDL) TRACELOG(LOG_INFO, "Platform backend: DESKTOP (SDL)"); From 17dc2bb474228da4375b7cddab24682e79a8201e Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 23 Nov 2025 22:58:15 +0100 Subject: [PATCH 180/189] Update rcore.c --- src/rcore.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 85adf134f..377dd4eb5 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -530,10 +530,6 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab #if (!defined(SUPPORT_FILEFORMAT_PNG) || !defined(SUPPORT_FILEFORMAT_JPG)) && !defined(_WIN32) #pragma message ("WARNING: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG") #endif - - // Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined - // #if !defined(STBI_REQUIRED) - // #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard" #endif // SUPPORT_CLIPBOARD_IMAGE // Include platform-specific submodules From 7e3d6cbfa880ac97638b8ef06235bd9a9022fdc9 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 23 Nov 2025 23:16:32 +0100 Subject: [PATCH 181/189] 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 377dd4eb5..aae5daa09 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -533,7 +533,7 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab #endif // SUPPORT_CLIPBOARD_IMAGE // Include platform-specific submodules -#if defined(PLATFORM_MEM) +#if defined(PLATFORM_DESKTOP_GLFW) #include "platforms/rcore_desktop_glfw.c" #elif defined(PLATFORM_DESKTOP_SDL) #include "platforms/rcore_desktop_sdl.c" From bd36610f9167ec9288d91d303093eaec55b55ae4 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 24 Nov 2025 15:37:28 +0100 Subject: [PATCH 182/189] Some formatting --- src/config.h | 2 +- src/external/rlsw.h | 14 +++--- src/platforms/rcore_desktop_glfw.c | 25 ++++++----- src/platforms/rcore_desktop_win32.c | 10 ++--- src/raylib.h | 8 ++-- src/rcore.c | 66 ++++++++++++++++++----------- src/rmodels.c | 2 +- src/rtextures.c | 4 +- src/utils.c | 2 +- 9 files changed, 74 insertions(+), 59 deletions(-) diff --git a/src/config.h b/src/config.h index 89b32d0fe..b749f8952 100644 --- a/src/config.h +++ b/src/config.h @@ -75,7 +75,7 @@ #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, I prefer to let the user manage them +// TODO: Those defines should probably be removed from here, letting the user manage them #if defined(SUPPORT_CLIPBOARD_IMAGE) #ifndef SUPPORT_MODULE_RTEXTURES #define SUPPORT_MODULE_RTEXTURES 1 diff --git a/src/external/rlsw.h b/src/external/rlsw.h index d78da3ff8..025216e39 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -3668,9 +3668,9 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, x = sw_clampi(x, 0, w); y = sw_clampi(y, 0, h); - if (x >= w || y >= h) return; + if ((x >= w) || (y >= h)) return; - if (x == 0 && y == 0 && w == RLSW.framebuffer.width && h == RLSW.framebuffer.height) + if ((x == 0) && (y == 0) && (w == RLSW.framebuffer.width) && (h == RLSW.framebuffer.height)) { #if SW_COLOR_BUFFER_BITS == 32 if (pFormat == SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) @@ -3695,7 +3695,7 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8: sw_framebuffer_copy_to_R8G8B8(x, y, w, h, (uint8_t *)pixels); break; case SW_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: sw_framebuffer_copy_to_R5G5B5A1(x, y, w, h, (uint16_t *)pixels); break; case SW_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: sw_framebuffer_copy_to_R4G4B4A4(x, y, w, h, (uint16_t *)pixels); break; - case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_copy_to_R8G8B8A8(x, y, w, h, (uint8_t *)pixels); break; + //case SW_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: sw_framebuffer_copy_to_R8G8B8A8(x, y, w, h, (uint8_t *)pixels); break; // Below: not implemented case SW_PIXELFORMAT_UNCOMPRESSED_R32: case SW_PIXELFORMAT_UNCOMPRESSED_R32G32B32: @@ -3703,9 +3703,7 @@ void swCopyFramebuffer(int x, int y, int w, int h, SWformat format, SWtype type, case SW_PIXELFORMAT_UNCOMPRESSED_R16: case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16: case SW_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: - default: - RLSW.errCode = SW_INVALID_ENUM; - break; + default: RLSW.errCode = SW_INVALID_ENUM; break; } } @@ -4330,7 +4328,7 @@ void swVertex2f(float x, float y) void swVertex2fv(const float *v) { const float v4[4] = { v[0], v[1], 0.0f, 1.0f }; - sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); + sw_immediate_push_vertex(v4, RLSW.current.color, RLSW.current.texcoord); } void swVertex3i(int x, int y, int z) @@ -4348,7 +4346,7 @@ void swVertex3f(float x, float y, float z) void swVertex3fv(const float *v) { const float v4[4] = { v[0], v[1], v[2], 1.0f }; - sw_immediate_push_vertex(v, RLSW.current.color, RLSW.current.texcoord); + sw_immediate_push_vertex(v4, RLSW.current.color, RLSW.current.texcoord); } void swVertex4i(int x, int y, int z, int w) diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index d7f76b9a8..a56e1c683 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -78,28 +78,27 @@ #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) #include // Required for: timespec, nanosleep(), select() - POSIX -#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) + #if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) // Set appropriate expose macros based on available backends - #if defined(_GLFW_X11) - #define GLFW_EXPOSE_NATIVE_X11 - #define Font X11Font // Hack to fix 'Font' name collision + #if defined(_GLFW_X11) + #define GLFW_EXPOSE_NATIVE_X11 + #define Font X11Font // Hack to fix 'Font' name collision // The definition and references to the X11 Font type will be replaced by 'X11Font' // Works as long as the current file consistently references any X11 Font as X11Font // Since it is never referenced (as of writing), this does not pose an issue - #endif + #endif - #if defined(_GLFW_WAYLAND) - #define GLFW_EXPOSE_NATIVE_WAYLAND - #endif + #if defined(_GLFW_WAYLAND) + #define GLFW_EXPOSE_NATIVE_WAYLAND + #endif - #include "GLFW/glfw3native.h" // Include native header only once, regardless of how many backends are defined + #include "GLFW/glfw3native.h" // Include native header only once, regardless of how many backends are defined // Required for: glfwGetX11Window() and glfwGetWaylandWindow() - - #if defined(_GLFW_X11) // Clean up X11-specific hacks - #undef Font // Revert hack and allow normal raylib Font usage + #if defined(_GLFW_X11) // Clean up X11-specific hacks + #undef Font // Revert hack and allow normal raylib Font usage + #endif #endif #endif -#endif #if defined(__APPLE__) #include // Required for: usleep() diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index b3cbd515d..8a4050332 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -262,9 +262,9 @@ static bool DecoratedFromStyle(DWORD style) // Get window style from required flags static DWORD MakeWindowStyle(unsigned flags) { - // We don't need this since we don't have any child windows, but I guess - // it improves efficiency, plus, windows adds this flag automatically anyway - // so it keeps our flags in sync with the OS + // Flag is not needed because there are no child windows, + // 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; style |= (flags & FLAG_WINDOW_HIDDEN)? 0 : WS_VISIBLE; @@ -1230,7 +1230,7 @@ void SwapScreenBuffer(void) // Get elapsed time measure in seconds double GetTime(void) { - LARGE_INTEGER now; + LARGE_INTEGER now = 0; QueryPerformanceCounter(&now); return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; } @@ -1987,7 +1987,7 @@ static void HandleKey(WPARAM wparam, LPARAM lparam, char state) { CORE.Input.Keyboard.currentKeyState[key] = state; - if ((key == KEY_ESCAPE) && (state == 1)) CORE.Window.shouldClose = 1; + if ((key == KEY_ESCAPE) && (state == 1)) CORE.Window.shouldClose = true; } else TRACELOG(LOG_WARNING, "INPUT: Unknown (or currently unhandled) virtual keycode %d (0x%x)", wparam, wparam); diff --git a/src/raylib.h b/src/raylib.h index 67279753a..ece2e6aab 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -99,13 +99,13 @@ #define __declspec(x) __attribute__((x)) #endif #if 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(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 #else #if defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib) + #define RLAPI __attribute__((visibility("default"))) // Building as a Unix shared library (.so/.dylib) #endif #endif @@ -157,7 +157,7 @@ #error "C++11 or later is required. Add -std=c++11" #endif -// NOTE: We set some defines with some data types declared by raylib +// NOTE: Set some defines with some data types declared by raylib // Other modules (raymath, rlgl) also require some of those types, so, // to be able to use those other modules as standalone (not depending on raylib) // this defines are very useful for internal check and avoid type (re)definitions diff --git a/src/rcore.c b/src/rcore.c index aae5daa09..61916284c 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -28,6 +28,8 @@ * - 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 @@ -92,12 +94,12 @@ //---------------------------------------------------------------------------------- #if (defined(__linux__) || defined(PLATFORM_WEB) || defined(PLATFORM_WEB_RGFW)) && (_XOPEN_SOURCE < 500) #undef _XOPEN_SOURCE - #define _XOPEN_SOURCE 500 // Required for: readlink if compiled with c99 without gnu ext. + #define _XOPEN_SOURCE 500 // Required for: readlink if compiled with c99 without GNU extensions #endif #if (defined(__linux__) || defined(PLATFORM_WEB) || defined(PLATFORM_WEB_RGFW)) && (_POSIX_C_SOURCE < 199309L) #undef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext. + #define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without GNU extensions #endif #include "raylib.h" // Declares module functions @@ -115,6 +117,9 @@ #include // Required for: time() [Used in InitTimer()] #include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()] +#if defined(PLATFORM_MEMORY) + #define SW_GL_FRAMEBUFFER_COPY_BGRA false +#endif #define RLGL_IMPLEMENTATION #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 @@ -155,18 +160,18 @@ #define MAX_PATH 260 #endif -struct HINSTANCE__; -#if defined(__cplusplus) -extern "C" { -#endif -__declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(struct HINSTANCE__ *hModule, char *lpFilename, unsigned long nSize); -__declspec(dllimport) unsigned long __stdcall GetModuleFileNameW(struct HINSTANCE__ *hModule, wchar_t *lpFilename, unsigned long nSize); -__declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); -__declspec(dllimport) unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod); -__declspec(dllimport) unsigned int __stdcall timeEndPeriod(unsigned int uPeriod); -#if defined(__cplusplus) -} -#endif + struct HINSTANCE__; + #if defined(__cplusplus) + extern "C" { + #endif + __declspec(dllimport) unsigned long __stdcall GetModuleFileNameA(struct HINSTANCE__ *hModule, char *lpFilename, unsigned long nSize); + __declspec(dllimport) unsigned long __stdcall GetModuleFileNameW(struct HINSTANCE__ *hModule, wchar_t *lpFilename, unsigned long nSize); + __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); + __declspec(dllimport) unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod); + __declspec(dllimport) unsigned int __stdcall timeEndPeriod(unsigned int uPeriod); + #if defined(__cplusplus) + } + #endif #elif defined(__linux__) #include #elif defined(__FreeBSD__) @@ -314,7 +319,8 @@ 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 prev vs cur key state, we need to handle key repeats specially + // 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 int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue @@ -547,6 +553,8 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab #include "platforms/rcore_drm.c" #elif defined(PLATFORM_ANDROID) #include "platforms/rcore_android.c" +#elif defined(PLATFORM_MEMORY) + #include "platforms/rcore_memory.c" #else // TODO: Include your custom platform backend! // i.e software rendering backend or console backend! @@ -621,6 +629,8 @@ void InitWindow(int width, int height, const char *title) TRACELOG(LOG_INFO, "Platform backend: NATIVE DRM"); #elif defined(PLATFORM_ANDROID) TRACELOG(LOG_INFO, "Platform backend: ANDROID"); +#elif defined(PLATFORM_MEMORY) + TRACELOG(LOG_INFO, "Platform backend: MEMORY (No OS)"); #else // TODO: Include your custom platform backend! // i.e software rendering backend or console backend! @@ -2233,13 +2243,15 @@ const char *GetApplicationDirectory(void) #if defined(_WIN32) int len = 0; -#if defined(UNICODE) + + #if defined(UNICODE) unsigned short widePath[MAX_PATH]; len = GetModuleFileNameW(NULL, (wchar_t *)widePath, MAX_PATH); len = WideCharToMultiByte(0, 0, (wchar_t *)widePath, len, appDir, MAX_PATH, NULL, NULL); -#else + #else len = GetModuleFileNameA(NULL, appDir, MAX_PATH); -#endif + #endif + if (len > 0) { for (int i = len; i >= 0; --i) @@ -2256,8 +2268,9 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '\\'; } - + #elif defined(__linux__) + unsigned int size = sizeof(appDir); ssize_t len = readlink("/proc/self/exe", appDir, size); @@ -2277,7 +2290,9 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '/'; } + #elif defined(__APPLE__) + uint32_t size = sizeof(appDir); if (_NSGetExecutablePath(appDir, &size) == 0) @@ -2297,8 +2312,11 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '/'; } + #elif defined(__FreeBSD__) - size_t size = sizeof(appDir); + + size_t size = sizeof(appD + ir); int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; if (sysctl(mib, 4, appDir, &size, NULL, 0) == 0) @@ -2318,7 +2336,6 @@ const char *GetApplicationDirectory(void) appDir[0] = '.'; appDir[1] = '/'; } - #endif return appDir; @@ -3748,20 +3765,20 @@ void InitTimer(void) // High resolutions can also prevent the CPU power management system from entering power-saving modes // Setting a higher resolution does not improve the accuracy of the high-resolution performance counter #if defined(_WIN32) && defined(SUPPORT_WINMM_HIGHRES_TIMER) && !defined(SUPPORT_BUSY_WAIT_LOOP) && !defined(PLATFORM_DESKTOP_SDL) - timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms) + timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms) #endif #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__) struct timespec now = { 0 }; - if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success + if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success { CORE.Time.base = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; } else TRACELOG(LOG_WARNING, "TIMER: Hi-resolution timer not available"); #endif - CORE.Time.previous = GetTime(); // Get time as double + CORE.Time.previous = GetTime(); // Get time as double } // Set viewport for a provided width and height @@ -3887,6 +3904,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const 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 diff --git a/src/rmodels.c b/src/rmodels.c index 8d6802eb7..fad6ae78b 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -5018,7 +5018,7 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou animations[a].boneCount = iqmHeader->num_poses; animations[a].bones = (BoneInfo *)RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo)); animations[a].framePoses = (Transform **)RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); - memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here + memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); TRACELOG(LOG_INFO, "IQM Anim %s", animations[a].name); //animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? diff --git a/src/rtextures.c b/src/rtextures.c index 7bc5bdf4b..17065822a 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -1099,7 +1099,7 @@ Image GenImageCellular(int width, int height, int tileSize) } } - // I made this up, but it seems to give good results at all tile sizes + // This approach seems to give good results at all tile sizes int intensity = (int)(minDistance*256.0f/tileSize); if (intensity > 255) intensity = 255; @@ -4600,7 +4600,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 // NOTE: Vertex position can be transformed using matrices // but the process is way more costly than just calculating // the vertex positions manually, like done above - // I leave here the old implementation for educational purposes, + // Old implementation is left here for educational purposes, // just in case someone wants to do some performance test /* rlSetTexture(texture.id); diff --git a/src/utils.c b/src/utils.c index 123c7b0b9..892f96cf4 100644 --- a/src/utils.c +++ b/src/utils.c @@ -451,7 +451,7 @@ FILE *android_fopen(const char *fileName, const char *mode) { if (mode[0] == 'w') { - // fopen() is mapped to android_fopen() that only grants read access to + // 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 From fc8049a039b5c4b2bcf3a1bbc77e3f8527638e9f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:37:49 +0000 Subject: [PATCH 183/189] rlparser: update raylib_api.* by CI --- tools/rlparser/output/raylib_api.json | 2 +- tools/rlparser/output/raylib_api.lua | 2 +- tools/rlparser/output/raylib_api.txt | 2 +- tools/rlparser/output/raylib_api.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index e5815854c..b3d02a928 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -40,7 +40,7 @@ "name": "RLAPI", "type": "UNKNOWN", "value": "__declspec(dllexport)", - "description": "We are building the library as a Win32 shared library (.dll)" + "description": "Building the library as a Win32 shared library (.dll)" }, { "name": "PI", diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index eb3e6567b..e680a5acf 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -40,7 +40,7 @@ return { name = "RLAPI", type = "UNKNOWN", value = "__declspec(dllexport)", - description = "We are building the library as a Win32 shared library (.dll)" + description = "Building the library as a Win32 shared library (.dll)" }, { name = "PI", diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index 76d223d97..e2edb8f3f 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -35,7 +35,7 @@ Define 007: RLAPI Name: RLAPI Type: UNKNOWN Value: __declspec(dllexport) - Description: We are building the library as a Win32 shared library (.dll) + Description: Building the library as a Win32 shared library (.dll) Define 008: PI Name: PI Type: FLOAT diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index 512c4c6df..3d1892c7c 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -7,7 +7,7 @@ - + From 47a8b554bce936596e910aaeecf3d524c83ba97c Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 24 Nov 2025 15:38:58 +0100 Subject: [PATCH 184/189] **NEW**: `PLATFORM_MEMORY` backend New platform backend for software rendering directly on RAM memory buffer --- projects/VS2022/raylib/raylib.vcxproj | 14 + projects/VS2022/raylib/raylib.vcxproj.filters | 3 + src/platforms/rcore_memory.c | 595 ++++++++++++++++++ src/rlgl.h | 9 +- 4 files changed, 617 insertions(+), 4 deletions(-) create mode 100644 src/platforms/rcore_memory.c diff --git a/projects/VS2022/raylib/raylib.vcxproj b/projects/VS2022/raylib/raylib.vcxproj index cf254761e..3a7082d77 100644 --- a/projects/VS2022/raylib/raylib.vcxproj +++ b/projects/VS2022/raylib/raylib.vcxproj @@ -533,6 +533,20 @@ true true + + true + true + true + true + true + true + true + true + true + true + true + true + true true diff --git a/projects/VS2022/raylib/raylib.vcxproj.filters b/projects/VS2022/raylib/raylib.vcxproj.filters index 4588f0521..33030fc9c 100644 --- a/projects/VS2022/raylib/raylib.vcxproj.filters +++ b/projects/VS2022/raylib/raylib.vcxproj.filters @@ -49,6 +49,9 @@ Source Files\Platform Files + + Source Files\Platform Files + diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c new file mode 100644 index 000000000..e49159a85 --- /dev/null +++ b/src/platforms/rcore_memory.c @@ -0,0 +1,595 @@ +/********************************************************************************************** +* +* rcore_memory - Functions to manage window, graphics device and inputs +* +* PLATFORM: MEMORY (No OS) +* - Memory framebuffer output (no os) +* +* LIMITATIONS: +* - Software renderer (rlsw) +* - No input system +* +* POSSIBLE IMPROVEMENTS: +* - 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- +* +* DEPENDENCIES: +* - rlsw: Software renderer +* - 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. +* +**********************************************************************************************/ + +#if defined(_WIN32) + #include // Required for: kbhit() +#else + // Provide kbhit() function in non-Windows platforms + #include + #include + #include +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Platform-specific required data for timming (Win32) +#if defined(_WIN32) +typedef struct _LARGE_INTEGER { int64_t QuadPart; } LARGE_INTEGER; +__declspec(dllimport) int __stdcall QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount); +__declspec(dllimport) int __stdcall QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency); +#endif + +typedef struct { + unsigned int *pixels; // Pointer to pixel data buffer (RGBA8888 format) +#if defined(_WIN32) + LARGE_INTEGER timerFrequency; +#endif +} PlatformData; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +extern CoreData CORE; // Global CORE state context + +static PlatformData platform = { 0 }; // Platform specific data + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +int InitPlatform(void); // Initialize platform (graphics, inputs and more) +bool InitGraphicsDevice(void); // Initialize graphics device + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +// NOTE: Functions declaration is provided by raylib.h + +//---------------------------------------------------------------------------------- +// Module Internal Functions Declaration +//---------------------------------------------------------------------------------- +#if !defined(_WIN32) +static int kbhit(void); // Check if a key has been pressed +static char getch(void) { return getchar(); } // Get pressed character +#endif + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Window and Graphics Device +//---------------------------------------------------------------------------------- + +// Check if application should close +bool WindowShouldClose(void) +{ + if (CORE.Window.ready) return CORE.Window.shouldClose; + else return true; +} + +// Toggle fullscreen mode +void ToggleFullscreen(void) +{ + TRACELOG(LOG_WARNING, "ToggleFullscreen() not available on target platform"); +} + +// Toggle borderless windowed mode +void ToggleBorderlessWindowed(void) +{ + TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform"); +} + +// Set window state: maximized, if resizable +void MaximizeWindow(void) +{ + TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform"); +} + +// 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) +{ + TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform"); +} + +// Set window configuration state using flags +void SetWindowState(unsigned int flags) +{ + TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform"); +} + +// Clear window configuration state flags +void ClearWindowState(unsigned int flags) +{ + TRACELOG(LOG_WARNING, "ClearWindowState() 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 +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; +} + +// 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; +} + +// Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) +void SetWindowMaxSize(int width, int height) +{ + CORE.Window.screenMax.width = width; + CORE.Window.screenMax.height = height; +} + +// Set window dimensions +void SetWindowSize(int width, int height) +{ + TRACELOG(LOG_WARNING, "SetWindowSize() not available on target platform"); +} + +// Set window opacity, value opacity is between 0.0 and 1.0 +void SetWindowOpacity(float opacity) +{ + TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform"); +} + +// 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) +{ + TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform"); + return 0; +} + +// Get selected monitor height (currently used by monitor) +int GetMonitorHeight(int monitor) +{ + TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform"); + return 0; +} + +// 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) +{ + TRACELOG(LOG_WARNING, "GetWindowPosition() not implemented on target platform"); + return (Vector2){ 0, 0 }; +} + +// Get window scale DPI factor for current monitor +Vector2 GetWindowScaleDPI(void) +{ + TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform"); + return (Vector2){ 1.0f, 1.0f }; +} + +// Set clipboard text content +void SetClipboardText(const char *text) +{ + TRACELOG(LOG_WARNING, "SetClipboardText() not implemented on target platform"); +} + +// Get clipboard text content +// NOTE: returned string is allocated and freed by GLFW +const char *GetClipboardText(void) +{ + TRACELOG(LOG_WARNING, "GetClipboardText() not implemented on target platform"); + return NULL; +} + +// Get clipboard image +Image GetClipboardImage(void) +{ + Image image = { 0 }; + + TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); + + return image; +} + +// Show mouse cursor +void ShowCursor(void) +{ + CORE.Input.Mouse.cursorHidden = false; +} + +// Hides mouse cursor +void HideCursor(void) +{ + CORE.Input.Mouse.cursorHidden = true; +} + +// Enables cursor (unlock cursor) +void EnableCursor(void) +{ + // Set cursor position in the middle + SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + + CORE.Input.Mouse.cursorHidden = false; +} + +// Disables cursor (lock cursor) +void DisableCursor(void) +{ + // Set cursor position in the middle + SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); + + CORE.Input.Mouse.cursorHidden = true; +} + +// Swap back buffer with front buffer (screen drawing) +void SwapScreenBuffer(void) +{ + // Update framebuffer + rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, platform.pixels); +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Misc +//---------------------------------------------------------------------------------- + +// Get elapsed time measure in seconds since InitTimer() +double GetTime(void) +{ + double time = 0.0; +#if defined(_WIN32) + LARGE_INTEGER now = { 0 }; + QueryPerformanceCounter(&now); + return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__) + 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() +#endif + 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. +// Ref: https://github.com/raysan5/raylib/issues/686 +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 + { + char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char)); + sprintf(cmd, "explorer \"%s\"", url); + int result = system(cmd); + if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created"); + RL_FREE(cmd); + } +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition: Inputs +//---------------------------------------------------------------------------------- + +// Set internal gamepad mappings +int SetGamepadMappings(const char *mappings) +{ + TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform"); + return 0; +} + +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) +{ + TRACELOG(LOG_WARNING, "SetGamepadVibration() not implemented on target platform"); +} + +// Set mouse position XY +void SetMousePosition(int x, int y) +{ + CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; + CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; +} + +// Set mouse cursor +void SetMouseCursor(int cursor) +{ + TRACELOG(LOG_WARNING, "SetMouseCursor() not implemented on target platform"); +} + +// Get physical key name. +const char *GetKeyName(int 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 key repeats + for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + + // Reset last gamepad button/axis registered state + CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN + //CORE.Input.Gamepad.axisCount = 0; + + // 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 }; + + // Register previous keys states + // NOTE: Android supports up to 260 keys + for (int i = 0; i < 260; i++) + { + CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; + CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; + } + + // TODO: Poll input events for current platform + + // Check for key pressed to exit + if (kbhit()) + { + int key = getch(); + if (key == 27) CORE.Window.shouldClose = true; // KEY_SCAPE + } +} + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- + +// Initialize platform: graphics, inputs and more +int InitPlatform(void) +{ + // Memory framebuffer can only work with software renderer + if (rlGetVersion() != RL_OPENGL_11_SOFTWARE) + { + TRACELOG(LOG_WARNING, "DISPLAY: Memory platform requires software renderer (GRAPHICS_API_OPENGL_11_SOFTWARE)"); + TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); + return -1; + } + else + { + // Load memory framebuffer with desired screen size + platform.pixels = (unsigned int *)RL_CALLOC(CORE.Window.screen.width*CORE.Window.screen.height, sizeof(int)); + } + //---------------------------------------------------------------------------- + + // If everything work as expected, we can 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; + CORE.Window.currentFbo.height = CORE.Window.render.height; + + 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); + + CORE.Window.ready = true; + + // TODO: Load OpenGL extensions + // NOTE: GL procedures address loader is required to load extensions + //---------------------------------------------------------------------------- + // ... + //---------------------------------------------------------------------------- + + // TODO: Initialize input events system + // It could imply keyboard, mouse, gamepad, touch... + // Depending on the platform libraries/SDK it could use a callback mechanism + // For system events and inputs evens polling on a per-frame basis, use PollInputEvents() + //---------------------------------------------------------------------------- + // ... + //---------------------------------------------------------------------------- + + // Initialize timing system + //---------------------------------------------------------------------------- +#if defined(_WIN32) + LARGE_INTEGER time = { 0 }; + QueryPerformanceCounter(&time); + QueryPerformanceFrequency(&platform.timerFrequency); + CORE.Time.base = time.QuadPart; +#endif + InitTimer(); + //---------------------------------------------------------------------------- + + // Initialize storage system + //---------------------------------------------------------------------------- + CORE.Storage.basePath = GetWorkingDirectory(); + //---------------------------------------------------------------------------- + + TRACELOG(LOG_INFO, "PLATFORM: MEMORY: Initialized successfully"); + + return 0; +} + +// Close platform +void ClosePlatform(void) +{ + RL_FREE(platform.pixels); +} + +//---------------------------------------------------------------------------------- +// Module Internal Functions Definition +//---------------------------------------------------------------------------------- +#if !defined(_WIN32) +// Check if a key has been pressed +static int kbhit(void) +{ + struct termios oldt = { 0 }; + struct termios newt = { 0 }; + int ch = 0; + int oldf = 0; + + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + oldf = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); + + ch = getchar(); + + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + fcntl(STDIN_FILENO, F_SETFL, oldf); + + if (ch != EOF) + { + ungetc(ch, stdin); + return 1; + } + + return 0; +} +#endif + +// EOF diff --git a/src/rlgl.h b/src/rlgl.h index cf4156b7e..6884ad183 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -776,10 +776,9 @@ RLAPI unsigned int rlLoadFramebuffer(void); // Loa RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU -#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) +// WARNING: Copy and resize framebuffer functionality only defined for software backend RLAPI void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pixels); // Copy framebuffer pixel data to internal buffer RLAPI void rlResizeFramebuffer(int width, int height); // Resize internal framebuffer -#endif // Shaders management RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings @@ -3750,21 +3749,23 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format) return pixels; } -#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) // Copy framebuffer pixel data to internal buffer void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pixels) { +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) unsigned int glInternalFormat, glFormat, glType; rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); // Get OpenGL texture format swCopyFramebuffer(x, y, width, height, glFormat, glType, pixels); +#endif } // Resize internal framebuffer void rlResizeFramebuffer(int width, int height) { +#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) swResizeFramebuffer(width, height); -} #endif +} // Read screen pixel data (color buffer) unsigned char *rlReadScreenPixels(int width, int height) From 80ed6eadb828fcb13d936c602acfb782d0b9df3f Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 25 Nov 2025 12:15:14 +0100 Subject: [PATCH 185/189] REXM: RENAME: `audio_fft_spectrum_visualizer` -> `audio_spectrum_visualizer` --- examples/Makefile | 2 +- examples/Makefile.Web | 11 ++++++----- examples/README.md | 4 ++-- ...rum_visualizer.c => audio_spectrum_visualizer.c} | 4 ++-- ...visualizer.png => audio_spectrum_visualizer.png} | Bin examples/examples_list.txt | 2 +- ...er.vcxproj => audio_spectrum_visualizer.vcxproj} | 6 +++--- projects/VS2022/raylib.sln | 2 +- tools/rexm/reports/examples_validation.md | 2 +- 9 files changed, 17 insertions(+), 16 deletions(-) rename examples/audio/{audio_fft_spectrum_visualizer.c => audio_spectrum_visualizer.c} (99%) rename examples/audio/{audio_fft_spectrum_visualizer.png => audio_spectrum_visualizer.png} (100%) rename projects/VS2022/examples/{audio_fft_spectrum_visualizer.vcxproj => audio_spectrum_visualizer.vcxproj} (99%) diff --git a/examples/Makefile b/examples/Makefile index b2feec0db..72df8571a 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -708,7 +708,6 @@ SHADERS = \ shaders/shaders_vertex_displacement AUDIO = \ - audio/audio_fft_spectrum_visualizer \ audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ @@ -716,6 +715,7 @@ AUDIO = \ audio/audio_sound_loading \ audio/audio_sound_multi \ audio/audio_sound_positioning \ + audio/audio_spectrum_visualizer \ audio/audio_stream_effects OTHERS = \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 35024cbd5..431b2cad9 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -696,7 +696,6 @@ SHADERS = \ shaders/shaders_vertex_displacement AUDIO = \ - audio/audio_fft_spectrum_visualizer \ audio/audio_mixed_processor \ audio/audio_module_playing \ audio/audio_music_stream \ @@ -704,6 +703,7 @@ AUDIO = \ audio/audio_sound_loading \ audio/audio_sound_multi \ audio/audio_sound_positioning \ + audio/audio_spectrum_visualizer \ audio/audio_stream_effects # Default target entry @@ -1471,10 +1471,6 @@ shaders/shaders_vertex_displacement: shaders/shaders_vertex_displacement.c --preload-file shaders/resources/shaders/glsl100/vertex_displacement.fs@resources/shaders/glsl100/vertex_displacement.fs # Compile AUDIO examples -audio/audio_fft_spectrum_visualizer: audio/audio_fft_spectrum_visualizer.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ - --preload-file audio/resources/country.mp3@resources/country.mp3 - audio/audio_mixed_processor: audio/audio_mixed_processor.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file audio/resources/country.mp3@resources/country.mp3 \ @@ -1503,6 +1499,11 @@ audio/audio_sound_positioning: audio/audio_sound_positioning.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file audio/resources/coin.wav@resources/coin.wav +audio/audio_spectrum_visualizer: audio/audio_spectrum_visualizer.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ + --preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \ + --preload-file audio/resources/country.mp3@resources/country.mp3 + audio/audio_stream_effects: audio/audio_stream_effects.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ --preload-file audio/resources/country.mp3@resources/country.mp3 diff --git a/examples/README.md b/examples/README.md index 41c3c7c01..77b6ff37e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -260,7 +260,7 @@ Examples using raylib audio functionality, including sound/music loading and pla | [audio_stream_effects](audio/audio_stream_effects.c) | audio_stream_effects | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) | | [audio_sound_multi](audio/audio_sound_multi.c) | audio_sound_multi | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) | | [audio_sound_positioning](audio/audio_sound_positioning.c) | audio_sound_positioning | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) | -| [audio_fft_spectrum_visualizer](audio/audio_fft_spectrum_visualizer.c) | audio_fft_spectrum_visualizer | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) | +| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | audio_spectrum_visualizer | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) | ### category: others [6] @@ -276,4 +276,4 @@ Examples showing raylib misc functionality that does not fit in other categories | [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! +Here is an [examples template](examples_template.c) with instructions to start with! diff --git a/examples/audio/audio_fft_spectrum_visualizer.c b/examples/audio/audio_spectrum_visualizer.c similarity index 99% rename from examples/audio/audio_fft_spectrum_visualizer.c rename to examples/audio/audio_spectrum_visualizer.c index cad683462..f5334c9cc 100644 --- a/examples/audio/audio_fft_spectrum_visualizer.c +++ b/examples/audio/audio_spectrum_visualizer.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [audio] example - fft spectrum visualizer +* raylib [audio] example - spectrum visualizer * * Example complexity rating: [★★★☆] 3/4 * @@ -78,7 +78,7 @@ int main(void) const int screenWidth = 800; const int screenHeight = 450; - InitWindow(screenWidth, screenHeight, "raylib [audio] example - fft spectrum visualizer"); + InitWindow(screenWidth, screenHeight, "raylib [audio] example - spectrum visualizer"); Image fftImage = GenImageColor(BUFFER_SIZE, TEXTURE_HEIGHT, WHITE); Texture2D fftTexture = LoadTextureFromImage(fftImage); diff --git a/examples/audio/audio_fft_spectrum_visualizer.png b/examples/audio/audio_spectrum_visualizer.png similarity index 100% rename from examples/audio/audio_fft_spectrum_visualizer.png rename to examples/audio/audio_spectrum_visualizer.png diff --git a/examples/examples_list.txt b/examples/examples_list.txt index b6223e09a..605ddf263 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -200,7 +200,7 @@ audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5 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_fft_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4 +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 diff --git a/projects/VS2022/examples/audio_fft_spectrum_visualizer.vcxproj b/projects/VS2022/examples/audio_spectrum_visualizer.vcxproj similarity index 99% rename from projects/VS2022/examples/audio_fft_spectrum_visualizer.vcxproj rename to projects/VS2022/examples/audio_spectrum_visualizer.vcxproj index d7c6d8d3f..f8e5005fd 100644 --- a/projects/VS2022/examples/audio_fft_spectrum_visualizer.vcxproj +++ b/projects/VS2022/examples/audio_spectrum_visualizer.vcxproj @@ -53,9 +53,9 @@ {2B3CED91-973F-4936-9DD4-CC8B1C8ACC68} Win32Proj - audio_fft_spectrum_visualizer + audio_spectrum_visualizer 10.0 - audio_fft_spectrum_visualizer + audio_spectrum_visualizer @@ -553,7 +553,7 @@ - + diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 4af8d0539..07068d34c 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -411,7 +411,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_compute_hash", "exampl 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_fft_spectrum_visualizer", "examples\audio_fft_spectrum_visualizer.vcxproj", "{2B3CED91-973F-4936-9DD4-CC8B1C8ACC68}" +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 diff --git a/tools/rexm/reports/examples_validation.md b/tools/rexm/reports/examples_validation.md index 79fdf05f9..af3befad9 100644 --- a/tools/rexm/reports/examples_validation.md +++ b/tools/rexm/reports/examples_validation.md @@ -213,7 +213,7 @@ Example elements validated: | audio_stream_effects | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| audio_fft_spectrum_visualizer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| audio_spectrum_visualizer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_standalone | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | rlgl_compute_shader | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | easings_testbed | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | From 3d9129e3b47bdb83c47ec77ec01e769522623206 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 25 Nov 2025 12:15:23 +0100 Subject: [PATCH 186/189] Update rexm.rc --- tools/rexm/rexm.rc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/rexm/rexm.rc b/tools/rexm/rexm.rc index ad125f796..4d3785a6a 100644 --- a/tools/rexm/rexm.rc +++ b/tools/rexm/rexm.rc @@ -6,8 +6,8 @@ PRODUCTVERSION 1,0,0,0 BEGIN BLOCK "StringFileInfo" BEGIN - //BLOCK "080904E4" // English UK - BLOCK "040904E4" // English US + //BLOCK "080904E4" // English UK + BLOCK "040904E4" // English US BEGIN VALUE "CompanyName", "Ramon Santamaria" VALUE "FileDescription", "rexm | raylib examples manager" @@ -21,7 +21,7 @@ BEGIN END BLOCK "VarFileInfo" BEGIN - //VALUE "Translation", 0x809, 1252 // English UK - VALUE "Translation", 0x409, 1252 // English US + //VALUE "Translation", 0x809, 1252 // English UK + VALUE "Translation", 0x409, 1252 // English US END END From 2b051afb29900593697437b20cd7719067a99819 Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 25 Nov 2025 19:10:56 +0100 Subject: [PATCH 187/189] [examples] `shapes_kaleidoscope` rewind, forward & reset buttons (#5369) * [examples] rewind and forward lines drawing * [examples] reset button * [examples] update screenshot * [examples] applied raylib convention --- examples/shapes/shapes_kaleidoscope.c | 67 ++++++++++++++++++++---- examples/shapes/shapes_kaleidoscope.png | Bin 39307 -> 82644 bytes 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/examples/shapes/shapes_kaleidoscope.c b/examples/shapes/shapes_kaleidoscope.c index be1409a8d..119fca598 100644 --- a/examples/shapes/shapes_kaleidoscope.c +++ b/examples/shapes/shapes_kaleidoscope.c @@ -16,7 +16,10 @@ ********************************************************************************************/ #include "raylib.h" +#include +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" #include "raymath.h" #define MAX_DRAW_LINES 8192 @@ -47,6 +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 }; Vector2 mousePos = { 0 }; Vector2 prevMousePos = { 0 }; Vector2 scaleVector = { 1.0f, -1.0f }; @@ -58,7 +64,11 @@ int main(void) camera.rotation = 0.0f; camera.zoom = 1.0f; - int lineCounter = 0; + int currentLineCounter = 0; + int totalLineCounter = 0; + int resetButtonClicked = false; + int backButtonClicked = false; + int nextButtonClicked = false; SetTargetFPS(20); //-------------------------------------------------------------------------------------- @@ -74,24 +84,47 @@ int main(void) Vector2 lineStart = Vector2Subtract(mousePos, offset); Vector2 lineEnd = Vector2Subtract(prevMousePos, offset); - if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) + if ( + IsMouseButtonDown(MOUSE_LEFT_BUTTON) + && (CheckCollisionPointRec(mousePos, resetButtonRec) == false) + && (CheckCollisionPointRec(mousePos, backButtonRec) == false) + && (CheckCollisionPointRec(mousePos, nextButtonRec) == false) + ) { - for (int s = 0; (s < symmetry) && (lineCounter < (MAX_DRAW_LINES - 1)); s++) + for (int s = 0; (s < symmetry) && (totalLineCounter < (MAX_DRAW_LINES - 1)); s++) { lineStart = Vector2Rotate(lineStart, angle*DEG2RAD); lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD); // Store mouse line - lines[lineCounter].start = lineStart; - lines[lineCounter].end = lineEnd; + lines[totalLineCounter].start = lineStart; + lines[totalLineCounter].end = lineEnd; // Store reflective line - lines[lineCounter + 1].start = Vector2Multiply(lineStart, scaleVector); - lines[lineCounter + 1].end = Vector2Multiply(lineEnd, scaleVector); + lines[totalLineCounter + 1].start = Vector2Multiply(lineStart, scaleVector); + lines[totalLineCounter + 1].end = Vector2Multiply(lineEnd, scaleVector); - lineCounter += 2; + totalLineCounter += 2; + currentLineCounter = totalLineCounter; } } + + if (resetButtonClicked) + { + memset(&lines, 0, sizeof(Line)*MAX_DRAW_LINES); + currentLineCounter = 0; + totalLineCounter = 0; + } + + if (backButtonClicked && (currentLineCounter > 0)) + { + currentLineCounter -= 1; + } + + if (nextButtonClicked && (currentLineCounter < MAX_DRAW_LINES) && ((currentLineCounter + 1) <= totalLineCounter)) + { + currentLineCounter += 1; + } //---------------------------------------------------------------------------------- // Draw @@ -99,19 +132,31 @@ int main(void) BeginDrawing(); ClearBackground(RAYWHITE); - BeginMode2D(camera); + for (int s = 0; s < symmetry; s++) { - for (int i = 0; i < lineCounter; i += 2) + for (int i = 0; i < currentLineCounter; i += 2) { DrawLineEx(lines[i].start, lines[i].end, thickness, BLACK); DrawLineEx(lines[i + 1].start, lines[i + 1].end, thickness, BLACK); } } + EndMode2D(); - DrawText(TextFormat("LINES: %i/%i", lineCounter, MAX_DRAW_LINES), 10, screenHeight - 30, 20, MAROON); + if ((currentLineCounter - 1) < 0) GuiDisable(); + + backButtonClicked = GuiButton(backButtonRec, "<"); + GuiEnable(); + + if ((currentLineCounter + 1) > totalLineCounter) GuiDisable(); + + nextButtonClicked = GuiButton(nextButtonRec, ">"); + GuiEnable(); + resetButtonClicked = GuiButton(resetButtonRec, "Reset"); + + DrawText(TextFormat("LINES: %i/%i", currentLineCounter, MAX_DRAW_LINES), 10, screenHeight - 30, 20, MAROON); DrawFPS(10, 10); EndDrawing(); diff --git a/examples/shapes/shapes_kaleidoscope.png b/examples/shapes/shapes_kaleidoscope.png index d14571ab735c1d50b3dac244566dd5a8c04e4137..3c15a52b324aac6807c77c0dc15d03573dbde83b 100644 GIT binary patch literal 82644 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYU_8XZ#=yWJp1k%11EbSyPZ!6Kin!!IzrMb% zZxiI(v2*7`MFt-JRjq8BcAjVpy3AK{e9|lN5_6%)W;y>3E$tWienCslA+hD`{3A#B z^-MPuu>YJrK`Mrm%ks>Mm*q8S4~w<8UQ)HJJ2-V&2WPa?Ll4gzLE3R1ox(HfJ36&v z9=7S874&+)dVH(sQJ*NC#vYOh~>X0%L0G% z#77+ut1}2-yl`5d$C<^zu!m_@D}%1J)Rl8Q3ZFF!^|vu`&c2c0k!Mifl#x@%wsW?` zcHv+~-feG8BQC3~tB~M3D!k8&J-)R^dtJiIKB=GFY3w_BnUg+q7TFy75}>Sm=#$pI z4NW(D*Rjo?&z^nLHLLExv;Ku4Y&_5Y@N-2c9TEz!ZHoENbIoF5*l{=RF|d6c<& z${ZRl_Ri5<5&Ka=+-SoTQweSJDDj3PGyGRqD2Uv<@rXkt{KuEZFA3QP9vE@QuXH;7 zrC~K=ldfGs=#(#7f}E|gJ2R(D`#F2khJ(}UIt=>*suay^A9DG7U1D2j;?fm+<4{9b zot#gqp}DAA)yJoTMW@uVp4HZ5GKbGv9D36^YtP|Be0S$66n|*7G^_6DWY1dW9dudL z?tg%?T}G~*W!{l6vEbWt@083sDd}Z9<09V)hNIUU%)dF@Tb9Zuy=G=Zl&HxzChnW( zpS0%M8M`vZvNX(cyRDnG-zgOfYy%7bESJ_tGt2JQ918si|-PIl|(@*d+m((6vCZChaX=l!p zA|oi>cSSFo{nq*Bg|f#Cnhs{Lvv@zbyveaSPuBMBqPDv)-W?5c< zj(K`5z(4-RrE3m9GcBg%?>N+V#Xwb^k8M+K!<)Dn)*WkqduICcZ~ex z+bJGChbQE#Ur&99u61Upo{+HFlxcI9wEYiQ?cLs0-KiV?a$>xP@A=x=+QW;c#)X8m zJnX+HIf1bwDu;8zC9VvEr56r960h39JYCk=)Xp(eIQ*B4Pn}b_@|oNdkM5YvXjN9_ zxo~ySXU#sx#JK|SlNUq!%4xe7-&fLoes0ShXV03+(Q3k8 zhnFlZM|Y*T!(J3gd5{o=Y$eA7R`={ z)t?u*c%9~wOfxG=ThKQ5$*;zs-4oxYI&cSn3GvBEbUSOYAT{RDpXSqiIf>1_J=Ze( zrd(o){>AcA{YiM$l$#q0ocNuiTIJVm@$HP~TK4~(~WnA~gOJgoSTX|AovRz2eak0JW-a{LexpL&+-5~!%!6+B ztfkRGpLsR&4n1=#F|2v$z2eTnP_-bTZ!MR!_nvl2**{@Y+QwGKt(SOq{uG#P=XFXy z&+2^4BQELoTrm3k;I#LPyhSRy0;iODOcu=0ZFFC-Wxus z@KuSvxnab#_06*Mr!Csf&37Dp{~tKxyu8p=btNmWVIJ#D&$UcF(?0sI-NYY%hcD!( zSJtdW>8;J{1Dmz?WK0cjPjdCvHh;|h_~3+NnSo&!wdyBLKE}Ri&4FirS<~(wnc;eN z6Ib|O_qSGJ(J{PjMpLesxSal>{zNQl>Pw!(EIsEM7PzWtH1oPFI+&(^LiR~YMbTe} z6Lxt6LlAby``FwSIzeztqdQ_bS_@9yXmn zd*h7yHNPh|%$J;3*&bQqUUYbN*hl}fpXMjBG+&gQ;3)F*hLNNxmt0NSh209QH{HAD z8hl;y%DFFW!vBqlIf4EfdkS~TPPaG{S96jlP2J31XtDhKn_D{KV+tKtMxQ*{)$*wO z*3b4CA5@lJQg+o{`LJ2vS14P|e4ZnF&P#@yenE%irblHhjn8>DAxYh^PVxHt9gmvi zGG|XQY1OWOti`XfHcGRzIw#MyOx-ZiJ8PE8lem~?2k&(GO}>4i_2=X%9~OtoOo}$2 z7*sZ4QvHh1c?La9t6CT?8Y{$P@95n0A^Jr42CJZ}!bWoCTX&ps{-$nb z`eX@X)bxorE@?5#GHfhlD&|_ZVX5nkB=6uGmvq)`abIEN_=?9M_eQ`j}nRv%erACuW3mFVJgWAdyvhj&UL z%PudLb1FBteAy$F79i#Sq{aR)2lHZMg$Sh@1Ccc^@)%UpinLUNE*tNh**0rt@0<_p zFCDM9`}T-EY+SqHaH{#ff=6l_j`T_;`gA)LDtzL$v)*{};$ou%Y3v*G4o;2h;EWFX z)8?zY@z=$xjX!Q2={T7@We0PLonhWFv9cvkP9L1tm+;W$#wYomxf)SZ^G`f<&iUCb zv+c$u9>ct)SL|=RIXbnDv(?h{GRMw;O78M2-yI86<8}Gx(BFUX0b83RN5?$I#h)1}fbTb=Pd$^N2}`)>V_Wmg;h+`nYF3rr5ne90H|Iwt3x zt2uKluVJe3Ci#t1uU_F`F1l=Rn1RXbGlQOeac}{XlwoE=qD1r0&(D*;#wH~xU9I8W z)I951Z=RF7QdUOfLxD|l(Tbj()hDiY>lO>IS~B73OWC$1VF_1GE!=U4CB<&t4wvoH zwrf_*Wy^?Ud%WsO;zOsrJqokAx#gXBIdc9T5x0NR#=WqH!AN|zlvASPTN9to`<|TH zMUPm;zFpB%|FDx)Y~PEAO>fw0URD|$;Wx7nc%)a8*>daO($tyV@4|Ba9h$11_-KoU z_KAJ3}C=yq?8+{$;0RO(htjQhA$ zvF4-8={-$r&$yirzvAI+V65rsedOALI~7u?cT&u5Y}hGn8{_d&+Vn8vP1zr3R83_s z8r_{Z`Pd4T^{i!OSJ#4^u!%AtvIj)tD7CdNpx$v0Ji469Z6D)4$efm#( z-q2D_GL~NGCAXK+F;C6yx;t-iCug$sa%@hCPyzj_{OcwzQ;C#J2vK_ z)7d|uTqSLP$Hi>chNGH>y~;5!Ck50bt={l)X?D)P1JlhlPb$AiY?QmcWEbmQn=d<5 zrcCS5Y~Juxcf#J5LyULxlHMpy`QLf+^p!L3cl`0lo43$?cJGxvuD<3A+qsKkCd|&~ zSelsfU0C@0lpV}z;=638EMd2Q5_PbBCt_g;Yp)v_RMl^`ygnmm=Q0ZP~6 zqC)F-aOo6r@z#h6YMjx~?eNHy2++36oLJ9k`p(05_mf?M(X*7y?`&AA?DWxBx1R5q z*Yta(cH4?3NImrS+3Bpid*f2^s;8_qPlavoI{586D4Mq=>&HWG{-VQN(K9_(8_kI@ zpCnax-hq+jfD&e^rJJg%u!YQx*B2d-K=io2UNUwiuN1rNvJ3(QZ6U)LJUA=q~KTB`qH80}I3DV+E`Mfgp$Dv0}0jZpu`@^QnEdHHn8eD{r1T+`xJZOY_?5SNtZNr z@;1)&_pw^!c2CJPszY~k!Bf#0vpHuvXI8p-NuD-nV#ui!{iMUTZ6;q$wcCoFH)X;v zOuoao@VbY+9{c52B043%6TS(YQg|}&nQLa8!gj^h^#`1%9S(o-P%ETk?ST&6EhjZi zHiq);;Hpdcd~#(?=SmxnpNzBjP6@Ht@r5tsG1Kh-nrpW>q$PPfzxc?wSvpqNtn|n- z&zPr-ribU=*rBwf?@EoE=PuFUDioHyRIw`%YFDL;GWi$YJY zDkZa=l{4KWGk7v4iglh1|FNe{`@gWT%#Jt5r}a5JOZ47+hmjwc1J>V}o=i42UomvndDb9~>DF#F|!?J3i^erF@u# zqIy-t(~k4JQ+{;bVVV&4uw%7>`ql-?W_%lOwx3^rq(y#P#ZnXBhuI#yA(g$_a|)Iw zMlDx#s%)Qfj9v3*%N#H6**|X_YM*`J#V3bp`7M7Oa*~^6>;;1Tnm(~E+|!X~zHrBq zQfAihU58WkHD68E1aBe?3hZjG_b4lAxJLh9y!-1L=FBz`g2E}R_IarnyQ)%|k>mZZA&=s&)^C}4rf zpTbso#rlRP6AgEMbU3|3;fdOe-xseo-f=nqg=6#l28@`+zl{sUM!LqbW zPv75}vUxu~S#131*jwY~H}AkQ_V9g+!*e}6?<}5P-Ezt^>qqCT$~kvF%?m4Z_S~hi zy=U2$oaJGXCk(jQOjz8k6C_Z>Ty;JN>XmPgG@nfTVOH|j~oR+hXBPOSo456_*} zDz;Y2VaJ)HVU7GHi<>6xX*m6Mib=?cQhuG-M_%)PTvFA&EV1+<_a%OA|16WXm7(7j z?#|rMu6XAD9hWz;3R9+Kgw{VeWqx>V&w+5e36uLWLi>cJ&tLKQeMjWY%7x4R7tU;r z`}Sb7aJcPp0}jUT40rz?G-zQw>Ak_jwl!PdU}L)My{P+c>;HR))MxbXGz`hF|QI|CM-DAK4Zgyr*2MpYFGVVB(|J8 zo+?)qx5&*xXw{YrZxzh-gRRe9yz8j@S<{d`T4vF1;Yi*SdPRqYcM3BZGl%axEY^NU z#3by)&e=0ctRrq~|2UW_~8)saeiP@6{El60FQZ zOpA>b4(mJ=j1CA63QSxbaFW-}OG@U(n38r7sZR;K@Ral8$&(yMb~J|+e-w>qURbc8RGHzKdrEb|QsyrkT>JSWq9k89@y-4{ z@ovl6xh-D=J_)be(kWMeWrf1WrQT7?B7-g~Rn17a+`ooRO#jFa#+y1(KPBU<)J)eV zd&|E_6PVrRaWa0#CDVNd%BJ%&XWqYfw^PpT#-GNsf47_wH~9a!%f4!Q`;A93&+4;| z>zbZ%?w59|`Lapo$Z@f6&6={pliAv4RkLrJCqI`lQDPs1t?~n{Cz>Y>wrK3|=oL)T z)}OHR%ZdXVcFvdjCM0}qNekSi5jX`-NbI? zq)V?7R`j3XO|JRq`Sy!jZ;iia#AC0;H!g7<){xkyXi&wY&l%VqQ_y6@rK@FBwbZ0! zyKu0k!tUOn{leMu3k{BkO%VDdt^1fS{-7Ukbtk8J&bJ9t`#0>6^LZ&Fw*E=Tyd%Gu zr{BD?V#CDG{HAXfE^%yICm#Rnfm+csaohEev`$}mduVE$ey>Ybnx$F`zqqY7I5tiG;_K)V(;JtB%_UcxXnYj5Of}k6 zJ7vnt=B1(Me3wr(++Fros!Vp`MacvP|FTE-F ztUhX4aFmGTktOLhKWE*kI6BR4;@{)GNy)4?Wp~`+_V%8#LvsGj7ayCo*Yhl0H2;QC zt-+7ZnC*+6N9H_B@HW13;`NSC^0tTOhFEKOp5O9?-}2{7iSImDjpjyGZd|b<<3?Gg zTe^csPt=n`c^g8x6uv*u+T!@GEis0dXM)APLvzG>t%A-TdFGyU)*;;e?T^Fha=LGh zrKxS(a3FMNlJ~D4hl(~VDNlMdTWI^D+5RW&iY^)GywT*$pAaXZwoO7=HD<-c`<{l) zA=?EXmnVHzS^2W{iix9VgwSKNtRtePQI<=lG@kgjaJPK8ZJVASZ~f#XwXLTeivBk1 z?pZOn?W8CFk4Mb`GKW7IudCtxbU$Hbb3)=_+p6#Eu1Ak$u(u?>V2+U#4tHDT_Rw{8 zz~WLxFCSNT-Te!1yK?W|IJ0xDkixP>heKaJe!YQj*`4O~pAJ9sOZvlo$^Eq#|LmVX z-W-{>zOzu-Ftg!Sq3?;zY{v8nizNAgx^peTiOJXZC=gj*#d0HyZiTg{I#V7so zJK+=6X1?^_LbpnDfv4st?jQLf8*Rz1-QTJCUc&9*0{+H}d>pNTCKn_br~hr?Qjh7q z()fYjGLO|&dgs)`4q=a8lm#pA0lDjgoBoeZPWB0MInVgFaWOn|OL{Ce`*-I>@620{ z+ow+{I3l+EiCFxJe+tKVm;9K0qlC5Cdg~|Ul@FagV-mQ_i!SqT%w$Nj+j^)wYOU~> zBGxdo$+OlK%w+zgzboCU6MNvH3t0PagjPCw*SbL$2;zLanCKA`o)s_4s>D@ZB$l;IKIzo6gR}m3o}J%v>PzD}?k!sB5^a_e zZyR_vavZzbptOC`p{a#0?mjs3lrKr!B51MTT{|!Cj38~3tlRvb?DdR2d%a8cANcXb zPk2h2Z_sBJ)yxKoy+>yG=fxeH#^#W;WSMVHue;Z0amBw!p0LNHvKXcbubw{ZW5?Op zB})vwE-~7!GObB9UT4&D!=Uk~_|nYj62Cc?_BO85?&$OmI+a%RS2@$i&u553-YwO(?Q z(*4`5JNLjF<)umomQ9m;Ie*?#4ZHsWlNPJ!oH%)U$u08>nR1qL7w`IIHMhv@55Dw6 z>BUd~6a%vtKDYZok!tZLIevv$WPR^3xxPL)%l zDtoI-K3j%16>VWQV)3evk(_$zP|Lm6hY37cQ6eX%n7q)`oZ|Sq_Xi`;h( zUYQ`fqNH{8;Rd;RKeSwDNM7-1XP!Il;^V{(JK3MvIVJY#?%VKGFy`ZVgENfVs+cX; zb?W+aT(!TlZoY^K`Uqw>fM@AqeV<1SvlR9AFnS(&0&_U9F$GlO;;EexO8fByfCL-PVE5+}DmHLNN0 z%(R&>%kRX-{z+Rr`r?A_dc57!G>7fuQN^8^OyN??U74qg{p7UW^D=Z=fc5$d*6$l1 zHC@`$rEj~bLVw@ls@D8BCq+WanWV%6E-!e23tQf>OL-9^0nH{T0!K9#X1-N zOr=9p6$?{Mg5D@EYjpK_=-TaL5g;iY-RR+&=+PIKwTm&uUh(sXqlTJO#kbz|U4N?S z#vYc>@(T?VRnKGuo}BP_-@$;1Lcwwi+ph<3W+&b0)R*Pk*2bqgm%k>_aRtvplYJ|% zW-dA+yXDo6iBZ#dLiYB`mEAZrDQNq{Q{D>2D<9?;oziLxY%m7}R*ITHPN&o~hs2^2 zCWhA@oYFXAHjU$^<69n=vxj=bSd}#cyH^W6S@t-}-$~SPrRUTcU9#b>4qmK|naqu0 zQ#A}TyQWog&)>h|?h2`sUu8_C^p>>9o1W52x-7e~?Beb}N2b;lUNzitq*HUThUe`U z-!AQ1<76hEX1@2XgP(Q79fM^mcP9oNpAa?uvC-@)e^`RLdmQr|uJcb$mtak4J&?iP z;;><%x>J^l#TS=e-NeIlT-P!QM=N@~J~ZQoi06uiWlJU~Z+)O-Djs+{w?!)@=&pND z<&_m2Y~E2#t^E5c9H%Kyna?@X*{{;!?S@6AHzrR$mN_?_-HK=9)Q2xBC(qd8oK=-7 z!P0PL!*MabBU3D=95Y;4)p}`xihA$m)pJyylt(@HPdY3nB6nroXO69NC;avEu~R#y zf8trdX`ePh1~+Sk3m$SSSXefT+pbMKJ>$s|_nc>wqc|P~`)4|~tzNJsbfJrv#H3f| zS)qDYzF8YS6MS7(lj!8LxG5}Et7>Ue4!_=hLFxTFK56LfZ+LS!Rb4ZaW%_T8v&9PK z!bZ(enUX2uikmZD$_Je}CZ4|Jn6zdlceK@^>FFy4sg+Xy;GLi zXU%5k)(^Vtx_*aKpMOl<@#)J>N2{Ydc%{AWH0sNIII3(|c4?Q4 zYq`AXX}JmiIcECz|8V3>5Bel(_I+}&op84L%2bYxKl`ujntf%DgU`I<;rA!b{=Q;v zm?WEJLZZa7hD%ODVme1uI3`GC-E`Nm>NvY#N?Jr!s}zotF;HnZ(65-8%8nlU=21*B#wOkKkGjI6o*ULAy5vPUn@_%EWvh&9*<< zEFazI(%&Y!^4ldXo{M)K*SfJ4HP4It$lqOEb;F(4+T(2Vk53ZY&PgrJbGhcfc9XzO zpC?<~y>>l5W?1aBc2Cb6v8)-MJ~tF^d*(z08~d$D72CIIvRs+MZU5Zg7tSsYwRFy! zwb;F~T{rII&F-`OSJp*yT)lkbk^B?An7qYH?j08sTe8Hy=(5&23x%sTHLuvUY6BO` znyFYRT+vzaB2+^#I8jhbVS{PZ3e!t2ey$EH9;k*iTwL9huz-0%+ANhPF<%PQMb7;= zb2$9tg42Rs`4en6nD}HR`sLZF9Q9qI!klzQ^_We}!v_63ou%rknSC=pbtEz{ZoT84 zb?<=KvK^P0RDbeWW}NiQ-s1J$pnT%2Z5?O7-#8^QVeXDYbECdW?|jN_`7KyG_JZ~A z#BOJ&I>jk|A6l&qGkdO-bm*Sx=&i2Fl(3Y!aMz`GOY3Q#qCfrK{I;JNc4n3blsc@K z_#=VQP@u6t?naPxVu10*pv4;whiN|2I-qg#$diy8TRzC^?Z3GA(Sd2(PWV1vazuKc zlhm~d3@a6v@Y(ic1g>a)b3jb(%9p;13BF=;;Z)9_XNJ$cqswZj68Cn_i2`NSB# zL-15^%c+vArKUNlyr!oei!SqQe90GYF-iE{k4dU)PYD%SE1&pvLU*y|*|sG&y63Iy zSbI3}>05`X_E)%~V^XcQUe+`$>^klLq{VRIrYr-Iugse`=g#6RTVQ0N$*Qy~Dr>i7 zxZA?AgAHq$j;OWW5m=I@CfC8l82z-(wo?7j#L<@MrUl zLsKW&G|bz!ac8&0=gy1nt8U&nG&`V~VY*zzE!FFDPh`%Y@x@c)-G`HpjponT;;CCM zl$B7lSl4l}3Gbs~^L;y<^(UV=+k7Wt+Lehy_gdbls_lQQ72oNZzeQ{I#+$zR-xIi_ ziw+CVkKFO3gOl0o@caPj=BSU}r%Sxnn|O5EPI=;7^mge>9u7@bIXiwHmje@|7hL&d zyz!fGv_XI}^Mg;)+nAWiD0KJ&~uP#-sUB z{6y@OW5OE~yH*#u@JpxIdGM=#?9jfK@aV@Km#iHEkL_b_&b(66sei8UC-1U$k@7|D zjO#wAg!l-)w)Z+D@GLCo@T4hwID@^{$o{w_p!sge5&s*XES5eq4B%kfmABx^-y4@S zSAMn7J;X5W_{Fow!s84sFkHB8m$aur|LkNb@g>JhO`B%4N;P_|buqud%Av|=CD6*h zYwi!NAg4s{b-z6?x@Z0g3Yuulque0JH|1Gk%)_p;F*TVzH?}xv$R$2|@JU>;dc#TK zO_QgbnjXe0n)FC8TyBxuy+z?-3r*x7U-IwSdE*kB?&-XkN{;z+cU)51XQ4JFoa5)j z8(*4F%f$Th4E4{EaxtHN>5F~LD)y`?%txNEdwu3nEMGLcf6l&%PYae-M;%o^^KRjU zdmd*e?>N*mty02<*~uqunaM%L>O2cku^&q9vl826>TaBAZPm21teGh^yUt6R>#*rL zcIVVqIrAxEN0uBjU7Fb}^Y_RT^_Z*=FOP=F2?nb*U1Hq&*<$0fi>q=ZyLb(qGUrcw zYOrlfvu^&PcI|y%{Qacd{JL-4aq+q7pLgf-ZM&q;YKJuxv{_cfzAv6!IA6fb{J`;yBIA`$RqVdrcynOcJi!-%vtnH=M3md7bQ~9DJn`?? zvNoxQhkTD%B^SL>T()6BSgT*2ML}?Zqtr^t*%RW~t$G*l?hpDtVOE@{Zp($k^P@65 zCoxHjrA-lAp-{|mlzr(x)nj~5j%gS^bn=;{sCIthEPYQ-?j$XfoJ8lWT@KsXqicjF zKkxALZq|JJm|H#RPm`~`S?v|Q`E1cYyXE+{l*yZmzH-W1>Ks$I^h)oJOM>Q8Z!@-B z(q2~}^}^(YL$br^qAsm!hqh`Kf!i5}#Q3hP5czns|8z~%G0v@jTza{mdTFB1MV=EL+6*5;JzA8QV)b_>y02hZsN%Q7QzCFdsAHS9 z%*DU1Yd@%%-s{L+aA|kZ;@DTiVa-9(i`U z@m%_7jL&HZCC5g{t)AnXJ@y3dHC6U=ToJH8{|69 zu^2w|U2P_`GqXSJp^Mk71!2;yvq}vuUv`VVtkEdz($qXXV}t0r1uRZE4_P+NiE4eB zz*`ejr(!l|!_RK9M7Pz4`mXf&dG2_S&2aEh;)bQ$4?d9lvSaxX-yN3(6^%E(JiLtE zQqHqfeUt2!FUo5lPl)(j*lKJ0*=%8vMED%OX`g0aGFVa`wLm3rr)ET(lZJc}H@j2b zQPHw1pOiIvdE53lyf$&lid(eAM>R!!;jfwvTdYs$)}QG0j(Nz`&E1yBGvTuI#+U5T zR*46vS6q1d!Bxau_WIMy#&MZ}3oae{+q|@~=?$O2>^Ro11-|u5mWY1&(ALUndYR2K zEy$QxAX)6p{v*@Ee;k?-AladvvvFzdgzAn??wG2HcRO?VY(GhunLp$*&st`l^q9?( zXG1Id#=JvIr%M!m`JrldhU2LG!Y@8+e=I*D6Sc(A>rtV_w!ayI$BvlDC1!bOGG|Es zYd$L5a)@=Wjl`?WNjJW>G}D`qsALGhaK1*URyQJ`q?5?s=shk!;BpdmtABqU1;O2VflbdKIoG6CfO@y z{fP~X8(+5H`LO7e?~5(xCVc5(j#5>K3h%qZp`66c8FaW~%9qCT@>^Ei;1r$L@~2DB zKhJGRnUuQ7vz9w2eV@EN{^S^^;X@anU5zuHbN(rr>OL}(zx(%2g;qpP*`v?)I}6*j zb%T`u3uXlr1%LdO9}%Zu_9pR_rswA)M+7wseSCHunfAQ%tpAc3{%iNN$>}TD?JIb^ z?9seK2cy;rb+LPWveYbP+W4|9##l2qrTB6|E6>WO+J;YAm%ii;k2Hz6WVo)x!7J90 zcmIVaB04qm9>^{6-uhx@!UgT(33r=q6CbV0>Cn7z;V<_k=QR?Btn$pQ4R@G$X4|uQ z#~ivOyspI8&+bT?nkK8*#)~d%W*&JWne{}wONNnl-3u0fli zW@dZisRk`$g(+!!8vQoxP->XFK)50gcYMn46P?mYUmk;}*S4AX<=hFju6^{`eq+&% zLk+WjvfQjGI>r9w7_aFizJ(@@=jXOOnssS|vf18C#_t1WJ@-7@+;WNYFau+rP`c&G zQZ>Vulc!V(#@q63>JHf1@{T`GDa~3_Q{9u-ye84{gsj5ugsdGeclhw!ymxTIyuzK0 z*D5DIlNG4xl%Ku)W#o?sUOToFFt0n}>$R9=?}i1-tUYyO3PT%O?i}%Tapwttb|n15 zgxQTJ3@6WEO5PB*NMXD1r9-^GKtTZ-Lg$ST4Lg)e}$oSKTf&k6t=IA zIk0qIfJ}gOyuf66j-6AdwDBu`KYXWoUEiD^i(Ms+CcKo|`)BEu`Xkd+k1UyZ@J@vC z@!TcL%!^*j)l_!RKC`r_r=<{+>PKOS7EcjWY*R)izly zovNo;Ey*S@VHW?&hap~ zap;*_RJ-tr+#7Ek%DFW&TO>YT_-whbK-v6X#>A-~k8DQh=;gMU`)b|F~AAh#q zD!XW{r*X1;$u#{RR~~b_*HpGfRmw--Yh4=L=E(J8?ze)cz7aAPPT3wg^3ma`^R9CZ z54_sHa4E!myP*7Gr{|1)u4Vk@^IrO8?V3INjB3&iDe;y&t#bT3jMPr#1aXJOWcJM2 zuqfs?*aXHiA#4WUT}=8q>YcK_R^-#bZo|CAQd zP?7q&s@VZ{2h-$DAJ3nC!c0iK$(5{Ycn_CC{?6#7-?) z=IM2}OLtE}XbE%RJ;iq2eKxKqa(A3LxU_%HF~*HA<>O~G-)Yw86&7aSai{NeOwd)~ z*?b(WmK(n{T@mCmE-@DrZdjcT=I=Zivx@anzy8|bS#>)*Gn5~4a~J(_Uu)x@73p;%&grS>-p^8s-}!d& zacn!%a9a2Xi`rJ@8FyOTeV!ei=J`QYBTH2+OC>7F$fD{-;bcqgmK?r?1xKHmM=h6j zdg$pTwJ5F8v1@n2w@I_iR=h0F68UuFP`|W)tLvJ%FGRHre|cnXP?+7W&l{kpx5j97|nY1ZMB}xN~-xWJ>^>nwgD9sk~;Z${F4#B1?{ly)m#}At?9bPuuyLq{Fjr zFtv*8*2ra;cw0dE`uQV2dZl`;lK!x6ZkHzYq&_BwKm(e#u@*0jbaPd+w&V%Ge(?6q1+5x4V`h9grKbgmSTXk%db zIaR7v({zuQCllMx#tC&L`xm`FC?4u`EXQuTY;kKxs|aGg&yb6 z*nRSB^OP3dsu_Wg>We-}Z2aiy6Y1*n%O%V>;#Bj&xSB~qeoK}x=KP#`<&Uq%n+-P| zb1H;`^MbVBeP}gY_=)iuThJ$?wU_KPANqRU5#TD1`KNr`FDFfqD?91U!tzM()kSU7 zK6;!jV?Lqt#X#MRudPXb;^8ch5{C)0J~@i*zWj#;7=LJ)S5-9Laq;QfeetV6@XST4 z71ewScJkiUNz#fadekssc44cfYOB3jc~H>9fWx|5JZ}FuqoTfcLA&%Bo|sgAotO)U z#b);FzgZ!=?uM3LTOwP*QO1?`R79Tr_{6EV_sB8xjd`jeViyu zh_X}cBp244@%HX9wWruXMRl`!-AnqKepWQN_KP*+Q$x}C7zj!yVWp9AB3|sKuhV%2U zd@|o>)Np5uclVY~IsFrk7Jkt-#`x2)n>5qR^F){GT`YCrC{ zcN;7WTj+iI)a*-a1|If0@e^P9#r)cERM>2D=gIS1*1Y(zbMhSn$A12#KOSB(myB#q z=q_F{ao@$moifHdJ#9k!!+uVZDDKqd-?%ie>PdLjHr)${yXV+A^BQyfl#Jgq=~Y@z z+C!sev7g;iAGwRgO;1}?9Z_C;$xQR3OZSGw<@F7j8f6X+jQ!e+95^N8liFS`b!$tJ zSi}&2Bk;EOkv8Lvz3e5WPefvlyja*~yJ3UM_5xM2wTCX*=*^l{*mYKa#~=5u{hht_ zDf=e~xi1Ox+HpzOd>WgUUi~BOXoPu-dv*|a=zh_faSYRPvaYp z=1$q-@3*t%ou1bx)qO_2cZ&GJ;}$H5S!^O3@JPJqQHRX$j;-x?ek^y5Y+Ao2MPgyY zj4fQJxj}QOU(YzO{GTwJ@!(X=52@&)Rg+Jxz@1JnD^Q`=m zHcr({mb-c-{~s7h$I8T8DVX=M2U|1Dm)|f|{D;)$6Gcy!ScIA_>BRjZUzHB)7JU!@*+V%}g zm;FC+((Z?rK+zfLj-qUXkh&+wl(!kU`FT&7Wi9Zs`$|o-_T0qNvtOhIOWEx>Wl;08 zX@*H(j-H}7?|x_$NJ-Q8i@Jnx^9dCm#l>z*sq**4vD*2tYCHGRjY=K&qr z0X96psvQbkC6+S!_&9o<^?0K8Q6@J}E7z;{X)%j`8eql51BtS@jcW7a+6vTe4^XUBJouf#t2AsBrJw5WD_^6C3Gv@*S{ zY`2*4r`WA4>YDSxv0Q&+T7dE0Nwbd?JiWhghIyxF@sB^QS&?q1jl`$NX9O;v5Osaw zYIW5+J2ERY<-aTB-o9|^{1y-HBhyl+T=~sY!q8mB#u9!cP&uG;WylWp4{1JG$81$u z1rIYYeDRWcQWsO`m)GjIYP*If_Yn~XgYOe2Z~HjYf9;;8)Bl(J=oQ(z<5ByREsmZt z!i%ThdMdE7?%1-vIU9~nU;kq2+mof{ir)o;^(F+DC3F{8J!hP8|Ki)FOLSDs^Of4! z%|%~(&)9k64y&-T+5d+{$_r~;vi>b|`|0Mj@9=ZGoXqA#0p>4TxQpypKD3{)$K5At z!Lt7aPyZg2>uW9&w$iw;!Bs(HLgqw`#AiaME_~5T;7HYQdUsH)??l~`WrghA(_@c_ zh`cClJiq>n-ii)S_6-}eQqq;%^5DGdhM;j z-xDS)U&_s{s>$q_R@i$wuINvTZcay`^|}q}OW#PY*wdz4d(m3{!eX5R)32ZK+->l= z!!zCBb0_EZMvdlzR{M>q{D!|g&-O35_V!N2ErlaT-Y0l}Zn@**^-I~b{^2R@Cr^Z{ zu71{WUU=Q3+o$35{S#%0-goXWTWB*CN$;BNP?Php`Rv;-JnmUbv~&Kc9*c=dbUM3* zk2^kMMiO^^O(svI?aFsY)5Z5bmWY>GxVv?V!6EVRAD>irX10lCGN-96v~cwIZaJmq z^z7lJv;CR6n7rj-_n2<_=Im2d zTeEWN`h+sUQ@@YgYR}_a_@&j?_Jm$moAt_6Im5c8=`w-J>oy)`Ubm-R_YM1@{VkUm z_TFvLUVq?@<%~;57TjQN(q>}!b`T6cAyA}k&M7Ni#ATiGyYuXfJ0&lC9)99h6=hw= zB^5ho#+SpsN2)@yMAy7{HbKhl$0fzJpSjj;apE->oV;J+1p~)Z#RBj6bLMR<+|!@48(kEhY&PL;`)PiI!l)mtDQb$k zSH5%lZmgNMVD-`IFEi#Ua?bScie|UU%ajeqwZH)ksxo;>M~YmUvr z-}wtJ>nr{~skxk^m38A&v%><+%yY{e54N7=H86a#!!6w1fBWNN> zBzb?jamuYGZ%OD(Cyf}kWNU6)o5HKcH$HLLcFXV5KX^!Vrn90@p)1cy$>}pr^#`ao zNzH7kZdi8aWN&uNJJ}pobzS2R4$p+0DyQG^njrU)oy$DyMzi*x!k=@e7$}PDJMpqh zD$DWN!|XW=Pe0x~|3-o0F~6Er`L%~Q($trJ^jK@+w%*3kC(<=%hQO-L5-%9svSJVT zw(go!EwG)P^v_W92o%) zy*w`Z{Z2;ZTxtJ%>gKw_v+sR;D*MGk<(T~qsl7*9@)naIR$>^{G%aSdsFD?o^Rolqxu;i~1@CBF+=^-Vu1uRYBhFzfKtX`ZF_8#CKx zr5bO2Bo{4_z%3myYjOGCChfn$hh>*clfQ8)IO2FqR4VVAnhuqp~}=xPlIMT{$E+y{e=>P-xkWLwz#;gS35xvdwqZo_IN7 zTHe7lGt<){IUgJKWfw1Zta<3vTO=L*=K+^+))D4S_by;{4bEcN0)F*d)rx`;PL}_g7Zk=6EWbQeDt0x$~p%N_mZ~;9w&he<&?O_i-8(qXY-oPM`BXpXlBD6wxpz!F z-WpAwvZqsDZ{pL0hn?@joDzFZ=P%hYF>waNmrZP9`?m0K?>gJibA&^6%8rwo0vEn2 zv}aU30 zwy0fxok{CizpUrwF@>IfdlHJJ*L`EreLOc}GiR%Q)jyV%>gs>kz4sbL{4$&}<>!)L zjcKwI4hCuPKRc(nu*F}4XJe{aOlSM8kB)hc-fNHauK(aT?Qpop!(#4zT)eS-(`8%! zc=<>ix{|P2cxR$lj@9v0^|hb0ckO(#OgiO%pf+#d>Kun}!sc`N%Nu?&rs;3YUo*_TDAa z)^6C-ewu&BC-z-cS*@y@ESJpk%-p4T%>TxnmU;Z1h3s1o^(M|>j<8zVYW~uQ+31SW ztSe_+R{o#xRXE#Rv+UBLGY2O;-ymwY;}C1C?!Hsq6YdwxboH|llJ2|l#^oEc?j>g3 zM>8&UaXnLudB`|fedz_26tR5;3sUDy7XG*4gQ}{nKr+8(qD$`XiI*)8GcZ3Xan0PN zXr?a^lR&kd*Y$ns>m0wGACX?(HWj~RJQ1+Z|2<& zUwhq4Y?|*Gjp^nCzrq1VYcXB4~`k0@;_VQVBS5uXC`ZjaYo>ZN1u#! zKZ%;{{;KZi3_$zUq?d6*JFWJZ#As=B(LG!S_D2+V8A8vXp3N_jjPDEO|0>i&VIL+xy@^DRo=FxAQVL|Jl5pR2Iw32?28t`!3!zIZ=Yq>$0ug-z#T=UpU%@oJw`doFe7f`ASwG%1vhL zXFj{_LeVP%5AWZ?VVv@v|CoiN-yMbT6N5Vy!lh2s9Z8eh*vh-_nC;4!{Ilm5q-F&j zZn&1&Hfc|rzFy%;-V&*!Y4$~PCcLuC)9Tj~O159O#aiOC{lYJ;XU{H~a&pQPb%X7J zLU}(`M43ngqVxB5~S2pyQt;aO^I_=t;G_*4 zJA0?il-kR1c)G;OnGe~EYZm;Te2Z6nM&*+>#;Q3Jv*Zl_9Sq$V_$V!4N7Chf(4?f@ zzOK13`x8#Hzer0gHaC5{*!AgY-`2f4M|N}vw6@Rr*5SFj<&a$DypYcYPnjp!pY)x5 zWCx>IU$gC5h2!Q6P5is|dwRNG(ObXqsO7>6g{}8g)Z#il4sJdh|72NW#INOL zzht;x&YhQcWZF87PUD)NT>(3JE_-YL)?9meMeM!{IczB#SQPfP*aYOMs1{F*dNFC% zfgS7xT4K?OzMgE3=KV8vsH^G~taSBrKas_e8s^0nS(7>ahKY0DFL%E568j0sYNnSJ zwq6!t=4Dh(bkDJP?8SY>^UHasX71;yyLjT;V`=Iu-zkW&y?7Qli;bgI*LIS*?I-z-ncPqA zH)`;A__|-|%P)E)ZhJr2xOamAPjG{N;6 zMDD%#c38{8>rwk11H}-I!*|R?x)_4Al9Dbn*k0x`OzhF^<#Bn+QLMeR?C=-<5Y?`C z{~CF`V?O$OMX6rvIrzdqChz$3u%Ju4W?PT6F`Jd%c*J^_&*`c5*3+R`Pn4^c@K)V$ z%!!yF?Y`p@i|#A0n!J{s%~FN-60a*)l{)NTKep0P%mGO#J#>(F&yG4md0tGxN#SA|K3X5abLB$e4C zVw~`?*_;22{Ess-9iJMmRPjtHdoi{CWTCWWDzoOpzIWwWy9MK|nr`~8FL31deo~-h z9-q`L@3!FJ|CNC&iunuJTLPXf3p?uC%j2=)z@k*8#o>%i+Iu$s>=l!go^C(!?Q#_z zj-!f(FL~o_gdf)hNeLTlJ;BOp_V>s#+njfYmrf73dBFG3UZp2bdK>*dw>;_$n3J%Y z$3yr03Q4vjM~s&~)m{5|<`si<2?mF?1`cNJclLC=sSWyMSG7TK)pAWk=@fCxr)sK| z%wpTF7&OOx7oKf$@otB1EpJJrr{65~>;DaEuXH$GxN15)zENqh2zFTRbYVKNIJa zDLwmlLe&S+9Yi#<=SNlgu_Q70=0AxGi3z z)OcxbQl3_MjmEo%2|*Hpmp{Kq+vVVW+n5#K-Rs%B*iWwfCUJ`6bU3 zpX^xTR@c@lxiXb=-J9<9K8vTx-gxC$bh@-nkxwJjJy839@NV69U0)%s@)L#3rk9l$ zrnva;o^ZD*Pk(8l>($^5FD4dngmP^;@qf!F@wI1ERe2op6t+Hiuxx>N&-wGs8=aPi zIX1|hQ`kRA=>LyLoZ&kr&f51u^pt^h#@w{RpRIScIIdW<(7n>}Y)P-ozbP}kdG}u7 zh|X%^-FhfR;gwj-%la?$wi18w<)LZ|KzOVcVE56xU8Dc~eI{n8${w}*Nnz6acn zUm{kp<95#IwY$A`Rb z2++PL;B{k**PI|dDWj>> zrp2k|4+S193u14%v1|SWE2mt3uiG&{oLXidag4~?_CMpL{*3u2Ijf6432eP|Wx>ma z2iz7_E;2Y zo_X^Yx7H`*Eewm9c$e|vGUxTP?szO;GGR&EevZ_r8T&t^vSo>Xxf3!cPCY~+x!BrN ztGwt?OTa^qEN9O7l}na|2R)uICVDL)C*Z*;dFH2KUn-7@@-t68wo+EF;ys*l)Sx<${Hh1KHf6!H*XI0|h zQ1-aX-s`UYg?~!N>Pk$PY>S-mHCTBc+ZyI3{Y{#jB3|6)c~U(R4S$;R^p>_Nto-+6 z*{5G|F@-J~!pgg6N3rTw{W$bSVVR>tpZ$lOv#)IN&ayfXnkdLso^?cgX(e~KjUkVK z!cp5JOH?PAdvw+Zed1DeG`VqTuEhQem(O15FiyJ6zKxAx@1=tY+~qYtTW5UY36JbJ zKYz-#-9NrezPwEF82^)LKYtuzwA?#s(m#!r?i^2z^Q=l893D35%3XY`u3nqSU0n66 zd&-vnHPfaT2`uZE`lqy-*@?G%rRdHpIlB|Qr!1M#?{9C}D!lfOn@^JR6i3HA<)sb_ zr^Ro$*{Pk=shQHL8Q_@J(Hre$Y_zXHbxQh&rG`n5x^Gx0rSKnSVD!>*ck)v+yE{?p zKeOnxCuR;SB)2x7)JLz=UwpcCy!>vqpOsxQCHcrP_7ie7sTP*0^83DY z$E8n@n*QWk>=q4wj-%S!3RKnC?0k8H@!&MM36~ib?od_zAE10U(0Ko(N$DIny))57i&l~0-*GaGIc@yE(8{4{mOho{FbI;d@3r?9PWVVSMFmz0uOegb!R(cxLM z&&dkZWcJ;9nXd51O=I86hiYDD6?QT^z3t)QRw6~6&)n;ry5#;XQ<)gB zxIwbx)PyO=1ef+2PN<7|!W~nmpmtV(t2ic&CnaX#^VBTy2|rG8C0$}z=*4-nCg_vt z(nLSMUq`2lbLO)+WF zj_NpR?Yy_6OZi z*dx0pS2vj56c$#S(qgLmPwAyv$(N3%k0%Rlwy}6?Ea=eWU`t+f^qGFu&dH5j47TeW zJ~sIF%;J<4vwP7wd(tU}`Ef~?#WcT7o^1H>DR8a+*hup#ax-}QiDw)R`@HjeX*c41^H%l%x;l3k5gOq$Qee)(Xo`Ete;roMY0-TWdQPWUeo+puKS@+CIM!p=1u z$q;<^;$_RNvIA$F^~>3eY&t!qmptK2I@B}opR3+$P0#i%8qOW1{FW~#NM%kJ%asgz z+%TohL~pZau6Sa1cGlJJJS8kkrWoHiH1kSL*SdLPsU`~_Nb`Jj`68s_#OT6*{(|+S z4L>=fRsFM$y1egrzULt8e;C^f2^4KL)&Mw)(9lz(Hw|mPa z3B!l|dFJN4eMgRo5h?D`!?PG+Voc)ig57TZnFoOyB{-vbWkB|R1h zmpU-j??kV8(W#)M&syugw4e3!`ec7bF6b0v)l%i8&kqt-dtbP$X=cYfl|i%6(XZ<0 zG&>E$cA5Oezb8uk?!4&yzQm`$K>3M!(p`rzc9v*H-}gtFv>SQ1IdvzpFlR00^m-(6 zmzQ~>-G-;)UXxgtKJ@Z?c+hu&afAQ7D+b5IE>3=&p7i!;x|yBvhnTTxuB%^ zOc>UB}-JZ zmcMOWr9I)VPp9+=PxBjxsud13CW<8RGG-msTzas3o|?nEM{3CjCS-YUaG1v5c0lnO z@8X$VRhBa0tnO<~8t3gu)H|-)r{nLJ*f*zb#YDdisbNW4DN$1owjAPp7MJxT-HG*T zz`747eDAj$lDGA_aP{yTRkPelw;5EY{L2VzQ)<^VeD;`&JLt0B%0eb?>8KXQt)Fc* zU$R8%?tCeI_wSJ#{=J*p?i3uJX1_vo{gP{{FB1KHWZTcKy~5>Rlg8h=<-CE*0f%Mv zLCqbrKKfnZ;V_>zk5^aN*7h=w`MkK>8ElLFd;*k<7anId?A7v;iraC=M&dHd&WGMT z@f%td&3<=iDt|c2?!h;|`ou?N&3}idU%L3$?L>^%CD~2Z7ykNW-BK1=_M&X!EB_>K z_LA~|M|w$bmYCeR@K(XhZsX6%Qgbb`me_0vK#*vLXJ7=FLV_Nq?b?Y`suT(?J zJXN*3f?dX5SsxBc?Bj73c%a>X;^b{+S(Y1@SU0A!?7Dq&9^=8Vjz$@?DNIvl_h>37 z{b`qTd=lbw#Vh5=uZc4bwas7>oV`19svgJAnPRLO+e-R|E7 z`AJNetoGq2?@b%8OLhx49DEjDvOi(-{D3_I!ud;<*aux^TzlDYT~))ZZ$i=ME-A@R z7QSat9w7DoPRTxQ7P0gf-xmFDo>8E7?Y%+il4rSXjBGdlxO@ImzQHKD;)uZwrdf9! z*;f#nVo>aPHuyzmztls2pBWdGV=_bif{c4FDeqM_S6UJIOek4w>lzRw>-+S-YmaGcd?cD0*GOX68tq@EHaC0qV_D zJ_&`}JT_*2R-W>|@x~P`WeGM*2mQkwKWD!>{(*1m0kx$YR8>Fngebb?>{2;aJ0(Rd z$w+sX^oN`7UKNvq69TmDlZ(~$40BpV)}9v4$#dlU-pFGe^q225_g=2jFB=-C7VbF2 zqvpSMQ$y6Vgkt@zXVg^rc78OmTQQMui#&Ctzaan$=No^LfL%ogD&fusaAUS54B`IE{%-& z#?!{*pA)xuSu|%W`$7|^JjT}3F<)$&_1|4Q+;}T<{*67n#q5?-O%H2GOi^_3x#_fm z=g2cduge-6Qxy$=c28+g-!8Ktz0z9Xsrt%J@#qSH$9XlW+-822|N@^DcAFIVA_Pz;AI(zV$eIApne+{d}rrR1HPY2|t3wh};S;iQ2Mp^CO z%Fv5R-SSRPnfHBZ(DgO!X>ychYI)QXP^B_uo8vt7tvrfT_7(2zyi?P*TF^Di(m-gE z)xuqDB5W@*xuR>p1CT0H)H-|Flm0rbtyo$f%{qPePEU&o9W(y)YX5)W&E0Ie{y~>= z%)?kXPiioc-9c`xM{-o&diF7${g%Q%8SL_61L;Ka6;G@DO{n)IsrgSJnu3tToreO6}L4w^JQd(ykZW0J}GFy zWvgN#F6Ja*BU>%aBx6lOR=%Bu{(bg^p?XVNbT>ss+&VtZtYBv6yLSg;90E`0-Vq7Y z+F-CaHR7T1?1<`(E2YnTJZ*4@VdY0>pF0PyT-bDH>5&|-%l8Ak_aB+I{>U}fB`vmQ zTb~?}HQOFIE0l95v+cahne!a$6qortms@a-qv}WV9mkxC3rg=^g!(LQH#e-DAMrow zZ3EBNL#=Z<4v0A{Nzu!ZoE-Pi?JSGKTNj@!HPw&@6J`~9YKnM#v{o!G{5kthiIZoP zjLuv4oVw$p^KV=cdd**x$q^o>IAvX1v}DJec^zM+H8Ta`V!y z*s&)^xHp!vo# z?U5(>U%r?|9GW`sEz5-Y8<$$Hsdn(_4JrA0$N51BbIi<{b9y+tJc7PXjH(cd{-H42 zI^d&&C);AzhrT&83WPV>w*)LxJ^uH~3J*`t;;5F74kc9utJC z%Bq9G?VE3FOqH#x-l?GjAH}A|1%Xz0@nyb(*x%E_3)Ny9jhb?FOmDe#lbvMns zal|>RZJEmELjD5v33Co*D`*AP^fE=HEpvP5vLa!DYpYl1OlCoGo@S8)hXmtiG+eo$ zbf#mYbhxXV-%rQxBIfBcr|ja7FH$tUs_HYNUMU zFPYnZ`u>Y|i`-^Ro>js*)%D2~`5Si}*2Ndz?AKn?QTX1W#du$ZV?T2qmsQq{KW!Ho zAF3^Wc*?hRVsh1#)i;C~)}3Oq-SFY1>e07HRLZhcLf$zVaJ%-zCnmQ0>KZ<5So_hH zxAun?XA&1@(Orj3I|bDWczQ)>acBTG_m)aJFSvvVuwx7*& zdh1@3*>K5ddQ{<2-=$@?`zlf-HCxRWx-_lcaCGX1lfEiTZZ*r;H>)NJ%}%@Umy63g z=}&`pkH<#wWz%Lfan6=X**@v9T+mkmX|t9?4R;LGm&z!p`Aj@KKVZ(}B)P*H2?|#< zr1Bnee&#Q-a!Tu8CjZHZ)%3IK)>HZ^^A{Y~-ulWu=rXtEw@2Rdm)!8@wLko*O`FIGzr*zy5ojan;bzO zAGW1ojSe}76t3I7bKJt;9 z?KL{VlattdHmB&4q2Cd-TH?di@x|QxUwnV;E4XdroK5%lO}PsMNKu_ddGK#kb?QY zj6}V4Zj6SBUYX2-)8r?-To_aqxLe85j9+Bkk3(fE+Qb)r;=g-;3(w<&^Ukf9Ywn?W z`$gor04e?*r}S%{O^V(&G5DU~rtVw4nJJ%7aL!&B@NZJkzrZN>#zV~kJ6pB;Hojck zR?Su|b1>aO!?)p%Mb+v%%oalatL7KDS}dI^y^*ssYO2O}g;{?aQWQi|9noJ56raR|>P1fBMsvZOfZPxEQHpv$6rA2-cr%dL!g${=hwvn8>EaYDMM z=8p|4-M<-Git?QCsj2!X>c(@JXTsxfCrN%4{}l(FvhGZrd~@RCS$DQLWmYL)`O$iE z@*}&52!YwtJ9w>&4s~346cuB_`!j=Fd~Y(DRNLaade zV)LTV2MOI3HIiK6P6tC5JSsLf9H69vKk6u1|gfE9R9~IvCtnmXos}E?Lig$You0N-gQj z1*P}=ZD~A~FMDR}V4KN(SfO5s%RVOU(Ixl(PjX`RcT8?r_sH1Y_@s0&c*6ze3WIH( zoxU+AI9YGX9})YrM8zP8o1^4wi;&S_0j3>?Wbbl65n1)4i7`cgp;Jr5cEKWToqY-4 z0#`3uRA!}MHdk==au46O6AxR~O`lbFG*xWnKc~L)2PZr&Xq8t@bbnjp?qd;{q`uBV zMkiHmV`kf(JszG`N5tF=$^*3juWBT#zGI>t2A@B$N^RA$O;VB#S5q@H z7UGi6`pKHYzp-=1jHb?6@084Y1s?mwylfS*{&=%lhOgyLv$yWL4NuezvKsXKy($8f zV+vXo*FJ8QsBbVGAGy`6&tDX5q2%Qib8*o+rR_cs)HeDY7xTa4vS#V=W&JmH zbxryp^`b)2)L!UuT+GA9b<=0P>=7zgY-iLf=9nt4V7%g~d`;%ODSsTY?reIH{X~E( zAy3NZX27KvDr$#5{1jJn&tY5Yy09}&vEhzW&cYVCvMZ+)cv2XW4hz^SUsCd!_|}0x zJ|@wv&-%jSu7C}KMcmuIc&z=PcrCB!t+ScDnBI#_Cd)k&o}TcuUZNJ5QlD6?y)u>Y zuma%?YDu~{($T@u_@(Ec+0;PbGO-XA)uX3Yn$1WFaO2#M=`f8f=!WS6{1-jrXB zS4y0`mI!B?ZTz=vS>=heKyBxTt36J1swW+ub%l$^Rz`CzL*df&q(|Ko?oOG}d$w*y z<%vY@ZfUPW6R*@buGyb4@&1Xm(i86btlNFU_wtn!_AQ6zNG1CA8Z0Wi>zi|9Vldx? z+4dWsI!8QiyY+8*sid>#u7z7_7N=S^osWOAOZu))&?Olkea$j{m!F<~k*=Pz)Kz_U zek^e-c!lwDrn?u49x$+7vaEbURnR37)6cwSyCqk!uvy&~_KLs4x~^QJp4Ub7BA4|n?6J)?*_%}(_vljZq|lgd4H z7oE^e&X_uV!_wHKqaB>aHJKc0$9tFZDXHD_)SdltD))^$haB7;dg6C<=3IW@rF~_^ z=?$!$h7Y^6{U^?{n{ZV)+Du5e_sKK;tgZYjt}!}(*I6m2Y^tav&eS3#XPCFpb=fjE zyJOGFV)C9YyEsoKDwOF+3%};aL%vURSWd(x9qO8}|6}MM1hIXf9xm}%dwwUcf6l89OZ~qXxP52d_>(2=c*5GrD+Buq zCSPPcIDMaHq42tjMPb%Lvn^Xb87P`hoNSgMT6f~#VsCa9TL;av8dE|vuJDCqsk};zFdYed(Q=8!l&h@fp|jr&!P$MDrPkZ_xO&c0RP_x~o|8Fq zi-u;ogxkRmj>d%(+&nbjubBGXaiYK9jeyN_7MDr-XgCH3trv(c=XHtY+BEq_8N=2) z$89~*9M~4^b@!17T6|}r%KFLD=b0}tHd;=b$IBPRrngo|b>D}B&*bx@${jZBY@cAA zQ0RNMtL0X!o~kJ8#=L{!KM!i9r)=&xDg9(gX3=Mvoj=>Jn0T%|C%5&qSQ1x-mlmVf z*Gr3iT9-1$Bzk+yllm!UDH}9tTIR~>QoW2{HY}Pp^T?CrtSic2bka{~YI9z_c}1)J z!_vyE>48VgLOKK6&*t8^#JBO4#@XL@M9xf`6kQIQKAyEOZFkGO%;uxTgOS6Q|{!g4BvC@jEXP`HPiR-zi*Kps?(qqo0-X zc17mT+G{_H?0na})Y0qf#}D%0Jn`8g1FNcHhCJd{6AE zS{b*MF>U>GYW8NuT)8DW`$^1;mNB(_9 z4HK+Cwi??NpX5w0I_rGhowrZynZcIIhRo9 z!Y4hU^2m*T-F=;<<_jy7mj7w}*&6kfW7~#N`F3IQ>Dv?4D*R^Txp^xx((*cM4p-vv2+D zbiyX+vzpHT=8O{i$&bo%9=67*J{Mz5LXUh^Z~vF;U|0mK6*R-xlo_o^N|c zWX`O{ckVN6pWO1#vQoJgzvE8lS^;-4=9%Yxm-guy<~>l`9O&#N*`(d~;pgld6^dJh zl&||0X;;mtoib(Tk!hQkO!Is)?f#EPZBu?IsQV=$_me5{CkmZ%c6xg4J>tNqa9ytGw)l}Y z`GsHHdUl^IRc4;cuyDfySIh3W{)>lJ`%F>u2sn^%c#4&n$buh2Vv3bBW=pV1JSbA% z$=P+QlWDd!N2~5SCm|KT6$T4btS+2Y+t#3T)Gy~<`%P!>{SUc=lkWEG+H4TrcPFKc zqvNB!=_gs$w1CZwP4oB*o{GkNbk3?$JXTYa7Gzu-q%7z7&`GyAAgJdbPHK2Ftu9L^T0hkoY|@!#Y>a^tk`!<`RXE(x8m z{c%Zn*WV*E+O?G@M}2s_ie+QxwTG|#jysM%ha2XclG$mba*QwQIde=ZyJ05Ve5ofJ4op>ZEDN6Wz0=e9#6xc{ zyF+PaTR)pF{L`-ccJXe;csm!f`BFa_!XqAee?M|f^v9J%4?R~!OT1v=SgKz1Xr{z|p-t0e-U}CL?_o9)n08rdfn%eKcJa!o z|5m)U3o;VgY9y=LDqwnO;)K6_N?UZ5I*ts%)!eNnk zS+g6j`s?=)_N$)mCt``}E!=X$3L8N-;kr zEbDe;?m0OnWWPZ4w*|`$qi#9-&2;p<)AZ+F8E?>AH-GOdKK4tVS(a=U-pbB0MWGV$lgTftJ}gZS_#yCGe8SEX zSs!=yO0N}mU1RT2s%?6x{mu@>Dce@eZDU)tLWbw(j438wUb7B_-wRs2#>sqsz`Ya+ zwT3x0ow|D*pDE0C?c4dnu`5r_XP(qYU%xL0?=+vz|8Yq}^IM|v{D4aDuAc_wNsBuT z+c_AzNFZ0lG&{49hg&v+R*Ey!3oF?-5G z@8t&dL6h=24Cg0uFl8O*t`ZQKZ9d_v;`H1fO;cw5WW8JGwRqAM8*dG{4%7ZQAJoG5 zx8C94jxIW7`lVvw6`q(<-h~E=X1z(??oW;gYW{4HdT1rlWt275cgLyPtmWxWsrMa@ zahvVd)SSKXr|A63Bez_6jaN)9A)*vY-q#yS1)7sHE}4j&Pj z(qbgAl{@T7!-1!EPMs}cteWf2_+&j(6q)x#EaJu;!wIeO>)6(JePON>{Imi6+@$veHiQ*-jfuR_6bhaO4V z%3V0?I8EJj{=*{kwU3$tW+`3$+w#Zngk8-)moo06d55R{?^wBgWhA@O?%qo~l&&Z^ zO>^JgePh$~J2lRkH~rRCOJ;Crcs_n{PD#XW$*tDaF^f#(Jb3+PSbv!Mazl;B*%eAt zre8SRIIWUDI;Q!}^4G2{N759kSa}wD9G}{-a-zqMjV5e`JK3WT9he%yp;}aQr*HLv zR0$P^@G3_!b@Sqhi~4VTaq?pHcd4xyGM~3qG+Mer(m9bMmY8J`=AMXOyP!PdMvVW~}?k=!EW(Y5iMPOz!m6zwwH# z%Ix)vYmADf%okTPF|nF0JT>hWtNucker@N&UoL7LPVlbyvZZ@ci~rdk7v0SrzK4H& zV)Nh&U+8n*rb#T=K8DLPHPU?#iw>?g~#iyrk)h@CR!>Xc>bv+lO^y)h^< zzTl8%63Y?aLqQT*sXR}-rrszxI=xeZP4j?w+z%tEZ9h~*{Ei&q)$Dam*?LFh z9&e+5m4@!06DOsQEVGQ6`p!YkJm`_YY-`S=+M1bS@jJV8+E1TdGDY3M_=IlriHrVy zyHEDY=e#>C8ouL_{L;+kxRfb3%~?WE5p+x~d0-0$J}z2(ZIV(zt{*;IdaMAT1=at~HMyYYh6!=Oi+0S5wu zGy)%)JBbRK&wTyT^QybwvLjE+ViG%b`#f}gB-#`eRR2EgQV+0rq{Yx-DnDED#up*4 z%^NfhJy(ml=;32`B>cj{-P2{vC(JtH(P=;7=8{$J<@}bFQzz`b!lj<{m_Jfh(YEDJ zx3B#|gSM9kr%&tfW&d%5L0 zFR_w8T;ieE{u_51PV;0fNp4eQDp;BuA?c>!_o3BXGto~YuJEb*4C_wbyr4^O99$JO zU-H}j^Wfz#`r~m~HR6a^&Xul$C|4tmqz|qtC*~g!sW>9mHRT8M-MLRh8g|^V6yXYX z`sm_$~TC>;gV9m{A!gj?&e#w*ktm^hT1;@mXO_}9> zqCO?o#lxqy`CWmRmS&#S+_ScIg}r?-bz5t_q*E;KSi*@fmOZiq0ILy1rnh zYj;iaY2KDkHoBK()_v-m!e&>sYq80jf|u^%$3xd0copjOlQBMSv5EdgrN05%^^<4S z7yN9EDE8RcKV?hbocsx21vljz9OX6VWq*|!$~W1R*=hYLPRpXqnFm)sln+wsxZ&cR zw?sI2N7EmlHC91~(l>}s`*DePrKH&Os+f;0`hO1{5?RJJ-TLC&Bg^^%?kSkdF5Erw zQjJrm^#pB>l=25c>Q~p^xTI@YDHR`eK+WAt?#T4*96LqBtqxy*a5!CU=euRC)))Ue ztla%^sb#hC7vh`F!)^zJ5(`xTTNG0t!n-&o%hH4XxUIEuTAOindfp1b^etX>DRY}lXV|vrHeR-VFT^Du z#H~?u*WV}AvrB4%wMXyogA)Qf&(3MN({)-VC$Z_YPEA(l+9?Sy8E^6h-EqsTQVO?M zead!X{gqG3W}7!mm45ND@$}yxj~Ff2b@-|uxzVi4w<1(e__6$x4~NqAH>ORTw9Mn| z@*AJHeR#s>1Q@UD%=CEZHTlOO)-=6sHIA8a$qN_)v}GT8Cm(rcne(wn`_6``j4hWq zJ>Q)hQf42h6*(1?FH*`43J=AWW^>_e^P9lr5DE@|)U znjIkXaI<{;O|Lu&0qJvBI=u6gq-QGBU((W@eEGxy@ohiOEKap-UK`_F&b@C>kDPeR zC1bPtM@I7{wm&S^UbjQtTux#IgGZ;g(>s-`I!RZAPt9*RWu0`1Z=xA|o)U&7*Cdx%b>1jpG8Ug-6_aXQ zHRF*Hvt?h$SM!Axs;Yk^*cb$6>v3B0M*mxM#aiS(vlF-bL+u=no9^e2IOy*FFw;4w z&6(dgC#~s7hi}glwWuH?3*F0nhBG^b?1Plwb*@zK+}IvsuDF~%<|V60-;GNOML&vy zGe1jPess*VN%$IP^wIZSJDm{u*Z=6zOj)3l!qplE?hu zwD*r!WlHpNttsS~#JrO~{GW<>?Sx0^NvGJdOwVZ;wqG*pnN#B2CFgax zV~UBp#$JWz@-w0$W;r}Rd`V&DOL5zr7qa$09A4y! zeEDLt&&8$JLEfj6$8vJwX_ptAjMM*rOigq8x75{1&9rCbOSYspYDev|+U0j9IFxYRvJi*v@!B`uPMh2B1MlDMsNetp;}I9q1rL)W}Y*AsGI zHnEE6@A%`?XJOuWPD}Nll3DG-=_{8U6D|7blT+p3cmIk<_l+~kYJY_$pZDoq?_zB(i6CbS&p9(X}Ib_`kN)juYm%M;U!PH-HvYltCm}RQ=wk@qW`c;ul+O`v; zml<3T2vF|%_*6b>*W6j(CfPC@1u1@-l-3u1s#_ z){5l;#=VVimZjBPylqqRJ7em%52nXuYZXA01FDuy#aCt|_@Rvlj>}ujkk3X54&kM8*GG;L~5?I(ZC9#2_>WAPbZS$$qeg&M~ z-NF@GB*mg&d*e{!jFJYKc|WcQ2R8^9ai`gBEEAFzJMv@lw5eRGgm%=#gF*M5t^hAVcHwySS znX&7f(cqP4<6^9`XbX zBR6}}A?DeUSG??*=kj&(8aw?Ii=TB+T>ZpDf3H7@-NI2zqKh7}PnRqCo>;7}`Au>4 z(KNG-4;@#@pER8=QQLA!a$SvY)*a#3={ZlC&1d#<<&+6cR&%IZmS(kNiI%GAoW!z) z&vSDgcCDLsV}~2Rv{T-aEprxz1-C?{+FL$5a7aGhM&Wnyh8D@4iT)bC0@8d-ZuQHU zKY1q0CdHh!)Y`AX?f$6SkPzQqL>Bk z+8bG|w?2|jli&HyA%Dk$<$^K)9Lw!ZKPlN6dvq#$T^8T@(K_Ok@)HYX_49(lbw_@P zMoTqzKD^w&I!8&hS2&q}+ZNx)xFx)V5*AF|qAaj<6a&WnEX|=DGKr zL#n}yOUk>hbF|9us#;{eF!}SB1dk_onlrk3W^)}cTNEzBW5RGm>{j!}PcC{K1+2Ua zyLguIM_WvIonG{reQ7JF+4rEu6V%jh@;+-4cv6?OG~Vf-irHSp<yj1OwALq4BBf!5#i20q;M3Aire*Fp#g=qRHOh_gyF#>>o991;EKV^~V}-5CZ2_!K z>-U`SJ$#P+M8AO#?|*^l4E|?b{P8m;Jj(lWs70=h?Iz>lACD$W75Zf*dV1av^qS2a zTX1=ij=~f5n5ps`KiW&&5_)pvc0y;i)4K!H#ZPudw<+>@^qL1Gd+D|cv5aDOySR%>Yow2PBDDJkrsW!tQ8Ztdvf{*U3pYwzmk_F<|C7l zyroZj(*Fd5<)uld8ERg2=+2*T)%wK0{)tUf?HcEY3cjT^esX_nT%Bk|4 zt*je=GTQFg@N#kLP7l8l-eV;WeX~E5Ib2|_wNR<6dhQ!AqtRevqNktJa`!y}n;n*= z$_QxLOnA!KYO2dEoAd67c>j}QhI;l7Ry~;bm@QU+oe6{YV}rdfYMeg$cHQsrZ2zLS zd_$|@nYl}rDdzlZZdKQ-zi2e~(4#&PYqm?aI}UZtC~2PO_wlHr?VpY}a!#4ELjF&j z*_bQs@iQXD08@AYjZ>Re?p1;I;Lq6+mnKi`z|$Y*udkK<<=}} zaKhxU0&~lu-dpEXw-q?>6?@%v@R2(7TrcHs%b7!=D|xm#Nr^1`qQSo5r?hQ+fOc=- zW&0gxl$K6x(eAl;R_&@!M8(C!`=1=)-S=Z@xZMKxTWYE~1wW<3D;smnHpPGV**#;^ zRH=tdpSd@t2}VDgJp0;(ue{rKuwkQCq#eN? zTy;=v*&UTUy~EGsgATKWGrDIT?!IH8xXelUXin0j8Buwze9BH~LDp{*H}?lDZP(5h zIMsi|%&MT3abumjDi7yV`4scy&+?jyt}A~RzEn4jojjYLW2q>c7DLjbK9TRjk5#gs zmu5{_{^OH`Vcnr=>n47kDAl&)2WR*^g(>wCY!VY@uj5!MU-K-9TR6htz?r9N1{&TP z>pmW}Uihi|hEeyV70O5d@-%Y@JkIOkI}z|zN9WGVr*$zi+2Wg2Rh1tFo%TIum6gQB zSChBct<|l+r%U_2pw@$erLrlXKZv%x`1UBMd+h<1m#V5c8lBupZxmDP_TK5z)hle3 zUsti*ZI-h6o{c+2r%M>7a_;jI+Uu02z|hf~oRg|)SXDUn;1#dvD?IvnOw3kGmRaVc zGBUR|+%WN28NG61{|dq5Tl5|mO#S}j5WkAMmrcOxbBPiP4xTas!E%Dhc11sX_0Jaz zZ`5j;-7-~q$0_{@`#p54SIqssGI04tW6y`&-V>|?tQ1;AjClkP_#R$-s^hH1k~Yv#3hs@n0KW1Nf;&}dy%bNL`U)2p;)ru@GZg%v~WN*3hV^P_xgV!At zrhGf$nSI5B`;N+)h@{WVdgYIcq&NOknIeDTsb+42;3fZ+yFGc;YZA};K2hM`_*8c9 zB{|if%=6<{%zUq@+uXrf9CXLqN6y`>Kkh5DWoFx*XOgzB%Zg6P2HjFTGL5 z`fq(aX3NokSJiZGBDePp$q%zHeAG;mIK=QoKTDM>XC`~}LjTN&Nw4FaekFXmafhcn zX~ylBfeeqh{j=09C)BTqz3_u%TC{XZT}llZ-2=5&wVc(2RKD_JcyANId7 zOR3#)MnP5gQMa+zCytdr8>f6wFnxPz(VB(Rq%WL3D0=Y z|6yr*))Vmw)*ELwYxf2Ug-x0Ef5)LI(@OQXUXoau%5PUa@vpar-HBfPpsx#89}neQ z&@DXsdMD@p#xCus?RzI2=CEOI(k_r}(>M@5Vd7)eq%(_;_~j{8?`#oLsXFMIvqvaf z&+PMwtKK;_7Zw*f`8{lTQy25GT|bB8sHo;cXN`FqcQW6sb1Lk3BbM~IdCnH6p81_C z7bHBJFe|>}Dtl17zD&VQ?#s>Eb{c2z8+@NE?LK9hWzZ!-(@P?H|AmD6etcqC_~Wpc z-;p1(;d>?sz5j7#QdHl=uKb*57nFPjwVFAmPMq>%`jk)N)2%%XnQhl-awfA0F)Xc| zG-nSBw|Lgn{Y%=6_iZ`l`>2P>FqP5rDeFFsCEF@_npqb7<`(hqaoGM>eYsJBgiFH| zAGaJwuFrD&y0|PkIzrp!a&9QGMqijTYi6hE^a=78F0B(Ip$hm!i=X37flTY~eEM zo>l0$e$%`uH4WN-C%n$DsZ$X#KQe{+$&<>QXG*i3bD|VN#07-k9ht`dWQz2ZE1_3B zjCo4fUL>|$VwBX9TePJ?(fp#K__8Y=H(s==>XkqAx^c&%>T`>czF}tH6oX|;7?hU= zC~jMH=(&B-CB75&KMqZ~^rhqU-XE7V?W|X>(OXc$LpL>1}@;{PsF{?PIl^KdVf@i2H8tm2=K7 zE;g?2ar|yx^-E24t&sG+A9tGG9SCoC|DJ6X!CGsjc+3WuoEk54>$`zKAV)6nHPaq{*Pv9=p; zl(s%%pXr$OBQQvD;cm$kv3&;WD*fmGo+z6ryxyR`=<-hHrZ?&}Pla|q<=qcS`K{l{ft8 z>T{#-QOM(eWq7*R&|Mdn%=sCV`_b; zb+3G~-gSEcW3h;c#cR*>g`Mx~!^fxg@FiQ+EFRjjf7HpGxa(51!>;__KLZiOc_H&u6N&hI#>{o|7KI+M0_ z?Ncn=_=BCQ5VSs=1kU2d8&byZOdvlV9^C zJ?aUlS$Mlw*Kfm3=NzjAVY{5n+2f-W)XpkQ&pZ6TOJoVDRm_VomA z{iI8(cE%fb^2hHH_+)Nb$W_F=@}Xy^wB!q(ggn_P)eZ%!T1AIBqLUVzZ0ax+j%Rwb z>{C>JkgD!1|_*Yuq` z?)0zEQxxgD!!oUCQjnbBCw0Sj%T4%&9 z*Wo$+MWy8Q@1DK+MUPvj*tF~C3qRHm`fRTF`-7@%%~Oe8GP zf?oD_RB|fRP0x6GTJw}JJ!vsr_^D;~88+^1Hr_b~0gw2-PT3VL?!5AcBdGuU+#gRo z*G})?C zReO5;hA{W zl#fSdIQmJt=h*hI=3(2}eWPg31o;g!olp25S(ZQH?vZKkS3dDCEb)8&i1qIN7pbb6 zKLut-a~>5p{5es?^v5Nwt%oMbl}(s6Ju$ImD|3@R^ChLmi&hNVe9eScPw!nfS`LjFjbm-gQjPQLKYm@ecbvR4zkOag$5Hu>mA#Xy8m?Hi&nQ?_7L&MHcnV+PRDb5sB>{_d zTlC+2xEgrlld9R~f~l4Z3=XH;ZL8{(df0Qm_e+O+OeV)Y#)H!`IYpbUlvtQgmGXI! zr!>X0)01aOnp2+8vNs!4J!Z&zXePXn4FB;+Hrz>hThM`2vuzd*;og1{6NHZ4cyoB^ z`~XMS9K{yhT7lq-AZzs(h~^M|X? zvm5mXFV1!GxqH?(Ww%JQ1!&F8ul_k-8nxqgWL`O@HihrQQpG8J948hu7O3dHIWm36 z4$YV>M=xg9Wn$q;N1plx8Jn95Yb|Bv-ukEIwCoczgN~CkuIPktikck}aa$r5q3}JK zTi)vuyXj-$+14JW^3n5@uGJs8;p+9z&0qh=Cu`8ysQB8?yj!Jtmi(HUIDw()&>V^V zL6hzN-^dlrT%HvM5LGG52x>ebk- zedweo$Bsi2XFcpbegDgv&o7^{B^~OG*&ZAN$VRFF9hr^-SYZ+pHPxJ~JM7dj}nwF(LLv z8gEM70+aa5r}S?ek`A|WIKTbImq*;mPKDl{|CHSIH$D}xy~MjRRY~`j+?6usbp^`m zHXo---Z;cGTlUDZ>^4Ovj#lMkzAqLqI9y{%3ZC@xg{0pOC6T+lFX~i|_I}~vkJvGJ zlH`krc3C22N0w=Ny?vy%@wh+l{)3lfAeg34H<~x-OkHkNj=6d4~ zQ?an!_XAHp-0apn?tAD~Y0zo+n6f}+pN%seJ?A{;GA=r08es9TNPeG*civy-)4L6< z6KiHvwj64m@uQ)YdF!i~qDNe|YlDRDzer^3Hm<2;kNy)dY1+ioaW#ega`Sgw2|BEM zWLIZM>5(P5Nr&f&)ISRH&a#<2%iObB6G{qsVh2Oc!zO*+i9&og zv_76vwdSK^-Vgq#dz>`ZJ~%DC;Dee< z|2nqWwLH!|6CSe%oo1`~Id%4t+O{t|aZdkKo`~f!Roi=L`cHhTq?Z5Kc=nu4jWhN% zu04Cypod{!iBFIDN!@yfG~rFNrQVt(opC5%!S1s(eB2t75lsxYxW}oTjEC(!S%5*$t`mCn6F@mc{3!DK8hUnJTex zOXIrfVws#z{BvH`8yr{EeAuu?EZpw+)cG5hGI||iogb~CsqbkjKFx08W$}%fV$-b) zcQ#Jh;HtlS#Y{F$-s+$`O*!IKa%$#t3Xfh*$k=}9Pm7G(iGNF$NpGCm`Qs5=tnH>~ zj-{MMm*m%d@jJW4XSIbpAAgFqN2#^m*BxitZ@R9t3p&Jnm-osC>1`J7e*c%;YSiZy z%T0kN3^F>cGG^rygcNUZDSv5jHshaOmGoA{bmN0=mz=bRS}~fQ zf2On6Jg{P1)jl z+NMMIO+wO7VfT$C)LrvkpB~D>}`TbeVPQB?H5svqN@oSg9`Z{KlVN z{T$AxwqHJ|tIqqdQ$9s+SLBU5PB}J7#{4R7KJ$_m7(4Kb*VG-cW_I#n;M?*%;oD@P zi97E2_#8+)t#CwzDQic+#QsO84m=TYnX+r& zV?HU&#h-M?A?KF5S^Q(K{2gB=OD(_hMObn7%BgWXJ7+vwc117ZhtOob4M$nGRVZKe zee#1bT+*9&v&YKrf}PAadA@9M&x&$4>yG%p@U~~(pQblzs_!Sv?myXU9(0;9=v8IX zsi2t5R*C-;qSPh|yS;em+$XtY8RHj&#+#lwF%N^>yKWb*RDHtc^@_8kUf76xwshf6 z{<}Iwj|FZ2E}re26=QgTW5Mq3fIScIFgLCKptAje!jt$sBkkO*9qm(CTD4<1R0V?W zcIq!wn(dm|q_#9c-R!K;>#_-zM|RDh@j-dYkCmcfHx4mAv&%ZpuJ^g1mEBx0`|!oD zmyBXQw2J!liTvK!YP@a3f~oU4Lj7L+Qw_CcW^I^K)F`p_$ui-juYtGs@`SK8Yp&y5 zT3B>y{=pc&2VT-Q4l%~tI{EE*;O%zBtbfiY!EgzM*{*qeyZq%1zX{D|T^Z~D$eUTg zGU#sKYTd@Ocb^<%H$6026OS;=4_x?`GoF%SZ|0iBP=5R!RQ+;Ql`O3oXcj`3{ zyR|DPC8?jO`C`=3=+!X$%(24>=XPJwnqRDnh4*t$lTy*z+;V)KRXwq}G zF6nf!Q)1g$nUwOtS!-5K_1Eb15Bl41Rxjx?%i2$hX2mNd{g<=|S{6Enu(RBqd_+WM zi$+CaTF_>N1tyHir#+_3^6d3#)$J(|)tb_#ZufmslG#2dNwM#DShSK#whKgO1VlL~ zq*r;JVVc=2m$qbvdr#C1*&|DglinVi#$Pa%@x~ty&q_znI!FHOq|4k}wGxWXEHqi0 zv{^XZ(#>m+((}NWUl$I~j{3^7GSSIrPw*qNn0E`?_Fh>bf8np&nwdwIu_v9D2s*8l z^q3{uYO$N8WA6s{a_MyjuG_i8cY5Yn`gv6y6F+~VR95#?Zq{+x6TLeQ^+kMN+-_)k z%FydBOR@F7FV3q!O$+$xxMr`5?m?$@5f^NI*K)PYK4sgSaD#?z;Ba@|3Wg_~_`xc*6IHkxo`6v+dalQf&%b=M^)?(j6Z&a2&T+@g-^S6KuYzu{~(TxjC#b8B(g zpGT*XpF9cAIxfF&$0N0(XYBDmEoPi9E!qDVw3kp&Gjm?REVXN~N2Y*AsE_ZxqGf-g zmp$opbXJ?Zo%P37U31>)2@|u;ZpsP-C|uBP48E;5q4I@bYutm$ug#;x%C7L_=Oi+C z-}v!H@rixb?uk>H8Uqp?dTwt>U2-t2aiWyJL4ELP`6)~IlelxTc1TW_ym80>yoH)s zf5BtPDGS5qTr$?lNEF{zz|c7{Sdp(p>Oh$KL+$0AC%q4=zJGk$xOs1lnyGHkBl)D$ zVr)i?s$cE(_FgG7*1gQUGw-RI!2!Sb1`C$e?l`5JG)Y2O^QFMui(gLsP_WLFwKVuV z@vY+V{AR<4kGtbz9(J9TS1_z$<ER0jpyUJku$9)GmGc4D-4@erp#fY^zyt#qP@o1=Ba4vlt!qHYDa`xtQ4s zt1o0wHgi}RSeVRhUDd`~^ho)*{gyK?j->Hq?Vc@t-bB^((VU3-#zWI0ese5Uo?)}| zox1A0my&J^HXM0o9`kSMmJ7$1%SYEJu0AfV_v6rXk=hqoCqbJ;`mUVnj@Zn(bGAr* zpmNT}R&CSMoJoJX&z@^Mm4D=j?b4^b=AFO)7VPYtmMJxRZp$gon0G4bdp<19XR~TN z_#!VR?~qvBl@rc89yMMunkn|t(<@@atdt#^G1pwf*jb)<+9N*|9?C!^Sp zD;^VmC{4O?q$`JQFPBu(A3F&y+b<>_e#soOa*5EVQZ4o(YTb& zE3XAo|6{=to+D4)iXMqX?Bc@E1w@H&0tm3WM!qfbO|kbGZ@8H-`AR?w~3 z7g;AYH+yiFdwr5VA(vBkcq*Ib%JmwB>aMZ^CH_LM1!@F6H6D0$I%JtieEiuv+bcU% zQ?uuUZh*$gB~#J_vW}>(%u`r?sD0;TiM=o0DVp<63W_ugki4+yL9#?kgVf9Evw9h_ zriJq?ZfKnKR8v>F+FA8pd(uvaOiM4n%Dy%2lYX_$(D6B4;+Z4pbb|ND7Q>9dn7~=< zH!LmBQ<^S&arN6y?K>N8`fKP4&)&at<(9upPs&!6IXJKhePXFP@F2+Fhhfqs1C=QU zPWt8?`N1CDGI5ear?12mF^QH(`3hXtQ8zrZ9y)lby7{%b=IjX!+Bh+pU2`gvWun(v zC#m@4$#UNedYUc@EGXh=`1CvBtn!m0s`9DZZbarT843Zb?OxA+vYv!pO;_APQhBJjy%Bj;R+ z`a#2j+(uUQCn`HW@g!p|aur~a+bg8vl^ybBi z22xDU$}Ao$=f4Oo3*20DG<06Daal&}@yn|V{qt^fS?avJc<*4Eyy08hFW>Z3=Zbv! z;@tmh%7p5Vt+pE@IvJgJXg;Q_Cyi zoUe9@hE910r?S5Y-QIY|eP!&Gb@MYXnl&C}-dL)&@~i2toi7qk`L?QhHE+Co#`oyb z@C_D8imJ@Q(i&g*Y@V<*oXztxk}X=uXe2#7a>*^neuG7+&yG#YoGAVENsHxHZu257 zmY~P1@v{_E^A(pH2Ypp+x84<3bXGRcS32p^;{?qwn!MFDbxW7Y7fxlIvSWT+p8Sa~ zwv#R?EzN8UnCswIrM5ip&@=v`S6n$yjY0RH7R|r&t1GP3c%KnVn)=p9+~F3JrPO}B z3dz$ly;OL!QAX^`iuDCI8_(wjJ?a*e(EQIHoXkA^@y1GtSY5-c6CbsA?YtqxzR=;h z+9MIstex|tI-93#IFzccI#qWqx7>{X8FMFger4Z!*YWkCt}8o^PRo~YW3*t=IH|tG zEK9>TeaV!IOI-9dQ#I_0S4vJ()~#Ih{9+@Qcht04=1{rGv;0?1{ni$A*XQjv?tNyW z=B((yf*yTck7ZUQ;wZdub1|)7cJ1GsA;SjZ&Np(aKYAwVG^f z)m8k@<8qwY^5DZw^3!*FhWfug#<14txkKoqFF7_7rH&uondpADsC~wtR&5xayr*-8tLMy?F6)WwY`_mjvuAgHFqr zY`$=N=N66g9zMv}wOcYg?V`f^5R$_>{w zaWkxvxIP>VyYR4EJx5uB$5}+7{kKEd7SI*m3)EEKE?B*E+I-Ez{{>$DEmF)s4$Yop zprSTE$U1vcmb&4~;tf;lnPt;` zciy}O={Gyi>t!7iHmlB<$~Qy8?O+B+Pul_P#05>33?t^IwdR~ci^KG};`67@`Xrk_)7NvxFoRlk2i0z=E=#<3$H1P zxIJlk=&&R{=&j1KIT9}m{e5a(&zktXH%eBxq*+x_c)4(=s_tp!q{Br9Pc?%c%@51^ zxRgEWy8MqnE@vwarSY%5bnt~*iBd4{x)bV4H};?9DfxROMJC0z^f_E#fUxn4lk?uq{+`#h@OAaa^B&| z#Dz23*^@Wg2$UMEE0D-4HP(D9o%Bi6@U5=b?UDr>mY2;Dj!p~6(zmPbFr7W+Q|=du zI3p{C1sxC63RPNebSzb23{d_U5Y!+XyhCxe|Ej8}aJ?;A5(1M8+r1XEgv&hm^f=(V zxMgNv7%yMY;Yky$Pjt>+nD8utv%W2np)Gr#+zF$~1y(A~E9;iITX$UgCiMM<;U1Cc z1&hT6g#=q(aEgXBBnTf)7y16ewZ)>j{YulsTVJg#c@2Z^IOMcC=awtn_U5*q6xEr0 z+MH)GgACJ^9D$3ACO63VZpoSwbo%ZUp3@Vj*3(t^SLbh4xx0O}VoE z%evW`Z$%cg8=8GiczDjXO7LNWc)p74Vei*%QacwquGp~1WO4E18E+q`C5o}cC#gTl zFS_gh_Ds*&xmR=+uq{${>NV+Ied*b>-0Oq$jjxaRBdU90gve<@$Z)a&EVsWY}T z%$s-8xBAHvXRo_DQO#a%3JQ`xmGoIiiz*mYKM-_35{!HPMm%5Lu%p+&W0POCSN%; z`I1xDyqUAZ@|LZ}T`=pKYjPI3q3J;33 zx4v1JYIQhl!9wwnCAa!lD=a8`=ipzMtb8hg5+@3!B1fTG(-zz3A(|Fe~;gv?x z)#PrT7`bI`M+Ch*j@&J_AT`BK?|Wn$5D5{vnF{Vv=&bGF0cc~U=TN$gInQw`HyXrXZJ|B+|WtI8ZY zd>vYB8g+|Kc+T09^=Bcw-dbVlt;TAbes^jL6s%mhboYl=L)BKZm6=R8`;WYESFWWmd7~wYCR;{3bpBrv8Yk#=`pB)rzDIW#XuN7z;BKJF*y^pn z&Ba(k+T{nAWDu8b5|>Anh}x2ru&N#HQv`XF?l|}S-*A+5Uqzb4v4%+&&yE%E;?Qm8 zd6E{SEgSW7@}x}ydmWutFsWZV-)yNn`LUVPN8cWsjV~w8c5~00G&#=ms&n2vXMX#v zr=o3%d<9EWbG~w~TcDt}rf?~<*Q3r!DxVomhWlMPn=HzHfTEpH!B9>^SSY zD!ZAR^o=|`kF+TDMa}G-P`z?yL&sX5i+|m`(iVhD`mO)5z}3;+tK!g` z~*C)NLhXmvQ6bJ8QcJlji+1h`>^6aEbCff{-gl-E^<_%iivm`X? z*|I}HGD)A=c7Aj|Ta~t9i+l&H%W+wIp~cd$m`hrA7tX3)-y8C>AwVc%iHeAqG1taM zx7SUA;T0E+bqZQl4eR82SY=QAopMCju+Smrpua|J)0u^(vkqOmu%vD7l4GWO|8%~I z&-pn^!Z7Jk@2%dTAZ?aBCFy-jrpPWiBB=9kBe-ifW74Gi6Rs9bzF?_f`e&nQ(1p*& z3vHaT<{b!&6VN{9kZd6ElyTjTWlO^~H8+1;nw<1XHt4Tw)|?AkcRDuI)dvq%cZ+ z?-vd34O7FHT$%bJ(c!d7ukIesslq!RbP@-W_|Y=52zmI%ARZ}l6`NjOqJnBm37B8VCTR00=s+!qOe8ryi)IaCjq*rN4r*orPSl1q&8}Qdl zhJY+dyW;|023PuIa_Sx~J9Oq;g4d50rTKG?c)qW2`p&HS(A!7q&@{FT$>mc* z_%RDCKUthG83zo_|{W~)K-G#3~r}giMoM{Sp#g=rLW0zId z^5mdTmWGuAw(C4R`EPvE-&W$BV|RRddcjoTmQQ9Ye@+ei$@hdW=u~9TU)L3T6qnYr z1beTWY4CT)AMfr@VkzpH?^H#^pZt)WJ#$K%;=+;!?f&4)aXFdOBR+S&Y7m&bQ&NNF zPDNGv5|xmmIgXwG3skkd4)@GB)X~V*a80sd%Au}1OcJ&dJ33?9{ry;bv`?%|72Ebh zVd;ZIQ{U}iFUaSvnz8V=VEjL|qxM_Q7$4a+^NvpE`I-qbx_{g>&Q5xrp7bS9d;f#e z{dZEXXm07SXVYSixRLl-e%qfW{dz^~-dUMFH%z*Cy zxBZnonSiJTi;lCaJ`)s9Q!s6LvmjixQBHixE$_26ji+^ww1`(7b?>qNuu@UIU*MAS z=?zM1{)*G@9%<2B`Ofvby=CT%DLdMJw#!s^aOx+0GBPX9cq-?Vr*>jx*$H9GGi!#eTk9|g%Lz3;d@(Jy+;^^7g)t8kHVRb%_<^G|+s zPWhp-ys=SNr(kJf))W6HC5~CD{yuva?w)(cLTy=(svGYv`IoY7OO}-eY3I+VDybKo z+*YvEHt6uwD;CSP+&Lh={Kzx)Jf-wKoJZNKBAdN!4PR;KW^+8Xjmc~h>#YrXv#9m2 zf^lad^SUh_eZN0Gb2Kb~utkR`z^%dpOi z;aQlM5x0l_rumLJPOOZYGn+5<@NmcFymOj%Sd4eaA>Q~YfwLB#+$en0_QxO3JT_Ie z&Y;By4vDkxc%q@Z;=@bzC;4Bt_~(SFUG)q4tZDk!MZ-4mR>py6VKHSw!Rsz)t!+AU z^jTQYWd_Tipo1^-wmRm`QeAq+txS4preK~~*3|`VEYWcHe(iXRF6K@}z;KOHk9O??#>$vvAp-?lW-}2yDv*@~IN7nB65;SSK z#0riLQ{Vr%)3%w}>1@-4MmC0cCsi|}4X$eY7>+ER7xBLF%j8J`A4J=3oKaFMOxisE z3XkJ?ABVF|t#>LGwMlavwJxej+T1^9OLN=|(6pybtG?`{*;`+VuHSLT?}Y!AFUGo` zxy?2we)Q;)@9>;|MeF&AQt`Eyc-CH4+W3>twubZN;w@22m+s$q)X?ys<282e&mL#H zTRurE)=$oo-&WzEzka3cwJ%!sg+F_xe64C;GKR|}tY-h%%DS?$V@ko%XKpFq7tU@y zt9#>5vv$tLoxRsmSu8*H$m#v~(^1SRX5PCzYl5xY%GeeznIt6zDG@0F8H9jHDOVD%|z+{M|Mq|)oNsz**NKokI&K5 zz6&Nhtor*yE5qxvq1oRlN7&7_PkJ5yrN+@~9?MJDF#n$UA6B|=pB?pc{*|ttOM5z2 z`y3IqYk4FbJ|j?B_Q0Pm{WqFxXFH@lUakJ&seaaS&652Sq{5H1ux|aNu6s&0=I7j7 zPX!l#X_=>{;hDVSl#bV*mUnVaPnCRZP2Z?o(ycY@@-&n|Hf|0rORf;P;|$$|A&(5<_BDASz?=h zENZ&);lQ-E6TMkUZ;z#_Z@r|m?u`G5_!sY(j!LRNWWMa*xj!Lof|UA`U#&ANT*`$v z#ZGCHT=+>+%|CO-C8ha~y0nWv+nL#4S|#J?um9p@!-TyCUw>SA=p}t*iDk}5SHFk} zuk@W#b$3ah_{goA%CqrjV?=r2VcipXN@{%*?z(0ETITvs!MxTefWxDgJ8CNLjy;Z^ zQI7iBg*$5(9GW+0g)={YiG92!=+kLG;jB}+_|`M6HyzK~IAqx^ zNmJ}!UBkGuGhol*JHDs4xM#^N39|_{-Wy=-E6i0KQ#SDx+mj-W*>NR?MW=O(PDNzh zcGcdmFul3u5$|398;4}(@85W{Rc70iC5}a3grb*US}e0P{nnAG^E!F?lRksi*&JX0 z;}lQMv&7BP(jI54;W$yhEF|1;miOr|=m#FClajiKx z$>C$GuxhKhA*+rlH*b=Ww4HfkG50=`KK+~y&&4NrtG>ADn_gm5Eo{HHaA8<$-}#uB zkM2G89IfI@6CE{j6N;@3U(Rnl$MB3lYbkG*<@`IFn#4YOWkso*t>>Hmr$hhTPS2Qi zUVfIGo9EAV_{|(%5j;!(q~>hSqqe4ZTk^zBUkPPBDGs`1uV?ewt68anVN9We zmsIOa=e0!>XZM|6|6ywNiA09?4Lm7Mho=dwn0cYoGh+e6;pcowcRTbaeN2^d`gc^! zo>?;eh7qe_9_ZRV)3pz}*=Ky7a8||5cGLC_%?}=?^QSa%@BOe?MStR}a;J;nrF2?L zp2_EYJnH*spTUf|N7@7pUot(>%Xt>`$i6L+!-JDQ=A%na%>ypGphumv4;?evCB0&* ze&$s9jZ+sdQFG1{`W7_lF@K8f9g#Pjs#EM7J}tRsd89>j>*=(dvZg~B8rzIl1j-*c z)I7WAoaVk=jW@PcL_H_7b=EWCBJOo2EnAtL{M!?|Q?f+jZZNULs|W}?E?IR@ ztgnTOH%RN~!4QiH(Go$c1s!^sX3zQIw0(NSe}&b`+X|g>4z|8g^ZI0@t7TF2$HB|d zd)?0$m7SMLJac3oXa(;$DY15uYmFg~lS9s|XKITWyU*(s9hwZ&Jw%`cs~G z27M6{W+T_sFjHSx+TT#0A~)IIF}GZSzpe zdE-rQzZ;LWyE`{Z&zB0ii6j#P6i@aYl!~Mkh8=quVUrrah=+Pyen5VwX#_@dl zi+^g@b-W(2-{rk=N%_p5gA)Ef?zF7#WBJ*B<%iPo_d5=WMb{`!@0~I&cE_obqD$iD zysu1R-brw!GOyd?@b-%f@8=CO9erw@SMOqvmQ%Vq|BBZ8iJv8O-W&2RW9o~W$r#Tf z&?Qr~Lr_Hh$PsSKR%u-+{+2sjT*fsIxjyUb6({`iG;9x$cx2o?W5e;M@HremOCD&3y!3j?K5hgQqm+d=R}>#v6?R{6vFroKlmL*H{lfDQ_m;Jc1u$|j%>x-l%B7RSf=r7!HNUdL{ z{>Tl^VCVj#mZ-#r^J_O4984GAX41NzM_EcAg&4+!yx|^&!b=@~S)vWodtN3-tqgiwIIOOg1$+B#a+u!oXW37S06u*go`_KBH zNIJ4(=8O+V#LJdElb%ugf$8QO_rCY703QgVy#ZmOb=-u)|1ros0Ww z7Wd3M0or*dJHwwCJXA}Zth{v-!?ucLTRt3qYBpi#k4wTH@`{x;tWs<49GEtZ^C+*~ z_CVz|ou>0+$_0eeL7QhXn{Sl(uPtfK<6D}^Cbs{I-}f759;mIt<0ucQAtvaKcpg`sQDx*&5=GI z&^ zVTsAv2iYbMyuw=kG{+rFTrG3)uXC6Eika&=I&_k3tIax@3K2Ce&xl>)+t78H)Cp^YOMSz zJ%8tmx`Wg1tqk>>Gjjw^_Z-k?9bS}w1b>}aUK;lm5N#NtMOK%hlZ_ySMm#1Im<$)p7|U{S?%gCSfAOj zlXd>@#G)r{vRhAkmXr$=$?KIr<|+?*G--x`qu%@tH#>9WS3VQuims`1+0Gpw*YuO| zrcKc$X2ZQhTMVzUJM*RQ6qRL7$9QzEd;bBk_Xcfvmt2uC~Mpj6uQz3p);p z8}2Yt+sEVTrR1ca@o}eUykcXH`o0~?=5d~$Ze%F%Fn~gc@3k}q- z@wR*t*O2*mvs>=mk5ha}XC58f=+%6qhV`<4&;E`=Yad?oR`;C4XB3aezIfR7CNJh= z&w05SGG=?1EQu}p>-4^e_on{`)rcu>Cmh7iZRt^Ql9Y&UQ&82}C>nF)(4-0S7lq|F zJ`OZoi zFzFCq_??N5&AcW_uB%Yl`bNn#|KX|XCrc`mE@^KwP+HETtjaGat^eZPgJqXCWqN&L z)Z0FJmR`cM2cMM}?pPQ)?|7Qtrf80zQ*Z2X_KEb&sdVt$*(kSf$q_}(r#6Qb7+?Hj zj(73U*d*B|aX_^5iJOGsv%n;E^NG{@CeC`<(How0_Gp^i&ZoA!OME zY4#T%9as1$n%#fw?S0~* zp6o5L!KF<sV*{dO5nS2v9$E_QgA;Yd%STnSaI^nW!_|YM5Ju@p^vZ4-8yI$BTyUyTnDx2mY z>GFx+goE=Yybc5HVpZQJvmnjV&8NbEhp|CdC-K~|YC%O?A+@cC`>*A(sd6Q81(uk$ z+;R0gbTo8E!DPeNjpyU9a0JizdBSAxCqBFH%I%69UwzmqoyKOic|)tAW}^4mL%nl0 z$Y(ueT$4RFBzF{h7Rm{UK_N2EeYH}CPGQCthRx?4WMwD+|iF?kiLr>X?4z)-X zx@gExoZZH@XwDM1N}CI*ESe8{b>}8s?qBb7TrBO!oddp0pI*DN#(LsqsUF{zKYx5u z-dHISDSN^urc`TXp6V304NJKv$o}{esD0s4d<=pEl8vcblXWubtS=WEXK;@|aj!)v-J~iHY z**@vlv^yoPC-{GyIU1gJ=*&~K!jocl-zP-XT~x07u(LB!fH~<-?^b4}PnQF}n3zvo z%zdTLI7X5qnvLDicdJwrfODtA}vrz{Yl&P1V82rqRZ1yrMK+H=iyNkDn;vQnF@6y{KfpLXVD;K&U7ikJ_pGI< zd0b{|l-rqiRVUOfo@TxB=02I8%*GiTj)<}O{9tMeo2td!%c#rE9yFKFOXr3Vk7}#= zF6kE&JslFQW*ia?w@KjUPAM;*Y%s~e`+rig`o0Pk^S;8LjWd|UVj%}mY_M>AE__)+ z(JWqYGT+PC%mnV_8P=Y@&Nu$BbNk2qTa;?mdX!tUjAu!8L93|YOEz2HN8Qd( zVew`|*$I!;nq&ovjQI~UG&Xu@+<2q1jX~LT<7KUf53?5-@Dwo=S?~I->B)Y@%lX8! z1DBW$(-!|`kDs%6xpC5GZAIhG&QFaxQ&tB4+?fs_Ph_KpE@|%ogVh) zuxVx$?wl`S+`%jV#2{6o34YwlhM)YiB{oUEcq+HgO=a6J#_&3YWj3nnoPj}Mi(ac< zvuB=rMf2qCCp%>0?G8Q@OFAu)Q>EGIU-URt;f>0*wJo2t^@=-YF)EsWdNGl42m8rq zGEWSYuKKnp_1_ZJFxBd9)VuScl~Yqv)b`EGi6x4!lZI_?~BYv zq5na~?G|=Ag%15i?N>~E{485_ zbpuxKQ<}2;!rNt`a!cHHXDztfcD63)QD^HE2L?%-2<7HGM@~ApI%w2zoSZDZt%XZ1 zqD|@ApMwI^mb4vBC@@|sYIBDF$S>KwpPFv^`&hB8blnc>ITwrXiVM1YD?vNj!?*rK zp<{22PmiR5>5fOeQmLlfOqx!|e6euh6E5nGtVx^j$o`3el6uUE-gu|NBL)l%Vq#04 zSSEckH>^`N?+sAy71p|6;CeJcYj($41 z$w}ucv6-A?e{%MPPR))Nf(%zy#AH77^D^Qve8)J`Uc`vgGLgG0SVC=yycpk+7Iw4E zE2h@5S;-1Xr?q_2-DlFO?>FJ_{3$;Ui>YtXxO1{oKBnrz-S)G4m)tnsn;tcPN{R0( z`A**SlH$&b?izC+WxJ?CM^8@Hmz+|R<2F0pv%nqF2^{VKMzlE*gxvG@Fz zQw2_$Efb_K-aTaC&@jhhX;>@^cYV_7&Vxc}PuxTonmBq@dgfU==iOUa`e{j+mCDt* zPpp1KDYP$=e0rb5 zzvXE%0h9KvxM|?}O?cr3r|HW>XQ^DTpYp^o#rot*^$$0Dz4H_f^-n8RF#PDY*5rs& zo|5ABNejyuJ=Xg8tab5U?Zld?dtT19m!0tMQC;CB` zm^VIU(A$6D%j9Hr-AhV4pQ@}gP&Iq6RL;RUmDgbRiBj!#7Kf*@eLQNoGnG%zn0HaG?s%cmjB$algMR?y9U$3R^d2=3o zRyO>1TvYzZG0k0dL5Fxm?6!2d2VD}{R-vTs8+=-S%9HpR@gAMkUZ-@vY*@T3vgHih z&xy0oOrE%d^NOs(ZqB33%&ZMp3Kq3RbKLaQIGa$+ystoI>7P^yr-p!;?x#zd*PdB& z#ZJuYu$--OlMw4xrp6gPPJRoW*M4z3G5^Re-kUNdwgz@Z7KaZ>sI|*H`|(CaHSR>O zd(fliYcpBnZGw}`w_cJle74}ZzEho&=^xIe;uCBXjaSaR?`hgS<-6FH;w<%orLtaU6ixdB7N2d)VO#j&`LYijQ9+NzXIDM>!c=6v z&!kP?rqgr(i-+DCXD2?g_j=qnWk=IZS5L`i{kZ{$W4h8E68K#BB}$H8G@f*#GbPJa zNK;aJ`rIciq8nQ!R<_ET8q4b*nsH;tvtxlBMUx|TBzZr-@rZkVeBn|3syheHC|s*a zx_iul)gdn?Xtj*Pw)rB)oG%Zn_Ur389Q4#cJ_xicFX^)QzAs((BpkMN-`JpL>N`Q2 z?MR!k>7z+AKCwkJH_pnOIVY!2Kj-62_q8>>dFi!iB-uK|M_}0sc`z#d9?1hrqHWvD>Flt|F8}yhzT<-YPYaP7L8_zs{k$2>| zd(Kah=wB}W)jv+T#nh>9yVG`5b>9ZHZF82J$VseVIN>|F<&(AHS7FoF21$n|O^9c= zvh(QWX0u{0I@B)s;@E$lW)X#I4%-jx&d*%<%z}j2H|D9EA6z)wKd05Fm&NYJW7hCl zN?RKaO*cz?*(74R`&jCe2hHyZ?gH zZBw3QwlT82$WvGQYsACku$_-%sbuHuL!}*CxU!41LO{!Zc=}K0)NoFj)K$1abVAFY zChcUQPweYHJU({W@j&>=g}0CU9@=8F&!q8ujMrxd)6WK*qCd0>@3P9NV}Gf>J?Y4E z^_aAzV*Pzg^KX-MpPM=iN9kKVx5!n;-TMjXX*F3z`u3vZY ztuueR*CpMZm5oB*g@W5AyjIUid+eS5;?>5V-2rnBo;e^oO`)>rR7Fju@a&mKb~Gmn zFnN8l+*Dq0b^VlQ;!YnMPV=^W;_#8ze0JID*N&Ap+?J)u9ebX?={=*O$c!sr7``jK zsd?~Oewz!YQ1eU1i$~OAQfgZc%@HyFm|9o!jb|B8`}w(Byy_LKJ9(L7@*J-Bd&@4Z zQwX(R=p>#dxAqdl!YzKQ3l2@|>*%$9(#E{TXUbx z=-1Cpn9ST6Xua;_S?(=9#Vx0#ot|>9tMTZZUD#^7%VJxJgV)c_b@OKx`gMPCUaQk9 zXWnwCN7_BQ??#P>SDmWr-3P_uMUwq;c_&h}4l^)6*|4x|mZF-D=Slqy3l`l{D~V}k z-(+FQ%DHR#3B%^7mrVf-!bQ@mb&6(18+SI&X=&6w!)Elxv(vfepX)bfb3xf?r@~{t z37sMfzx1E4sd;z!nR`s#VezsbkEYBhan4iZFBaDOd&O(>ktNb4<^o*NDaIR*3U2)9 zmQyoP+TEb`NSmsMt!7qXEAzrHZmVQ}TnUykQ`kO9D*jH&6lsO(4$t&0S%)V~IEddK%dTzgXSXWX$ zDOh4cP^2M`k%PuOjY7SRQ)PC^D%37n#vdhK1UU-*c4B4otd~7eo?SQow9VPS@n`d- z8gIWH0uKoO!QcDSy&ulci62&Gt{6^iGpAI_f!Z(4*cNU)s;w6nzbx zv~0$UK!!<^4xZ3_vGOH*fQmqtK)_~!1F7PAy?uFPnPLsJ&Q~+pOB3|ja|a!s8}oO^9S^U#MN9rDn)j@Te0EW5?W1DlU2``SIGjIycZYXKg z%~%mBCwz+e#~sJF8OrK^IF=?xsp_g#EsYE^7BUrPH)Q45$I>(>aD`x8ix7v|er5H7 zB4Z89yyeSdr?lvr8VhVaqh!YW__VZwWlZMed6g{DcLXNuuXyU_bxF}j-!d&g`R`+H z=9;1%ZEwMjQMw1T>Q!v=1EL}%*@NM@g-~Y-2)Ep4Exzz#8|cT>IFWT=nAthbjnmX+&IU_$IsQ*^P$7q zrnaa|nfNHBDSaDGPM%~|C|dF3jq3H9qQl(rjxMLS`1$QR^4vXTd(f zC^#gx{*KC=32r(24m~f=dAG#1>aeKXlw;f)JRCd4XG_KW6o{N7vVGxl=A4&Jb4(bE z_}7`RO>W*fGc0pX)Kd;-QAW+Ds!Oju(&oSTn89|fU@)6tww-w+n}NCLxAg`W7!$mg zKe?uTMZ3s{1rkU;h$$C>RYfAQ#S&n{H$HdH@w3u(KTJh9v#%^|{IUA>T?l{F& zli7d6#A~gElB#@watyokL{Pc<+O4Kkdz0i9y~pgqa~=Jpj*IQvaVk6}k;l0Ch7sF* ztD@I=MVE~f?E@FDJNVS>$&W>0b_&~Uob_%`c&nDhDYh%ki_0sfvpuSF=8aPfOZcWq zyqL?8n0Mr9de#p1n>;a{^X7P^E;!V6ZK^nE($0x7ykc^e-9jfG%QYuDlf4c}&941Y z#=P^L`V+sPzm9pVo_=!5R}2)lKV-Ue-1kWlYl^i)RmWHMsvVPFi6=dhzUx!;xNSo0 z6+dSlW)?PQJ2kWY6NBWMnuOyky?Zxt-K{D5EO%Id`N%U(r?0|QHItI{sxCbAQohoW zU$ltxnOscW;puLk8~JDdY&jJjbf$f$u(WTF<%i^oOhLgGAwEUxlfD&OjHX9DW!!qV z{j^Pzko+0{C2gjr!iJU)y-w8S8R>H~?_{;qInk+|r?l+6W7&jR&pS%R%{CXlR5kBk zcwBO2o#OTjZ7&yJu`4@nD*Zn!`pzP3H#5`Y~qg7D#pS!vA^vEYmG?VVMYU}L$ zcqQ@35_dK!Ca<^0r-plQCI?+sSop_tt%+~mhRdgFr_A#1-X$w`jpaS#!lh4lXnE&M z)iRuD6(TILk7+_sy>Rf3iI)yIgjol)Dj0q%n!Mqdm~GF+$IRg}541Pz(2V%sf7bTL zA=&9wF%OUUw(?dynZ~_jnS0XXwi_18ON$zIiq4Mj%#9ETRtuaIwsGpzCr5Y<{~b&d zuc~;od3J<#$JzWRQ@$^G=3Vo$YeM~prSfcC40`4hC$VdsZErcHk+c_d>(_DZjSoBC zsTZBrh_F)MHb>={oKs=5uAPUjc)?Lk=BbS9ekdN3ib-_!t5UhT|H!l2s#fK7AC#ud zJ5eZa_|VU@PI22Aw{Z81t}R;%49+wjVKdTI>TYCXm~H)0bjFoW_G=7ORX0wabU;(H z=LBb3(%Z*so0*$dFFFv$`G{NH>oc3)W>4SuHx6~rZsOzE_|K`#e&x4`!eu+&ELPEe ze0u(gry_dale~>v?lkM(+xf91t+P4h{$!qS?O1e2gvVw< zyYRvv&fEDdeHCWAW=1xgjq&=-VfdBNva&1Sm&5kyvky4%u6!vy{qK}xjCS>j-o-cG z9G)8Ikl1v#CeJACqbF}Yn-Jr!{T>_n!)FLg7Ast-c&)A`(R0;qi5DCkOQVba_~$+k zp7boEOxS9vq@0+?6ETe~=Q@tKDXl9|2zl^8Ys!STs%AZ$t*n}PN1o+-aj6CwF>8J+ zxV%u&DQBrmR-5|un555K9v}df7Uoq))$B!0YoB z4fD>kkMF3I*>!M+*OUcopIz9lxX#4i?`La{*~U~8z2A~6cus6(54RBTQa{orzw+6H zAT@#6(182(} zp6)p}I(;*47;#u8Hl3A;sdMDZiuoncX0Tw%g@vw+jw@$Q`O!Wp z^X_EyvL`(jynFsi2lIrxH_kZrXBWLy+TPf@rvF~0!2H^lOKeLYx|~?QFre^uvpA?kB0C1C)0NR_~Yv*#jvwEq;|(0KMmQ5Qt3A? z30ppN)BPVf$sT+S>ihukHK>oK1XL-g>LtEYSZ3pBCO-eSr)l@B%6V5lwaj`dY54D% z+TzLGuscvq_k38&==E53c3seANe^4oQ!IHp#*#~>%zm2ue?T@zB-JCRnI$$*tqQi_gB>afx?Z%^?F8hN2ylgzcX!lXprL z(|jrSj4e+~j)AdA-tw$}a1RpE*tMG@j+F3f11Cw|a%7|B|+o z8{RbttcqDVwIO4w#Ya_}BCb%czuumWE`Cql*Yo(D$i1S$aN(`Ol(Z9TBRE?nch)Ix zpYTX+qoMQK4a?drUp!@3G`^^97j#K~X;orb;O+Z2P6fo29k|3{dxxP&Ts3p%v?|R` z@0iTCs5GI;{X17~$nT!?L3QgL^<#QbQ}(yq@$9c^y|O`Ro6K>sWjDSEt?rwZ%b#?Y zar5LmySVS3eNne`+Rht?+NPyy?5f@Jg?(X#{G{axfvY#AEnr$ux=2N}x%hJ8Vf}SI zjw>3{B^VmssMSc$k`ra!_d!wpjmAok53a1BtDqTOy=E;*U+C>uv}DPhL)=^+@VR)>E5WLgHa5_8 z&@#b`?<@?x^RU>S+g8ZHl9#)NQ!Yi$M=pHP;Z$`~>6csldY*{g+R_so^U&}7G39+d zO=o3qJnFplZmAn1LzlVNUDw>dQ$)OuJTndYY_M}K`wY9H!yIAn0<7OAeCFSJNq7y9 z<96ogI~NYepLq9h*{2}gn3qkn5uo)VUiQ(IL*E#S*dW> z!E1+*@cbvU+I4+C&TL(MfMI6y>A6SRj5qDQaw2`lnFa1ko6hD1on{KUY_0l`eG_;5 z9U~qkhnznbt?MVxI>+uT>7fyI@~rliQ^_rtRLm*^c3iURe_SkXwwv>)=`NcyJV~Eb zHqD>-^#M0`PMUCV+krb?ITDXQF>Aha@n8Psl=YJ-kGJS)Wlr69@o}e2bw{Uo#4g5_ zN5%K;_{385W6^TQq&Lr(ee9B&@UzFk{oisoMVCA$^{aU`jlHLNkBEr^O5|>P`<$i3xX|x@?c^m>kt=yfd@m zRw|R>N8V4yMGL#-*p7%S+VMsB6Tjxqh6&OyXDLtr8YaTkB{nR+eXnrFb z!;|=<^8d3A5xlms-}O3apU?~oWk$n*}dbBLyzo}CAu|Fh0H#C_J*%l<=j3XJZ&3}0`X#E_Hz^zxeYfLI%W8vTp$CM$)L%So z)}Jd7)O}X3W+q?wod=uQ=l?&sHs_?KL?XIIurlXpLzpggo6Ji7Ry^Ey7}yS zwCs>kP)?rmGC#E`?VV@EZ~Srak#h4>fAYj}g6so6j)kWr(=0Um4yCG@PnCMVL}bB< zMrR+UW1=&@c-`3X$1UrJaRBFpNtGu(m0KQ7n$y#=u6+iR_K>$~}5tG!QO%=QbbVx(65Y15SrnpNlNdwa?=&!jKG)-{=uZc{{--neAGv6nAv zisz0~PBn!`e2+SsRZTTqa!hbth2m11<)`vf6}I@xBUT^amm*y)6So$d${aVoK4ap$u#wQzAu)jD8x+k>vH$hba42lxSRio z+cyin?+3mtU>7o+Ie*qfKfl(tcj=&;4TQK?eq;*r&$+cQY{sL_{WA7K($|(e5lrGT za7y$&`$OqT*%uqv%%a0-@`g{@3=^HaYy@8GM?EnwIy~W03EQUWGmQA6?=5xvrzrC5 z$S&UaAA!m}5-WH*c&&r(`gvM1baQ|C!drYeKr8veU9avUhVV%XQZ1X-zfs&Cb4>L9 z5tYiK(+o~&!Pe)4jNb}L>z$}O@Lawo@9WXYr~Hz%j1`FXd;D2l^Idbf!wFB0 zFMT;*SQ>Sm7w+baZ{1Sr3m;1|9(wB5=E$Ytsr}>%;}RC; zGc`_mN7VhZ&4Y}iF8*ztGp%5$eUyrJ&QDHDy$gp$o|(y91y*?WY_$FxTPk0g_7+I3tP_0lw3hG12%FAN_g%3uqnj=nYT0 zEV;3=E97_Lvm|cmtY4zjBbWT@zVpXt^`AEFKN_6YS4qCVENrXaF!lKr4QbA+)&|v?vHz02y<6@aGdRMq^rLG| zo!U{koTu{p3e?T~dD~Vr{%oGHg?k_8+}U2r&+fSN?7FaN(gD$xH)G8Dw%m}EsWK_sI zb%%=Dos%EA7gjj+>Bq1dZT#rrm+GWl-+af(=b`u7E$wIJ6*d=k8uu`5a&DMoad_&v zjkr@T~7b@?3U>&&Ed(QB3`b+#$NSp2n|K#`I5VFjiI9ZIUk$-(_^WQ&yK($p+j%?=x| zJPFZjxuobJH($!>W0&rXlWSLWbmqrg?3(AcBJx5&(8|MKgl13g;I*z2S<-Te&2*E* z#(xT`vOz)LgdV5oJiDxHcj2(~?735(l{*!BdHqsR&C868xvVVPe8+!HePOHOE{iiZ zL6?j-KIO4|=-X=~wzEfF{rrSk+c~F7KY3Q}R5@{yQN{-ISP#$S6CZt7?fa4}IQREKZeLTqZLq>ewUg^b?-mUv&68HRp34 zmEHSF*y}OtZ2N@F_OL`h&t1=#eSE{d@52I<{g1k|opRd_3i01KG;j8)zsvy=#)dq_ z4RQ|`I2@U3@gcRK=9dSjlM|;vir5*wns<_37u)oM1*PSV{F;7+$FFDSjWbK8?amB+ zaN$r)P9^8GIL=mO!-uWsd7jufuHECY-p1u^&6(aX!3W&87e-7Ic$_w2{=~n&rw!!Z zr0Q<{%%+(tZF^eM>oH^aPuCT96qn~HFW;j)rOnfD@{B(XIdYbX#v->AmQ1OCazwI9 zLSWVGf}`AKwO0zxC-f^%kreoHjAbL^f!?L*M{G~HKX9x&I{jrr(GDRV)z0RCiich% zPsALUXHK|yn16cog~Kf~m_%&nY?$fWXK7G8@vO4C?c^-;t&ciy7^rW1v~)|6(i45J zM;(bQ%t@bwEPK`8G0tOD-1yYs}ev@KM)nueVh-iD!(0Ugdw` z;dq^s=&f)fvB_IbWW^PYki;^@*{#}!#r&K6WEXC6&P!zDj!xnd$_g{M6SBs^qttpU zmrPZN!i`Tt``nawemr5o^`VVn-50MFKGInSz1F(j$S88+Wpw&E=}L{?+YheW=ijjs zzZ<*c2lw8&4r}Bm-tEeh*ZetIs?<*Psp-~3bFNkP&#-C>ko8^{zwu`8dA*cskE_;q zP8sw_3PiLuS5667k{Ep6wnO^V6qS&es!mSjF9l2=J5LH6QL%6mHQD%XaoQub<%&K& zcLJ=LmD+jD1!V<-J~MB8x71B$qVTgFcgzI}4I{Y2Bknxl7M>s#)gozFrra*Q?n{q; zPUlJHDMxtCTV<=g{MZTWV1=G+zzvVUZy(88rq zWTd`Pa?0$cK1s`&z10m?O;bW7wqzLytm3#J&2vMl?#VJ?%bHoyD1ah^# zxU2G{bY?Cnvq<=?Z27TW*Y>h>W7>{%a;@y-T7?1&BUeK zX!49b-dVB^KDJKhi#nzhC@=L}Shn-H?@>qYq&vra9S=*T*{Qx|&RUYrCdKfj;Nh|& z_Lc`iIulxdFtrD<8}SGn2zwzsn`6VvR?$g2&OBJQ!MGtuZyy)Cnt6n<$+{QEo~p+r z_Uhl9@VGqZqjT2LzO@I`j>Sxn@_NKQ+uF0#+IExTwo?+*_rCb(=kp`r^!X=CETdZG zw>~a3_{nQ~MniWqTk2`+zus|4;IIPwksos>eQLh(1Wr+cS6Pk-SV*AsJ>{Av!H zIWwgG!71k>ztR^x>YtU#6g}hNCvnw}ZTf3Y^s;~XV|%6BzUY$h-pdaPJU+j8*)pS~ zSKmKja&zazN$D4^J~9$t(kHRCSCe^f@-K+D1YsNyEj3q97+qgQWFg4wqIc0_yWB8rI%PS^(_&i&pVmmP?@z5K^ z9X9$r@XdY>Qn{_|DC}myUnQp?p(hS$ z1x{1BiWHh|9QoCKg{kRYV#6E$7|yQQO{q~w#Eg#onmy%%%nL8k=tS2Z3EN8y3%^)T zNOWKI|7Gm42di2NS|!iaUeV%Ccorz-e&dU9uv~z3?W1n{tR>D_%lMrNIafSQg>8Npb@+&o`#5Vmo9VhLVJacra%vdosaEspK z3ul*?# z{{q4ZizO$2kx*5OIl1=0hokIg;IX7+h!6 z!?Z@xA*+(dxTU(I%r4=lz}@>(mQ*iFb8rwV7B;kUTYbi%`-^|xBgwPfGZY)vFIW;b z>ws9i!e&p+Ii0=5Ddv}z<_ZLFeBhmag(EoWPph^}M{do6>C!v643a*HSk|ej@4I-{ z=>*Rg6Azy|LSEYq%pZ8SADP9-U7S;B7;)Mt=rjAa4GO0G!qL+TCR=#7yx|MFEVix0 zA!p9S;Jk@KeK-Cb^*!XpSyKOiTRrO6%xgcJuatDWk(;rf^J?LaS8iEP@@vvAFUm`i zSlA%-a(5TUHeV@8`>5{hdV>+7p`u<>77-j7G}FKbB@?Y zmsQe*t*lk|)SsvqU6$HQ@< zxw*4i)wdNW9P_`TA$`)c`OcO`ZP^D#{dbI*!)pW|=T)_HnwbY~KBK&v+39S9y6VOY zx8rgq`erHGifCyh3EOEt^k3c6BscF!o4)NOzI9#GZk0{WlH15D5MXscH2=gypRA{D zIWoL$ho;{6#4$g*Ff?V!F=<0lCC#VYOJ54a-*VtH_j;q~s=urH!r`Wv@&xYSn#_4q zED|If9D0iyW*n0+Oyw{uPWb5BWt}NH=f@{G-Pb~23=TZE|5D<{N;p;!NHXe*h6b!ysIC+D~)PQ-4 zQ^X2eh4qR*wpv=c3ht{|7Akf48GF#F^q@bTIeKQ*j&&|#?H?V>9&lx+m^Lr{p+1H0 z<5J@Yo6DEtxA=Jfu(E4;#6Eww#@X91%7lg4TCN00xgXilcmaj@qqO;#mp3nNG zmu)ttJ=AvZT-jZ4)46M>4zuLLEgBgoI74Elvaj24aG6|untQl^=0O92!ZzJ?9liE> zTBU9tz3N%*!m8hbC*4f^x1jxh=0x?(L^Z=g@0^N>ljJ>n-LsBZZ+s~cZOMGeySv2s zwMFYr$-DC!dHlV!Qj4T!Y}m25ypo^0xae@zf=|{vGi7Jndwyjun!!8ef8tXK)o+s@ z=YRR2ywoODLZx9!5nHrGV3fYV>iM%Wxh>D~g_sEJ<&=HqkZ0AKlgup;6=wJ3NB5K# zk6st=Jf(#u=QgDJIY~~N(bJ@Fw{qsigokbG72Uesq%2=fov`22aI#pUM|Ts~^!Yn7 z_mp$q)W4w>m~={^CecS@okpj8)$_RrFZeB(I$yI>J!*+`&C5wQDiqY-^L+ip7#$I? z`A^GC|F;E)!mnRgB**l#`O+R|jk(Fi=1afITmCw!xqQP>eZAeDf!*)K@~r08x%yQt zRav9?QQTElz==~jJZXW7P-dv$qTQW0I25nx?+{|OHIh{2WQpD}K`M+n@Z!NkQzdp! zeB2vr?9jkb%CM6G2JK6gp(dmo?+7Pj;$tb@}oGf&+L{j#iM7X zN+>vVMW6Vnt(PCD-PhqO{^XeO(%w}Ir(NIpbNY-OheG`(1=l^wwmEbvt>`t^jGIfY z_%cVfKk}--acJtL4bPT+7TmhykZ5$(;bqfq7_~@cPMCGnShdcvjD6`prJc-7o94_u zr962_2+Ni=%9v+1tXch}AjUxLxfhk!-Y0UKY00Z7*xF@X|uJFm{#{ z%cWwEPitJ!I&q@YBI*ZsbfU|97tgN!ACB_s_^b@H6k6rc(QBW>D!0w4e@c&g&aWlq z4_i+2w>-)*Fi9&oDtwrMG3ZXST-}aCv!`t8o>Al0yFfDMp zO+!Mrd!CS=iHhpmV*UeX_*PbSO)(OPj#F~CKQV{#b;AQKfeFlgG5&@D3_D(K_$c~J zzou1^c`BpkKc!_K+{@)Gs|qS7&f+z8V%1&As%7`t!*~6XWA>(pTN4GCV}2$tnA0P- ze#fK6DL>@T6nbi$pCH74#iV=MNB`a(%4TyfSj+Nn`{R=RU%1QL>ve3+FHc?R4J((2 z&RdxFv*oOgQ>v8aN2jbeG8!!Fm#Ah9o7AVyI;+@NS z`IR%TvK#6598u~HxY?)U@AcE6e^<}!L)&;(mfC2(W&g6}h;RE$rkGUyg@3%fZZ^Ep zf5$lI?*Vb~C%@RAnP>gXzEI+@p^_&$(LM8kU~ogx9BII!S8~Z&b@7~6Flba_~V%OBk;CORg0jh zwc-`8@*}@y$NlV%ddj%a?S96@UVD}f-_>_Qvd#-ce-{pN_iFFEmB|nvkx*>DvXpmM z^-lJS`@|;P*7(YQrvAz&@vC}DES4Qo^PJ6?qnjE!1GN=6RSUfSvKFapiZX9KH1SH0 zcaQYPl?%gbdY*W7Pub$q`$IwXuFxj_@J81z*&AH;PfGeu^DcSjm{ZvDP4QrCo8 zeU9baIuAD7WE5WP>a?s(u`N$-*KPJ)7nZ2-t(5%t;@yJOTZ`NeHprR1_@`+4#)Ff8 zLR8V?wi}0fZhdslv^(%jE^CRu*I&=G1y0}ibw9CdrajW0&si$Aa^nAlyw;t~QBO5? z?R>IhYE+@|jZYHWHYiL{)8zFJI>fMK+NGkY0XuCYeybm85w?8TtbgvL@BAx8>^ln` zHO>YtzUNRTz4ff}vYMq+=U(|D&TVQeyjDnbUsvCyL%kCJ7pEI#xxR5ocbahjq^5($ zNBgbXR~pyxbntR}T^86^aCoY{hj09m8;-9(9J|_aB%JL*@nwf4=25pibvK{n^$&69tybGAs%GRK3LJLqwzSSi2hjk5|pymkcL?iVR{xL~ZWE3I)w?~aD9N8&F{ z%^U2_YAR~yI=(8~8YwQ#Te#$4i(J?bEsq&dC8kT3hzD^=<@{4ps|{Ria5$ZRWhPVn z%qHzOFCu>=pVnV;!@t{T@|6O`<#!aP<~cXHbHUA!86nD2>|%uTzTf6GH9oi*+YNS9wJkXJPRu#+{iFD%jZ>^Ie= zc`9!9D}VM)`2XRiXYOu}ovl*e0=IC^mEzU$5)x6J*&0!O(s#*=iOyY?Tf98(WQc04 zlLaA zHsjE&3DF+D=~ukGmrOgjzVpr=-rC@L759DJQ3Yj^)x-5rL=oFInQ4lczN0S?9^yS3YnX zer02pWiWk}T#_D?%6ZK}^hS%2mCgYTPnH)|ooA065!vx2Pe$>$u<0L1zgfq{#J6y; zXU*zd@1$~7E>FoluyCe#PSmk!>W*nbr&e##`m-|7?$90ou1Mxkvxz}J58m;}iIO@4 z*;grdq($C`cVCI)`y$Ek2@{3SHy?ewL#pJ)9d`}C4o>!(%!YuSj-E3fZkj&pql4d0 z_q@k5q~57r<$1?AFY<_3`;#_i)6;1+c@i(I8lt`hr?Rn3xv`V|fzUqSNED z)D5!4I(~4OdujV-{g^!=e&X8$%f#Xzvpgwx%3Bf|5iGUsN{@NaCEbOa8fTx76qxb5 zlb1c|GUL`q-2uBC`RaqNBz2nyU1r)?cO*>mahA`dTPK~?tG}2iC)vU9rN{h>iG$CK zfLZq@ew{p9Jn@~H>ix&uRY8}PnK=^{oQkjc_Q)%F$0N4c^s;mN<})gGBWcrnsPY=2}`Zz zihYu>$n}wXx%pP^$e4>fo7w08Z8;<|J$mCzPtQLAQfgaHaPK(dQm$>7%4FUtE0DyM zlype?Nm$hr=_nD?D|+%9X1aUrQZ(%q?4=rL9KC!viJ+IRr{g-EuCW<&Jwd)3j+PrK7D5g&qi= zq_#oy1?bo^=}P9vkcL0qZ{!7}!zBcw880nfq@sFe!_(4|`pd?A8oJeN&XrATAIbQ9 z^z({RHQURdGE334_EE96=2sKd!Y=I?&Z(AP{M>(>vPn8TS1z+TVBd1L9fC&58dGC` z{4u(asrBTisRzf3XE0j+l(Ur4&^2E%cUeXxL-3^U9lYu_nUim9P*R^e z>5+NPv&oapJbQ~vw)0LkaX!1p(eIWszq;3F-Hi|X=83J4jBh!_XqzjvY4(*pPOB=X zEMxrgspr-+!QeQhc1zR8pqskSsBXQt#BHvF&mLnQA&1o#OqKnsWCgsWLbmW_J9WzK zov?UW^#$b#(*(QTb?%^zV_Mc(!?|eNJ9m=R~QzB`c0k zHL&>Ty5K!@%v56;iQ8tn16E8_p|( zmb%TjU@iAysUm3oacxZA(WyH(c20g3@AN8jZn&rBjt@`0tHOI)9?g{aeqmM8LDBRr zr?{7x9a$k6{^gVQ)>FP&OQf?*3p{-Jj~p>pE$lvRJ7r09(kF>^7L7N%PxI8gTNHZl znE1XedaFSfVSZCyds$iUz0hR2&ffnAr?qwTCV72QF)Rz%%WM?T**eFjdHtjXr3aLE zPmh`^w`t~=68oj1s!LlfcExX;*{&a}bUM)Z&W6yO9cR={c`_!R->`G~ogGJ?&ObOy zZ)2;vYNAi(EI0o0q&rRexxC*#HAwsynr*jI^xKpvr%&V^4YT7dshJSP7kGH@mQTi8 zPx(#wtW!7LX;z+{>VQiF@ng=|bi~yZaIr7%ph7&fLdY zyFo24N0uQ-|%9c|MN*oR?r#c@cY`brZ>*)=0 zT2GB^U)j$pacIkOQ#5zvcWH9kCLHgk6k=A$f55FK>y~G~Pm?ZB;Z1KZDJ9dp4?b(_ zZQjs1StzaL$|bEo7f%ZmeUjKExurmR)9wjp**C6?)m!kJJ^HcCw6MaR-9qMq!gW)A zNZ+hK@hsu9x!(R@>oXf~Hf!gsyvXOmpBz(nJWYI`#qzXU$5X|YmI(-#8<^gB)6_X} z5?cpvd`;RVrS-y-r)g{zzxn>l7v`NWS;A!|Omg=)xwz$$;L3jsTyMIp->1Izj^Fg; z3U;mLNz#^I{4}1Vcmy4qa)ZaK%bLwO&8b{}p%;^_?S$xpL~iwx-HA0>p?`LqQB;@P z@N(faYtE;ZL6146SGL^o_SzBfsQgKdM_$#UG*ze7HJ)A)7Z>eWURJlr?XE-SF2!rS zEtf=BKJ;B{TlfX)U`XYb#ln&3s)~It)D2o{>nOg4^3}R-PsBM z7KcftNVGM?y=9zL>cHllYIEZ1JNS5-Wdw43)T|@nOQ>7@RK$C*U_b7vq4)CeB|OCJ#uPo1+k zUD9G~-nn_+lO>W#fBgI+0(Z+OipbwdiJ4?6@Re`tC8@2iIb#wX*B0@HS1nkQ<636C zuHa~x{e(qgDeMc)gx39OT-P5}*q_5^SvhY~iNDX!*0b|pygQP{r?+2VvYUh(BeP~H z_sWB=+q*edPW5bau3Df{{8+nY!%T0VM+@DT`mGRf=nD@Lwo&|gMa!p?H$LXuL$353 zRz*eQ4NsY~eomfM$#d6tibz`X(fTD%#IvSWGe0f&dL!FmBp)58WNs_`y1Z)2{3Aaa zrRwBg*tqrly>Ut)Yuefuc?U$-y(l%*=vy)K{>Q0PZ@f{P;?}_#U3J8M**_SUF+ekD{{5Jm@qr=)3qY!KPB_gYiw2AIyHPzwSsd?wO;S3|)s)Nnv zb8m2&7I75^SR`qG*l@FVb%Kg2&&g8dm6dH*HXNBY@5I*0(&t&*znuBqa!4wiwM(XK z%9P3{EzJ8)iO;V*^2*u&{f|HHUH4Z$HOqO)Y%BNir)aFb`j50oZ_I3%ePU_&jz_Z_-5TODWu|}j>=h1bPTVlHb;lj&oS*&r zG8>m}Y}B!zc-O0co22Gb<$VRBO|Eop}7ks#)j2=KpNXgZzVO$5wZVaBaxtkq zYd_oV+PmYFN!FCoFL@#d4)w`Y7cP~I`o)-Lw)7{@^tz-==4&rY>&PY+bDN$Lcd8V# zm3_Qv@|_B`CH=EfH4O8PPhEE5Fk^Jp@#$h0-Y#3Vzu;!Ke$LB8d)3P3D<4#k>N!1S z`_3>&#B05o_SVn(E8i_U&BL*2G25-fTRI|wjP*5Jb@aBjyir-kv>^T1qPEyO&MD3s zy4?I#CQgMr=Lg(#ovwau?Uz+GD--!Q{uB&f>gK1+Fk3F@RA9|NH#6zkRzZKe=aq5H z^jvd0;aSk(`%8{6uKeh+*2HbSjiXOwt9JZkA#vur3z8(-7{c$VZtr`rEZKSX>{INC z0>OTQT;f5W?>JmLIz{dI!Aa$jFXrkOioV#uAn7&HOXJ`pErpD!6%)>~?#$iLqPkL2 zI{L>0W9IN#O*5TWS1fS7r}*UB!5RJ9A-H}^iTut~ zEyJ(OC*B-MW)r14IWGP3SyQKe;fN}_EVA~_ zu|oz94B-#?xECChT6rXeEo#@?0LN|}dx^u7=4^2MZmgNMV72S>;$+Frg`ujgXYbyr zaBC`fD)^+UWWguS6Za0r&3vqVt6=ARv4@@dYuKD6f+p?nSZjCTFhk07hiM;MPPtVr zYkoLuI@=~k)=kpUGK<$_4~oeCQqCa!GaTB_;D|PSc_ua(`yFy{xHwiMy)e!6$yZ|BH^Bu1s|5 zs>;c1pJ8z{jot8D61RNNU2m@{H~-B$J}K<8X?bVob=gMsDTC=JqkUW4`+geySNPq1 z#l*XB?~g}3w)_u`FBLFd<6fK~~6RWjRjOgdn8}vztu&Te!-TxHW57Mb-)_o3}1z zKJse$l7$YQj;!3~L1!3VE}UA;t|Zr~`(Q<^VuCjFhF0CJr@5RGd$jXBHT_Tcet+>) zb>+)RGd3uh?eolxc@X67cazE6*)eseN3myv^X~vv{XhJ62wKru4+$DYGH0vN5KdcS`k! zo#h9nB_tN}tZR}NJNSiT$H7@M93Hyn96J)apy><$vLo)9$Br$XFIVTXoq2A*zU;!& z6JN!}{A980y`VkM^P~D!sT76%54oLlKJk>Wy!a-3s{F_?(K9km&mK-XF0S{*OMk~H zwTLedij?=2uz7zs*xT}_N&o+WJC2!hOUsIycS=sb{qd;o$~;ApYbO$2)|WJ&_kFU1 zFX#sF}8&~E?H3uYPE{y2Ugrn zSP-`GuMy4J; zmmE}=ZIC!4=~w<0eGlH^h$uBxdBNG! zIz08CEUTSy^T`kK>AN>fef?xw{gY?DF%KDqmZ!~ZexqOXNn+zer_R|Yd7XvykjzpRdLGk6P)!qKWA1mq&uAOysuz;C2N0x zGOzIkMxIxa0y(YxRZh(xJI}UU(c+MJ!LcG#^U~s`g(eXlU$spSwOs4veX`*|n8PA* zii@llk#--*pWs@e^ozzYE*vh+ai}yOa662M!|Cj?WCUmP; z?QV|x$auQ>icYd)+N3Nw)qjen_a78Vn-!L9*5oZudgE~3_{b97phMDkZ9r$tFAA?( z))sqYmZN|D#M^ue!gd62&Rd)o+#m4oq1vX)EvM_hcx}JJHCgd8V`HU6cp`VVKoHl7 zgEEmzLbR5sutm-6e#2H|Y`@Dc=410b&yySbC&)#$3G3A_?0#IVY{)9QZ;wNsOrr7R zNi{8Nri++2UP;<4K40?0tBptXS0*~GyS>pgpmVGA-Mc$LX~p2M0?UzSj83wgL1z@z zBs4s?|B$-z9%tjXaM?$--JB5F)T%3RLh}uq)}$RL zXPi6o+}`W2W8Ol4pQI&i@r6J81Lg<|>pfW_Jz@Vz-r|zqCk)$T%r7tca3C!5@E?~| z)`c&Xw>diaIQHqj>+p2H{er^mPnMPM;?)bm`#9_(9c53|-mC~Y1d`lCL8#E-GINOlm9r0yF!An{98(hvs z+-5aXEltm|+;rysT#%}f6|(5Z9d{q+#!II{VX1OeSdQ7bHbVpD<*!=2>q7eU4BLDb-__Z!-tL9u?xDB zxy7rVgjZdgdBx-Mi$p)4n@+3bKOWUy`E6p5T#$Bs;O;jITq9ljE0%=bIu?2@VROF0 zw8u-@PEUB-Fd?Xcuf1bYYLog_NB1?+9lYgEg`K`~(Qc|K@_N-7Q|$^&1w1;vvrJY^ zc&mJD{grLPck7DIxR;r4J2mB2-m)vbFA9Bpzb~B4`e<@cp&?IT!}%VOzhY)cM&!2#T**PF%f1*m_!VE_;;wnwF`@RvyXKWgpQTNR z{`hllM17#K?}FokD+>=BG%*-HJm>rTw`+#rALn(znrv5!3BcRjt@`&n6gCKDQ{W$oMPd?48`4|v#Y%BcyZT1GM+3oRpty& z(q#c1TjAH?Ss|a8W796I&UMhO7vd_e`NWU#Uy=Tz4#e8pae#iDlzO#YuS zv&{4C<_&GuJM)y5>Kqc?uVCzmpxJV-C@_vD_`1UzVR%r zyEWlOgMhH)3rVrq^8uX-LBeutt(}&LwHSP#5d2Y~%Q@nyLtZ;qynFkthaLKID+P}q zImWH|P9a52u{?P3#a3-Oj?iUGj>ua+^w*F{OmxrPym9HzgCTA_%TD#p_{97yF6ht% zY47Ern?!SdELff&bZDwbeXvygk53jG6TQ4{1TUU*_*r^R-hotc)k0^DJ%v-HpWN_V z?Z=_|^jCt`>I}*LD_ZP@t>POi=Tvu`?c%xR`{Ia7OcIxRlJb;mqMC-B%y-we7};%X zHCEg&$dz4mXl96Qi;;xhXO32FO;O$=i@-^F9iF?7EHlqKYIwpf=nm`V=~uQm`tA=_ z_D|xr|6=0YH~ZwuDV=LwF8uA)=MB)_Ex$}N1LdMx(JI&+StoH2P$fHqrM7OskuIH zzT@U)5g275C@l8lk6$mFklyEwtw$Y9m`-+9*Gv`IRk`GubIz;8Z-Lr1Cq5c){cO4N zDXZnHPG0?*L_RLXntfgNY&lnrn zC!OB^;%8@oocb~OCC>zdE-9I9KFJ$hQu`t;SbMJW?8Cm#I?Sq~j!*aRIO%-knQX+J z1a9p-tDbYo#p;@g2OZKIw9ihMq(0&5BO`t_ztel%{4VfzNeUzx>6tS1Nlo<4`*mdc z&kv$GFMjQKSzxWX&Wkl%=0UOjwhxDv%0>Tq&|RK%iMJ}%%j?g?B)g?kl@2p7dmWl| zqsH|FU(HmRm7)q;n}x&Y9Z2IhOch<4Iemt~a@Sw79TrNcy#C&V6H>A!YM_gR^k%qanL7R+w-w$&@WQ^xnQux z!81q0IRqxxbr`nK_@QLp%y-O7?5_Tj7Uh)>9dex8B#H||XDRGeu#EcE98oVUegDQM zhAO#3Q~e8`dZw5w?Pi{DdE=8lvn=Db4~v%W_vB2jIcN}ZNy@DJ!D;m;%aW_63Gy@x z1RVbV|Or1@x0uZqV8Fx%KK`1*Yhd4_RTse6u#%us=W?AR#Gdr zam7wg;GNcRAk^dV9ryDmBzUGu?mNTE#a&|F^y3PLa?D4D?2tvfyXS0BTI#SgP0=_& za+ZX>z-<1NGtD$jy8{;X>dsX<&ZzrIa@X7=Pq<6U6TH=b-0AY=n|;44mOWbJhE*)dVNev4Q1hJs^L(+XM{mp+v+eCW_6`{R=OcYzxw-d_I>O@F`P z=ftzeMTZ@pI?p=a zAP{VE*@}tH`OpKkM=GK@4;%FVtdPuW5mH#k)HbE1d#%#Z(4B`K_00If9Mrv5!IfV= z>8z64=Eug>3oaY4oT{*{t9$m5%k>xDwze{_D^OpSa70}E$cyD=QVLVtKOVK+ddX_r zk3;EZiq#hn&zSX-YPh-+51i+oOeRy5fn z$j{3vQ9{9?bG}ERk>Sh9Q>p}S=H*oK#P2)&EbmLffoEb~r#yoei^oR@Om^?|+&o3a zGUlCfh}n6X#988qpsP;yORHWO5$5Wu-dyS}3WmebAL%Q^;_+Igfv39{Wr65J%zQM&ZS5 zPtua^x_ixesBNv$>Fre6GQ+0pJWtF=Z@-%@+O`LdtQ2fNGNrKPP|J-kUOuF)chT1)Te~6 zocfMqDR-MAgT~5YjZ!=AwL%Pf#q7b2O>f+0?7pDPd~Er$-JU1k@HBHg;8J$-J2LG+ zr|4lZ_ah=rOIV~;3#}s_PYPJ*)Hk0~^vji1DV@IQ3copiHcObcT;e*xm$HB1>`uM@ zJUPvWPA7CG+&pqbR z=WKE1-7XN!clc04#P11LA9f`Non4Yz>bXMZK)U%h14UDQp=>+5;*BRC3Mrf34X~bj z(OPe1ru;e!iJn9kA3K&-Ufoj`o6;RR&e}L@1}dpLWT`7;&1gT%lhvkg&iT5~)3fKu zGSM7XhBNh3W-uC0pR+;f=)HrJuC1JV&EcPt+1rW2{#Vw`Dcm`I4i{Ve!yfOxfJQ$b ztApZwKfYWxnqMHia}C?{-x+h;Px2Z^>{6I=Z0AXf*mkKpww?W#OnlecxUI2#@lJJV z&JoeH=DjsX!|NvoeG4$2ACM%b`IKkjj)%(*KeT*u}K1ylcLy#X4joKJ6omH zA>*w?nSrMw+$s3lF6oqd(k0n-HNEfnzSOj?;}73=_!(Q$VZP~cDTP(fbOUBgNRnS? zu&``r-)Y|)kETVKKfKg^_HD~2>5YkQ8oEM8?RTuC@A^-95HGY~7eQgOC1Dy{R&+R~ z3BAsbN$fo@e`J|p(BY;_HST@83tm1{OP*4!@k89UC-I;9l;<*!mFDsv-Daek zD(NaK5Rt&!cBo;VpnKLKW%a_xpZTlOjy;phN^z-43s}wM`d!^}s*>(y`L$d&S`UHKJ(ffKw#mq>fR9W{B zuVwtBZts|n{vP%o^8%`rm*y-`;TMR`d&HF<^qSr4bY{|_IgRHU0;HCt-*w5dTb33e zI9u!lFMmws#MxcmyE}a2pFCl2OXT2KTAQ@T=W_6djF~^#jO+?S6*h1;X<@hixq_#`c~ZGK?K@fT`tLZDxnsLyM&z`_xr_@#m0Dfj6m%KX zbWRH66bo--Y1Oy0OyWxW;^Vvai2GU#_j3NVmxT=f$*=h0^LB%R>01FVX{U!ySvM}N zQfS#JJpbp8KTg`_4^OS$ai{B@T})x;>AgQ5bMD0;pdcPPY+&+T$WbZq8qbe=6R>Qz zCcI_X=$LnKT4X}ek0!C%)hl1JC*3(Ra-4$0dEc;**}|PJHap?^%)iKHywc%O$&wiC$R}4>pNM-*XXHR?p)+YPmC& zVQH%I%3qpW`)};AjG8+^oax6UwUug*yuPt5E|`e^zU z1BY<_B6e<5rb#!NX54W*8_iX$^-ek`z@ zbLB|8|K9{}fflZ+tafv=-wCY(OGRyWMRSJQop_b_vFTmg!nnW-)^!&jGuYZ_dj9`% zru|8X#gr$aF)#Zgj5~doANj!@EfXlzZ?Jvga@V9!wkuywpJdc>Wlx{J?&D9=mLGex z?_7AR{-iu>nPAMzNt6EgW-acVePU_Zk4plYg?yX)W9%Pw9dCT)!&7qCVdegfOUq+^ za);YoR^lm`>Djx-(QC%V+jdEJ+&q8wtgUr_zsLET?~5%3F9P^|0%iz2X3tVj$!e2c z=+YVI`A~bygtJcJ?pYE7+5B5CtLl{pzmhMy^=N_Gr}!$A=xK-@hny^t+SLtsZo!fA*opr5FFY_1rzurn|1B{a%8iT211^ z7X5i2o<Dq!}2W$-QIpU zJZ;^D%W`Jcoq^1k+VyQXW;%N95DwmV@X)-7?Z!OH4KZaCqU{p6&7GbKt=ph>l=sLo z_b)FNrCD~!)U{kP-DExCwO-9Xhp_f{{6&Xk<1e|I_Xo&aGLq&I+de^v?Zrzj+uQ?( zxWo7GhHPxowtrA$uU9T)#2z{CS|<1O=o6gDL5C9+9u)?hZI~d%(5$(MBQ>ce@94CE z6)(*Lb{u+hAWd)IDUQg#39~yqKODK?pL5jvHIJLuoJ*H#`?}}gXjytZN z5rVJXYBFbqvFh%#X*=uZ^zcA$>bJ((J(5~a{_q#GuPad5rgK2N?M_9S?}?4m18z(d z^1E?H$<+6v^85+2>t0UWu5s3W$raZrQ*ys(P3Al*s(Y7_OFrqdNL9q7VDZPB`P1w+ z)qCo4d+0iM`pVyU#1L<{taMJ$W}bzmzmgUxN`x3IEcqoIe_*oI!6#`+IeBWPjsdeI zI#0$ZSUbF8v)b77#{IkgncN$PCe4zZI_Xr;gt(fz1uFj+{hoj8qx<9_~qh>zy`5WcktkWx}JmGw@VX@m!hpZYw>1#`t z$k#k{TyHcX>Yb`t-pZ+IiQg8^c3*E)x!@I>*PEl$mc59yYrfNW+Ais?o7cVtCj1j; zhpn7i{!-SQr-aFQ7ju(-kB8@-Cu0A;=xz9z8dYMSaN1yt)&$Q&aUb2PV@sCa_BiYP zWz~nyl@1fG21Icz{M~)4RchZK2i@HtLRnrEOz$b;(%Sn96xHtvC(CWDWQebsJo}!cU%(LC3)nS{yLkk)4o4G>1kH-Pyf9luu{;dSt^xZr-oyu ztM~s2NoIQGlcK~XPl_wp$saH2(ECAYSNvAlyF3WFBWmx&tWaYa>;W3K8 znWx|XxKuOidjFC(VYBUl%5Msu#s+=TP%X7QBUdsjQKZ2+VGFa9g5m`wM#b5jo9Er= z>bO(Vy*6M`nsW0cpRP6YZ?URw%u`mkSrO=Q>C*cnEvkmROiqaw5toD({$ZKq-e>G2 zD!A{*(P{mip4nIUw4>T>Ei>ob`pIM)!*0dX*;$=*iEri0sfhv%L5Jm{Ed+v}1xOvg z@yaHPP2MtdPTW%!#r>D9>L&#~zqD%KanWlxPStxIX5ML|uq-D*g7txb#M_1mGX)Yl zc_OWK1e3jcjzlz{^_gH7;I_!^plgn+L(YVN%>s*;MLu!ST<0WkGj_{5n-#GF!bbez zyO@5?oWaJVGv{UK%0q9I&DIJm?weN09dEV7+F+ zvyMrwGdTP#ZbDSdqa#xSr|giv8&@^$p~3E#Z`qt4nnt|J4SFRJbctcz9@bChnm;+0 z$wkWVstY=kBEc%5XmE>hp+evVE#`+_SFU8}JY2;wp}BE})2vyo5-WMVvz{kAO;uRg zDsTC2@iJ+LZ^1zuCkJ^3-@bdLFFNMslpA|kKFcpOP*gpW5y(IBv0c=Y#Gt=!K9wzb z&jL8JlkRlt%ks7TaOA5l`5qADr!d=l1lcIA^MU0eB-&Fgeu>DfJa6_9;rutw{^F{k`!>=$Ts3W1+kHPi7fki0r;%gMo+d{@rp2-X zMvEG!NzRCP{@_%>l8~t8gYrj01eSLP>Ajx6hV(*n8F|ht;f#xqU_f!^?wd{}NVTNXSz$%iFkfzQo=s%VbNc zJvrTT3cd0^9`$XF?kc?Lo3pFwGuVdx$!kts6Y?>@qnYiF> zx&&Lo7G@(JCBgV($EH)iV(Z^5gIq(6OY=QK|}zC~}cq#I+b6R3Dk zGAO=W`PowQ9CNByjHtYhvGA%7A4RjaX!M-abUCTJ<7DQW2~z)dT)BKGFDEUD+dt?K zcYF=cG^hD9Oq@HTFP>FTkyqtq^g1NHM7*ujclnYQ?v?)zJ!1X=ip_;%~Nx|pvLJ5%lL_D@Vw+j`m|>ssoPUATKH(E3%Cuw#cTo2m z`=Gn7>zjDO9lbIa9S)lz9NjrN`Fn!)kHVjcD|QIq{d;6ddWq?Yv_+VQF^J;huT_4o~;{xRcqoHu1Bu4{wo$z+^qn zpYqZF7KhK6C>1wlNqW)awiz1~)N_R%&s!L^ELi*Rm#<$h+GtAMym|Q!AG>fekF{I6 zgG8JDf$4=CPYOmi1gsW%vaG<2^De)_=YpNN8$#|}(eT;$vvr0SXS~FN)f{a}tPVak ziGy!DC2>V_|;-uQ7qTy4jjg;V!) z9ObOKGjWz*yH{?j_B)4vN5$9QIMh7jif`8^qO!j|e(KvNx{LSMIT~#Gp4gMaP)xM7Jn7WzC zg}2I~^6Pxsw38R??hpCh$tz!U_~^@jo@_aia{?GQ`CpV-!@ErWn7YWk9e?~+St@*8 zV4!aHZ{lUmrLAV>Q_bE4EjCbHw%~XgzhbR|?UFFQ9gpVCb~`QN`O(_2u+W0=RC8HLiTlETF%aWva9#X2ZylpzRgd=cbswObC;Ms z`-Jd<3tuNqVwYIKpmFx}j!#00^#Rtt6NE&jJju^mrX6%ic+>xmLT1CK%7%$a82n3%wa8%;jm+(SXofe&&E5< zhj$#35Nmt!jVDEB@ovf4(ii_a_rz~(W!z++8F-I(S&7ArQzbbsg`U_sJ#5wO>)=ez zI`Y=xDQC>LNz!6JPDN+^m^f*}v8iqs@49yHvAV@2W25M>*;Zl6xsnM|Do4&8Suops zon4YK(?Y@e3Dp}?>w?nD3R=Za)aB&0o{c#0=GasD2{xN#ew|_8Ws{S}bk}ytIhKcA z;xW%2e6rv4>tINQVDQVJAe{v7;2&CgDV8Or%%O~nf6ov2BltQ!=#c32xi3Dp&*OI} zn;>=k#+inlqVr{zUS&6zG_E@F?%*^3Jf&}S3B~5NpEUM;@yUuh{wyv@+IPt^{wE&} ziTeGx#OZTB;l%kD?~a5%Q|L}Ewm+l4#mD@M$K)eV5|b`TF;8Vs%@huw*(&$E<&<^I zGoEE7J~?}Mr&&!&oX~vHRw2dZLV{n+5wWNpe;j-sdgruS-?(IF`=~c;s<>V8#-H5r zRuVd*I{Usjc1f=kUElI%N%@Y8%JT(Zs|Wq@<2LTp^}g_SS$U-IdJ~tf{cS;Y>RWXV zPt(hI8ei3-ysu(uS=6#4HbtK#*L^trj4$c(!Gz3Yo@Ztc6W%rR{LqY8@=kYQc|uTj zTG9d`#+{PPW}h3g-C7ex5?T&8gw!k%x#GN1u}N-+LH(oEM?5~t?~2M1)iV3+kYupE zA;asi$W5M<&58fqw=>U{O4_8f@Po3c^<^#Hz(;;Lg&pto^R(XkJDsaPvdlLpvwupF z)cmNJhwPgt-}%)bchq*DiL1{&hce}zKU*f)XQt{YR=*U?pE6DNil6e0Q`Z~0{$G5? zm+O>J!q#%6K=ur)#inqFcSoLwC23_(s61k3(h=ysX0AbfLGaFv4r}61oXmRiW4=Un z!OU*mI>)Tcm+nzwhrp-nUOwczp{7~;{{!#o&8B}6-!-*9PtZDk;jYPz!vfQuO*kwN zZ^ycFd3nX-Q|5=)_8bVen=rYros7tpkF>Kp z*DmSMT)$HA-H~OyPfA+y^i?x^B=%03(J#}-Ec^Y+nf4<~;=L|eY_sw6Vdk>kqj@&{ z$+WjGz8(5;MUT5PH#~6CHxEwdtY@Mr)hko=iYgv{7T0~#eACx+r)OT3%2mItX&V>k z{y!+pwAfgIXq?(&*Cnfzg4|v$IwqeP#=z>=JbxkuRb~|RRkd0IL zzF>Fe0x9_xsk|vIvZ_CO11c7r7S1vdkZyl+gxPHK#!kiAzH8*FLj6IDfbOZPuNRPh z*78Yd-JgDKp3J$=3tEplJk@l{@!!GG=`}z4NzAbp}ne(gQC-3ZdhpdT@C(rJA8n@$(^3p#G z${4-Qn|S3}cAh@JWQXkRsHC$;m-R*Lc6>GA>)}g+yDW+pw_UMt^q;-s(98)|L2r*v zm0uAkKPlU6U4iPA43~0a%bz^~RZi2@&3PN|bjeL$vP9h}u_exI@owp3>ZW@QE(km* z;#PgCs`^vTl4s-7`lO~NX?NLXec6Xv`730<99gCq^Uyyh&e88VXqUJ3#m{_)8JLm| zPn_mA$G+aqIVnlWca25iJDcX#iHcXx$jxO;l&ET$+s(1FakiT{i_mNKm^!s7$2tt>-!N(OmDMa{ zFXG<#lH*xk(xX`s<`c5acU7;PDBgK8`pJ^)JTCn|D&{;F?|S*vENoX^n#u8m&FhlE z%2Z{u??FLoh5-x{?mB7koY4JUVA(%slf+HlBgd@u>IEnFdH6>2gfJXg;yPh>!BWWy zGKTNm!kyRbz41xsutvgy)aT41dlsByUm@(Yc0rnCPGQ??x!%SCbq(VOQZMCK6dVps zm}sTUbo$4M3J!JHtEWM)SJqxAKmKHY9IOSJ2W-`pmGdVBz-J zD<$)uEK#2D_sR!jv)$~)e=aXth9V8z0@>7at3X_+9Z*KGI^TbEaTwaP8tXbsmA4ffO*dQmkjr>>NVVgy4NGIIp2-Hiva5Qk993?Y zP}f%Kw8Bu>$cou1#Y>8()o`nkjhTLNaAt{2cxqcr#)ZX>P3QT%9tl0MmvGzGJgty< zGyCkl3j2AkwK1KzyW>#ntUNWfHz#}LQ_3G@cO-b{-}uv^%QsOw>B$Z?RbJsw@@Dk~ zk57KS(j#B8*`t)Z%3^{P{~ebpxjP=U23RaOT^zhnW@&1bn%Ue(r+4!-GbCt#|L{~d z%SzI=F5#PyaQ==vj$U=j$K;AW>+k#27xhm$g-`R_gVXiQQ+-bIR(sv$jw)k))pFt1 z{VOqTuAg`~HZJ#HxY}7RQ(dir<7~@>UB?^l*a~mBykH++!a{GaHkD)Z7w|L*%6o{a zYsM}8vP3K9-O)6?O}j6A6%6Wsryd~jfIHlaE4pSX&&Fp$!5bz;XI@-%(Iscr!m@`w zx;7UdPZKNT{H(vQgypmTHaG62iH;}oY6_jQW+>cl_0>0zIy_tCvu3A!))MuY%#MIr z%Tk@0@A}?&B(1c zua!}?SIR3$@5KBUGp_7#;n&Vu&KUK~C*~m^w{X$hW7FhMb|yzHagIq7(sFkA^y81i zTN9to`<{i|s_&MS{Sn}bcdF!`URSkDxu%lsnO(~F0I7dRmOMWgvOBq0ze*w@*x5sV z-=;b9{w*)FbU5+$#w+=lpDi~ERMqxqoD4p)gt6+FSa zS&GMGQvOd~HE+s>#cemY@D&IBWe)cDyeIXd&{z>xT-9@PRQlFYdvb{ z!)I$Nd}@8msiK^h4YPa7m^D+?buY{9tn8d)(x6>8@o~o-lZN#QsdMs|=8xlH& z^0=(!uXLoAm^T=yt!(AD{HL(JVR70)k37Y`wI3Fm=yiS+-z7C+u0hW{u@5ubb=uF~ zy~2?k6_UU_G5*6%&(#~0w+Xha>5JI@z)Sx~i>_v2m#^-|Ul*@7{JCJ6tvv)zep<&+AEA}@oX|4O>t#M}M zOt%wX#Vvn%l$vid>Z}&n_T25a(*%J8NnVaWiVnR_6Q>v)n-;lZV&Th&{1aq%7+L$w z2`OK&dU>g1SDxL*Zx26PFJ#lKYVL~4Y`9igy@0DM=&h@t^Bt48s7_tkhBq$$#|`YZ zeR0c)a_WmO`oeQ{)BHJ`c*1`?FzSx06u23C;$_Q~A2J<#Jo0Axy)J3jebd1iopgA@ zjW6ywQjeBhT*GOZ%A~k`!sPEBz4;~O$=dduGds`ne5oo^xb!fiTH2JwE!}}Fuxml+ z()RTi7L*@l-PA8)o%qW0YWqD4=2k|lV`5)hxFTZmj;r!*7LGS+zS()U|HzBu>1Mi* z#KU6(UWFBHQd;<9ky~qL4x8b_&a-|sFPZP&ztUwK^yY}@w;zA{bY%-B-#mC&)PD;P zchDOZHQB=8oyFe$TYSCd9iF*?GX);rh_=5QR=XlOt1f`=n2Nn!;{*V(utW5u0y3d;i8X7VoT zER^@)HT!-+Y0kvE&g(0dOtZbxQ=cR?`AJybjW2+HEN zzC9=s*M04objM-!j-%7#+M}utiMns;366OwDpodS3j2;%+(nm_%s#IWG`sRaTNAWh z%`NMenwj1X&leSwrT0HMCb{;}{5!uUUn^BTEWo_jSfN6xC$5t<`k;gE?w2zk6p9uo zmaKvx&2o?RaVNtMzp5k2?;l_nfk2 zasQj~G_5AlM&go%W$%%L)BdwXR~;66enn?@r(yT3RMB<6`fru$Y%4L9I290d*;@DU z{0Y$+q05YUgbi*nNE{S~~RIln@ z>Ckq1c*?e6u8G&>HxA2EV;**`zN4`0kJ~r?t)MLykGbsgwtNzvFS*6Xe#sI2GrcXB ztk)S$y_eY;_meNWqM%>zxYUQdGcSa6mS{X!_K_`=O{VN%%gTvAcdp#SHv5K1m$q^9 zk&Ay@&(Gh|#hmkQLD)NGk^CEn*k()Y<*u*!cU*LS^TA#N^98#nhUG1Gb#>LSZTjP+ zUG3@n{Z2~WBvn(pjH&J?PtKn*jd#lz?xLClZx)7DDV82!w_SVSNAuF0!(x6nE}8E$ z>0kY4VOXux*_!@$@j;Imr(0|I-d?gKG-d0R6TvUaE-Tjto#x+N_BLsOsYU%`HD=p` zFL*eZ|1xgtv5nx$$Z9#3uqr1*cK41yRw0jtrj8k=9lX*6#avj!KP|4AAuEC*sMm2}eLH=!j z7`TiB(w@mF1@V=0Ly=@hX9TH6@eDv4&%eUmWLt?vbZXy4}(%lBzg-- z@^qLZj$He@WJ`Bj)bI8?X7>};J!jukZhVVTa=`_8o>t?n+RGMBIQik{%qeWV3lGh> zvtg;*9D!^$y;A16W}dvvQOm6Jl+q^^h$`>6Wli{Beo@L{1U6PSrB+C~=k}GyGRqD1>Arbt?zlczl`t zQnMbvar>1GOUf4Z&B@y^v-kY|EhXHBqPF`sD4X|QGO7=ro&=z z@a@}iD2?Cnqr=$}&#YaKmKC~pR11`Cxo~*4SY@l!&)JDH8ZYv3@G4KKp3t9>aJu9P z8~Zk0|SFziEBiOb5UwyNoIbY zLP%zADnoE$iGqQNf`4*}f{}rdse+-Qm8pT1iGhNnuY$8{a0vh1%TE{>7$iYDgY(l$ z$`gxH8PfCeb5nJTlZ#SQ^NKU_OWrf@w_{+K@!8YGF{EP7+rQbHR5kflaHoabH~jkN z|JMzh-fyy*v&e(<%d`VuXSTk*k-d|d&*{Ze!T;yu>;HcJ|F{1CpXdMoe*XXa_5Tmw z@7Mn~{rvp={QX95He5cfw(9KW zvYrb&t~tkCYCrxt=$N3c`nA8V{qr~bU1b0Ews^Mc`k?0@QWB!rE!TYDncYXYXZ4s%d^EnIasJ)z;1EA6 z^?B#}ZMTQbvz>4H%i!aieyN>X6XJrqdfZ=_yxMm;C@^i!CfPgH<<TW+%bbDa~;hRaU)`TW7v=Sve*KS+K~7v;QX zDSzR+(3;J1`@iX2(=&Q4m}_w+<=y+)e3#E`OgrWB_^WrHetFDrKe0ccx0xqMEBD-fqro zzVvNZ{m#!x4+RS5n>y_e{QaTt!TGo0SG4avo_r!)_2+~*`wJ(oSH0i$e(#EP{}-KW z{pxdhPJevzwxt_*j{o^As2WJ^CZEq zZ41tAHT&dJI4RF~gUREs9R*=GjMX2zWfv4G|Cm?poo(P{oE>F{prwz+>UGr8sc=i&CdQ>@@e5`ZHC$sT?odsb zcyF$Ash48$ucwbBzh1l7o%nW+*MXAjFQqbXi+Mcn&6e@pFl%-2Gi9Oom7niTpLyy7@|bQIIzGWB1cii6?Gdk$e->R{Z4oH_MKD7V|FF zzpI_H>&Z+lx4$o?{Nm&IE?s95)4tTPE9IWW_mC4Fp^3Hc4{VCny7EHxyOdY_tm>V+ zCKs>&T6;15%iG^s+p^2pzMuY;EI#8zRoOc^k^PS!27X&8ds;8(kJjo9u4f%tAAW25 z)pMyZa8b(ZubUs{WL}9r^H%TbT+gjKFZZNx?tSaUUh?g8|K8A}1uIpyNBozoI(*1d zs=E93w&{AyzvcTbvrRjhr@Q|_&Yu;pay-7Rzwz+~uZnPnU|hK!+iuqF^O}3gt2O?5 z1%J8oNh^2$oNcyBCAX?gb1UTE-OG(g{A+WqZ`0J^EmGg_>|1+#+Y9riGtWXqZ8nVP{iD@4tz>OzAN#Z1P?InFAJzQ%5H)>`jUpYHXGw-}!E9p^u)>6jP{$^kMx0PYyQomIy$`_Aqc>YiJds18XltTS$-!g43-1pB& zJ#zWs+NA2roAU9D+Urjp%CcFuG;Av0cloz9f0(CSn|j9C)P0ke{KfBcPiRbDa3?-< z-l`XjYY!f+?dv$Pi|wrBqSB~UXWH9ys^0D8xV!Pu*7|r$=0(2`Ot>Xk&;0a!{Nh=c z4L3xH2OodDet*`IwduEh{%DU)`F-r?fn#$^8C+x)Zb(&K39nAKU39zd?}tTax>NXU zQck~`cfGXo=p}jYy$Pz(a*-l_|0TaCZ##STdF3^!u*HimC+;jiE88zWgK_fTJ_eDW z|D~o>-MzdwQu;v9#i;f5OLP)XMF{J*-Rjt5zWJ@jwNDnW)2q$~d@ow!_xA0nvb-g) z_H8LxWne3@Qh&{P!PB30ey_RqVo90Br(C@=W!L+TAN|;{V#d!O7jO3ecM7eV$^PkO zz{0-z+~Drki}`aCH$*7EHq1OxwnpdYqI)}Ay;3WL{MvT5<MXy@QqKCZ*<^h#6Snf+Yv+w+C&(^0bUop4q+0Ak;?qKo ztao3h2zHlgr@q%xtbJ&<%GN(`8t3`FX_*3%(<0W+FTDLgNOAx2!cg0CMQO&}WlvZ0 zvAempAI|E%V=NaDTctMf*hStqo8)(|a8Yw!S2k0p>(b_$z8=euRtrpSw%(n0ear59 z`l+(b-*>Iu^g^|GnpIBT^{R8a^X;?Z_MUIQ+HsCc!6A9Wirw2QwsA44p10Giu2k<{ zZfw{k{kGHRn$Vq}>0)Blb?y->uUdV`N#4K6c?#$DmdxISuxRg7ZXfU5nVFf_zi;j0 zd%MraEem?-?Y4VfZuPWpwT)d*XGsKXQ|>xb>|AxNa?`y3*3pSen-)*ud@>F%HkRra-t@oLS~UzL61)6?yw3=gPXtq9eeTbfOlK|oXH)Nc6Mwt{xWHL z;(N(E8x^YWg>OhW`|g*H#&g>g`z>c#CvSaU&X}fu$w+R_*{8nwES57Ct(kJLX%64{ ze@ee18+kIhAKyCN`197h-De$7oT>2Gd3E8+ws3(9hbm_ppL(4x=)$U#XA^w8Z;^23 za@%*o=DjRQ_759Z{52|PV9T7W%#|++IbG=R*Rk6 zw}NHqAJ^_y$JeFtY1@*&D}8+_#dW9bS?$HPGG)a_vRtPm!er$wr+q26sdM1Jee8d1 zLGY1zk7xXzU*CT#V$SnzQvBEYTz|{GUUjl+O?Fgo*F}eQi=RGJDVQ^J#R;QUtzBb)~hSgxzF%lLjiv)=30lx>V# zn`@shbk;U}vhGl%)nz{R{;Mzg=k4d>JHBAb})gZt{6Et6%ci-Dqe2{#f+9m1YI1%Qx@9yRJ>HZjY{7wJ{T}Qod_leE zP2L9F+H~V|*zbc}rz(_6Qbmov{g^J>7aY*@+45_(p84y4uf5j#h4`8}rYgn?g{iNa zeD=+h$iDN|T^z2JYmS}IOy7R}`un_ME5DUrg(tk*$(YCXFr-TQpyn&h+;-*r);iyp zJ+1q2EjS?hVxMNaop^F&uHm|Oor_l0o_=b1Jef60quX`%?I`=`{q5`i8iloQUUvTa zugBkVce06{e-HGA9soi1_t>j`(9cv_HM`X(yP;WGkcF@+)J^qzPj^VmqXTbXX&XArDT^|#hh*I zdRzF`*sJl^(mv)Q4po?42OD)3zmtlJZnPOFSx*oAvQPE%kFfeNr&{;- zMH~Guk=Lx{!~RCI?z8w?>HbKwIP|E&yH5{xcTQNjX2EgZEsqtCXubZ(+}%^#>a+ax z=KWb+>WfS=H(0%tdq2S;H*1r~&B(ssX~(koR8{?>Olq@EPu@_bQ~HB1_giwg{nO1C z+oo*Yaw1FL<&`q`p05tiZhjA4p8P=Za{Q);JGMLy>W2x}@uBMfmdY#|#-C3mlH^o%3dy%euAqdv99a zn3HYvkuR$9Q|RubtE}@r|4~iv^R|}rQFwk}wfuWKt%*B5SD#(~y`qiD&b4{(ucc0B zOZL1daQJ=y(2wpaGu>N->-_YOKG<=W@#bH<``$;h?ffG5c9i~@b?*L0R_31~H5)SS z@9v+TaeT4D%=RSFymM6^9UXh-@Ko|YPd1%&jl)D-d*=p&Gd31`=PStG&+5qT(3*JB zDr$M<>K)hY_oU9LdT&)P_PNzkc8X4~c)S&NUCr6P15MU(TP_zalkGoLA@6gwf{2Xq&|6j{Jw^8DWAAAa}K(=83k{${6Mw#smvseXFr7K#7oHmu$8Zc6&H zH>@x1X4hA3JneP%e)TJ7J-NWQXFPtcb}PDiAm}sy+X{}422t8yLOZ4BUwtIdIYIr* zjfFL8Z-ujdrzEU(>%7vi=2?M@l(g8}=qa|TU(e^-JHPjk73ezbRj5){eev*td$nR4 z)peVkw$JxpFT6C_SoV1I&pY)B71DP;&A5GVQNnhc z_*F;+$K=`m&^=w2r{MiQq56qQ`|iD__2(kp-xrDK92V>ivCE(IQmgoF@3%D>NiTZZ z1p@=KR)jqB4(xdq;c{tFW6CMxP3fW+_ndus;@$04|5udT#Ldt?y>F%dyy!2vf8S(> z?3kn&V`_Z&LgO2SGih0$UiKVseWP@B{RTO|?Y8%Gvl-8pyUd^TZ$)vm<|3|xrE}KI zVaqHrzqN8(QQWf(d-d!Iy7ob~|DR9zd*iO~!M7L7&&Hj2@HOXn_$EvJi<11TtId5^ zMt*;?mBVKX)5baWp3zf9)56^NcRgbf``eYaoZDzl-}*zP1?5lI&QzUvr!e4q@YU~{ zN)v3VzgaGPSh`$!)BRHUZGFow_q8)dGPO^Q+uQZLnq9QxoW+_sJc9X$y|Y*Jn=Sbs z_34q_5~&aC<&TNZ;Xh}w>fLjWhmlJ6)oG(DQZm zSLze~+_w&Lc1CAXE059S_Dk_oHmbH3d+^|9UQXDeHdKa$zVW0CP) zG;N3b{OPv}9jYTQomyM#Jx18F!O{V3NznWm5|F(;^{mn*d{CAUI)j9$g{-Su#1&fl>g?NU;kPAQ4nI8nCisu`KmpFVa*3kaVm@4{T88lh(w(aPq!+mO{ktFm6M&(@PAcky8WA(&rN~~6xm-~D{WbnG4K4M zPN}FXlkan=Jb%3TYq^&7%)4(jvu_?acCc11E57)5=&i0JS@x0JS-19{oZrsl^!L2| z*2fLsw6-nJcQr0MTi0c?J}+)@WSa8ZWz(N+V4Cp$!|d~Kt>t!WoT`d-PX0RQdJjv< zT-W&*11oDvBWpM`|=JL372HOKFt?g!q%ew|5l-kRKvB9 z%P;M1o_|bhXa04@cmwlAGhO*pa?+ox{?yytdi?pJh~=ifX?ypyP2D6HR#SR@?xxju zPHesIylgWYTX}87^QnK3E$o&`N-XMX7c4m)A+|1kLQ{`*lcKOw^=PaPRq*S z+M9X(M$e~geYhrmDo^|KUC~yopYJ5i_x>>D?}@)TPa85eSJ&qKKb(D&@5S7f*$v+o zT{W(_6%g-U?I-8Gw(QNNpkk}?KbbGyh+W9Cd;WEIX>FP5vzc$BG`CGYSfD*+iaA?q z-p<$MQvPCc?Hj`SR6d_STC}J6P3e?rSG;;oU;cNo=ee3qk8hrJ+_{5q{f;M;Rq4(< zXjFagLT=@`J*#B;cRF`naNxh-$9e9LoQH_{I@c+m4=QRMDpeNiI=#vE^~Z=uil?ug zf4cCn?Xl>@_iva=1;1Bs5AW=<+A+89|0B)hsijq}OSV~F{T6TdfBxyEf+cGo)lR+o z^MF!g=xM1<7p4WjIVD)>*Puak7p@UJ6E+&Zl4o5&GB!;z2_12*Ar~-$=CDT zFTU89+>^*Q%l_oP=XT=hHrs=ihFnVWi??1~ACcyvdwZ{}e&oe-t9L#&JaB18FW;F5 zm!z~`FSN1S-8wf}ZEpY8y)$*xQ@+$*zEvU1CE_e}OF!OjiOsx=&g;FIBg_w){?NS1 znahxsn{PhvRLTk7rT*FNk6V4(%`W%8{CkY8e`iUtje_5M-GGeq*UoFi^=_FiBk4es4?DY$;JW(%iww@4V^^)+KU;almsj65t^TD`x?e*XR#xhzhqVp{RLbAjA9 zt5g@AFP)|F`g^JRW7eBHv>tC{?sm8@F!f{7bVkWDfudaw_pRoOoj>Ty>ukUFWJLc} z$+IO^3T2OXE_FFl6>B?BI?H&KJny{EIVb(%HXqw7?f-30)$52(z3C_Pu1BordTLp= z?YQ>2>7o(eULUjEY4ms_bJv*?wkP$O!`@QwVD@(NErMcdhCGlkXC{syiXE;+E@Y{d~O5K3Q_c?U#+SbHshW zNj^G#?ijzv|GReT=Pl)!PY9eeGuYJFlk!I3*t@+uzr1R{_R;F@e(Me!UZ2xj7fcIW zo04u}lA19!<>zbmToy4#3GE$^BYNNH9M62-aHe8D2&Wjs&&wJF6^gXTN z?OXXNhG7PF`St;M*I2I_#n=BmIz3w3c3EQ--!aQ>%kzs0_pL~u=W0EtI=;xtZ;S4? z{J8V~Y~EJ<*`Q-sC7Z=1`|F+C^T+K+3J#^bEU|ZGvuxA2BERI1|7%Un;8Vwv_1#Yw zF0s3m(rlno?Qp5=%d9(k%%NWlL)X7K_k8laLz{jq|F^=U#Ng?^pLHi|uRgfNV}I-6 zgO8VLY~NS>nKAXUlxEh$|K`gzY>%w{taW15|Gvb4;$t;QJfAEvfy=iFxnikFV>zQ@Od=;@SS}-m4rx z&sxN+kzI3wC*#@*(n$3`DzjQszP`BauiQ~agZYfo*y_3}XG@2vCMPs>8= zo>%;NAa$Adyhq)^pAYU?Uy#tB!u<1#^^=%4zgF$@o8>%j^4=~ZD`OtMOqXe0)9qwm z3#HoJS75*LY3eFIjw4pf?!KSV_xP2UrrhuEuFDt8@><5v*zIp6CoomC*wyb?+xCr* z4@w!z&(FLdp+ARt=BMAe9&`9sGHdSbcW!lPZ#DGQ?e2VWe0GOI*VMX*{fE6K=UwBT z(bs*URqRtm@v`Pme{$_Vu2}Hc=*O1F3pFQa{(HFf%|x?ToM(^s`bDVC(qX?6_M|o< zTJUechIicBrJJ*?gVxV!(h&TVPHt!ezqVj;i{DT<5GEulaSDo3FJmw}11c zh`HI4OU&=M?wfP(?#{gbU`?o~{XVny`Qy^Hn2_9{hB&{BGU<&t|0p|1?#rxqlxhUwt_5poqUl zWM7-Vwe0_;@p|zG?)`poR*kv)*Z&PR0k$93Ox%|7I8BM~>D)Jg?=SCB-n6aK_|}=D zZ}m;ie=@LpoD>+9Xxcw-*V{Ck%~7Gxw>SknE4}sdNBpgi3S#Fj`2BlAg>8tMBp{&~5~G!hS5zFz8P_Ium*w+(-oMKm@<{4O)w$E)TXKmWSk zR;L%!n`<9T5f7Q4ooRA+)!N%93al0>pPq0h%&J0Xlev)2_b&4(UoX8_{w9Zg`P*yW zX1Sq_%G=+TyohM-Zk~6&%x2r0DTUSwMH?#jKAbCXMsVt$-ycP_u5wqq&0ENvCLVZh zLUvyLEazb9EhlG4XZSvQvH!_To78iY>i$2LU-G^v#MD4_*RtMZ%ca(06&c@Ftnh@3&h-+poFib=$8^kngYTFI%N9nZ5CG zWe#bw*-v%unCb5pe|FpAS@9;;YQO)}>y9^{@GN+?BEmVjm+k!53A?}NT>HKF;Ju#{ zPB2`#cI%mTU&OQGh`k1VYyaL7FUc2s9rws?f9T4o%g+1UY&`a_{fFEF*KNwt=L6?` zW_wn;Wk$Ttib-cZpBenjx!ro+bN$yjhf0n$pVSNb@VK=jK&|-71C#5bA7t*Y-BjW% z;w!!InN_&hu@!9HJ>5_2y7w8Sv?oo7JjwR;pH5s?SM}Mqy3en?so1)9QF3@vc&yx} zmp$!Gu`VlG`}o9cTYC644ja_RGiJJcnBp0^{-lfW-}6k9jNjGHdcLJ+Th@kCKLXxQ zobYr`;q|m~Hizq;$3hr2ta)qg_pM&CTp>^E_u>U-_ifvIXz}v^_jDVc8K;}sWCI^8 z44rWEGq03X<-Ko9Zfu^sy3Nm8&Mm~WBcI9mp5>{1P0U7%WzWBiT)e=J{Ygvsp;Iq* z9DOK}ajeVrtER{1`hfrD8&0*By$^5Me0=d&!|MXiw`5N}x{2X*$NvRvYw|89&aAN9 z6u(rKKiOhp8=KoAi?zIUy4Ox+)cUP?apb;oD-T`yUG)oqsmBMeK%g{l7Q&=S$i@ z&pv*C^YfbL6;&>Ex~DQWeA9Tm!*^b|q-CP*{+V~C+3v7RFg~V#^Y`|(!e7cg%9Fo) zK76IM`rG2`?NWavuP0S6&*itWt*(h-`!i`))Di!wnz1x+3k_h@;a-7W}IHP;C20)r{Ood zj%4vHFSqw&7kr*j-5Xi9;PA1>0_QI=n!lc>6S*bs{mv&`lh$%oo$Q``Z|3u~^1Htz z!=5c&c*ySIt9g(>@nBJFe~hwXV&4Yj3!WNng%c`}q6q6YN^*mTyV)Z0%`$=JWfaS*y(2ec2gX z9t)nS*|0U?b;F|0&*e9^Husc99DiuY_9kHYry`SYU--C1ERVdKe(w03#FIujMluX5 z4-0o5ty|LbS0!72uHcR0tZ)6MyC>b%*pV7~C42TVslR>h2FpFN4>JdCxse#B`gPB> zo+{UJcl+#mYm=LkUcKRa9cpHis^ZM$ubEEXl5hULMJs8cze-il z;a45iUk@iPZ{Kjh(OP!fmfC0T={8K6j^7whEA{MO-+sy~tfa87=KSLs`?tT#->}*| zexX!KD8F6ziv_7G@5n!?ozwMs`qYmdM~dzz<_2z7xUlu=X89@Uk5d|t-QT-nTH>Nt z%Omes%ojat?@?N_dAV#qgGJzcu_DO{fxMDmid8tR9%!GnH_6l1I45ELDkk-x-_xL3 zhE9I#LN#ycvMqD{wuUL}@ng*z{2ly>BKoQlO+9Jd1W~y#Qp|9aSE`yH-j;zk`8*rN<=>ki+@Zxx#JYhxI5$oifg6U%IR z7IGMWlPpaRxRv+s;gTy0S5$5*-2bh%Xx_Eg#tW<}gEXoSTD{s`z3k&(E3@9uhTBsE z!-8*qn7$w~`gPHYi)!0-b7$VaWv;e(-ua!<;cVt}Cx^t^U4CxOoBOQt``>kMHa@)E z*RD8W({l;l&tKO|@`~QDRGivd?RBKMCjMZcRC46PGfz)0u=@J?>!00aw#H%;jC~{z zpH8TnRz3f#gn`X9wn>#)Zcm;p2%h_gD@1;Eh~Di5y^h(lQ|Is8eyOjWaoWYMtun8# z>?{2r-)OwwcuvnW)8#ypUm~yl%I;ZsxpsHivu`?a%vO+gonZ^0*_U%)#%zw^5_ydD~;lO`XDi-u!##uKkX?FMlw;U3&NP z{AcHqY!nBhEVwWEbAr*Wuc=2*?pP7jX8IsSYk|*$b#rx|nO->e^VgXh=QA|U zi*8g~&U5A6@+n+x%2yx8*k6BlP-oHkD8C6UkN?!4eA#jBw+k%a;!*UMH)8sM z%#WAEr*;@z(>+yg@%zu#VxvnZSD2OG*!f>oJ=n=wjzvTB@2Y^~X-jQvdS3D@FnOi9 z$m0HXskpdfA2@v!_pRVr`TD5irZmadZ+gGYZMy!%_mj=FPd}#awW*&bc=O)N&p)kt zruPJ_|NQq`rDdpePxh?(jN^|FXiojrW#Fl_bI$p^IqEAJIZv{w=||kU7qxJI8b|O7 zrRte&-@RY|`&#+uk(^w_`rj{O+U*uwNk!P3-{zV#>9Ksg$)@XC9aF`b4T5fcyzyaa zk&@n>Pt&4h1>SQ!)(n09v|*1(tM$Z>Yl4 z-xvvqo!@nN_B_AitG_wjcC5KI?T`7~j|@8uwcpPPA+Oc5}bTj*T_fe2(XyiwTe0e|cZt?c;4=L&8JT|CbFjd|H^_T0}uHqWz>zbZf6EVsE^$;3$^x2*<#RQ?;FLRX6UDW&@ndxF>8xT2b`Jtv?v-bZMig8!EY;bj5Z|midM4q4>)vvmr zdmTId_(G*z<_6bSwOwzv+ZLNoWtw@fX4#ch%0c--x~Vdn>5?<8)~sJYJ-+b1XV;U~ z(v>#t@za0vEN6bLz3P0{uXS_#$}0o++syyCVu6Ts{ffv5E2i@rKRx|B^7;v%l>1>3 zf4n`H^9W3COc1*N3}5$#tpko_HTCv`zD@FF)My zZhyQ;epp#{UG;~@S;w1y9lCnD?L4>3n)BxvBkiyEuzF8UI~l*^bF=O5A3s0I-AT1g zyLmg-{D0ok?M5`%65|?ji>5S>MTV?i)0zr{Qp^fe&2Pw=lAz39DaT0{VC-I%}2fZ z9Uf0uP?%uyI@h#r&DqJ#?QfT^Kl#CD+vbV2^P*20yUqVtwkN57?b2`&_LS>>X8u#6 zLT8*=aaiM2!;^%KJ5_TdT$=s=X7@aOlTqCIuRb9)Z|0}hJNs2GUc9{9NRp4)gzx3v zu%$h-3^Q)Ep3+$RB(2n9^H(dgHm>Ks&m?SQ`%Y}qef^tF|EBVteT(MLon*P*XV>F} zGj;Nt6@UFx>z^#F6l$>gqwLxhS}r+?i*x_|%xdwUtowW7RKse{(;cR&wVtQ>5_`?Gp#4sw3#iV8l}x**#>H%)3% z*u;F_|Mprb_IsYBlN>JiX3m=l`wDimDRcLS(|wpxV(_U=a20$0dQD{S?4O@C$^`#%x%G);)?_MJ_@2-@a6w~HUJ!;C_Q=S%N9!P23l_&OIJ>yHSYyH(ZeEf?x z%S}D!pwFE5wz(-qMzTn~&|(ksy3jY1G}3N6aHRx0%wJ#YwJ^=a=KQHGLE7BS>E#xM zQ_lGA`4z)_W{3R!!ga^rUF^$$+njB1{<^F6#2FjokN%WMmb`EJf5FtrXMXSHJGJ6> z{Nh=~ZIV$JAJ0sU362wen=|KE>zBXps(1sl%PzS_KA*|5?(VCpZ$F-Sux5v~+@#(| z7sFlt-%H@)3s$@5b*wwKrMzZ;oPE9jPWSHAmshQ}%~fWN)qh)_Ykm9YhK@7uJ8tmL z%OCXbDQo--rKJ9ai1pNiK?}2TkTh$t&H+NogTTkX6Cu$ zR`cX%x&?-A&=FiN;~D(RWoP{EHknwqt@n*S=Ns&u__AcpFZbK`IQ@?wyPdh|)%&e` z3pcgqSvyNgJU+-G!$XS$ntRceB_rCj{Ej5P^?d-SE_ZYWmmlIs>Ye?9Z~)@?5zHmu2wW|G`A zv#2b}SWjPS*_<~5-;^%U9_EP6UYyGp9$5+Oze38SmrioqP-g%C>r^9lc3g$h3a^`MMf%oEf5kK{| z&%J%)CVSMHXK(H6Ef21}cy!%=+b2IhvueppT`WlL=$dYm_|{EA)4J?;cJA_3Yt|+& zmZ*PS>~15i`fAG2b3fO)e3?~v(&&-K?+R0%yjzzgmOt;SaC;NeXX9>QA-QBdo2JpZ zr&@DzUToZ7X7;0Muh{mU<0lOk*gd%(@!VHRqA%j#I~Ec@5Cv+7p-R&zGfe*5xr`b>}Ghb`G{HuAAW-L$(@ zm}+@0%;Wpqskx=b>gr8K_F|u(J*r4J#t>4xJ??X=#l&v$i5gELx9vE_b%o7DPFwlx z?EuNY>uT4{`F3C8_aC0m=`%f;q$Va$lXxDrh=()lCI43|?qfCSC(=?fuk)X|X?J%z zXK4SQ*e^5xnd!y0PT2C@{BqcVbIPao>ML?)?Kz{l!|>UOs(W|h_2OCQtxDL}H??T> zzK#FvmRvA>Tl9YWiA8JPMs8JQEmBfY*tv37zNMQttF!8+{8yi&-t}Mp8e>shak?hD z;MU>L(!ci`l(izaU!T+0@t5&yyQRWs)2j`0^1C-~`}~oA_bYyW+1KCtj(6^Sw?_P* z{F>(rKkfPV_xsPia(u79&N{JqsgKiJ7isU}nS#d+=Dv@$Uw`D?&a$Fsrqg!j=Uccn zUv;d_>VCc8%>$d@tv|QDyB-wp_Tl@oPmNB?dLO*h$e4FLDQ4=IRJQE0{Xg{st975& z>%Bkv&wPFUx0!btS21?I%T|&Kki7oKvOLCEg!vqIpK;0Ln0IrQ@HBsH%UK*U?Z4WT zsK_Z3LYQxzj;nZiQYY`kwS*$sK)$27{VE3u0c zq%XZ=KE2Uxin%9`_6f~ZTioWH*f`bcQ{BHemzdr=`$nxR>NeIi{kH1t&d}e1zm&Y} z@+=qcc>HC8Xo5aO$t==y0p9x2JMjBbg=V9@a@eR z!d)klKTkRtGwbS!PLqcHd%`a4>w2|%VqmVEqOH!x*tEqFm-((dvog!xV7zWq?V{TI zuD8#HZ} zc<18_4;lXMpSv`b4jT4ssj!q^EX%w6*R8L+v>b}F6gN*~?7A!!CAD_iQ-&$;EmApd zZFKye{hjsd%ZT;8QQq8ImNNEhdTvXf`?q4}_etAN6c_7eOWhB3UUfXLa-X?_q-Lk@|WF-tS^Pf*=@_eY(AHK;7Q89zRT;b zZVo72_4LO|hqq3THzX|&_p6OM(^?km|9Jn^hYhz@r5&iWkeS!#IPLPrZ>%qWeVsLX zqs8fcU1{s?-2b>D>Udo5^w!wu$5|KucTKg4x_Y$F@>kSMnJ;H9?n<&tS(~c*=-%ZY z*SFd9D)-lJHNNpYeR)8puIl6MOhqC(-@ovBlOM-*-(OJNDj7 z`d-Va?Ytm}WznYMoo;42&tIv0zx3^y*=qNsHOHq*Iv(9*7?}LPO6J1zdgZ6#Vr$+e zU(YzO$$a;>mA?(FHc!($eM2HIGur#eo$B@Jp?l}os;ylb^w#0U1Qze5Eq_*riD+rB zZ}UIOVW--)D!2aa;Z5_iZaVWn?-knEf8>$m%H;cN-_E*f(R;f1ec`>s8`?g<5t;dD zP46_F*cWeAsHoiaU`G%!R6A6ZO3(;!e1sxC-2C;>~{TKbP9_BbJ0FE zq5P$Lx7pjBZu-@8$>H>#{<8C@=VoU=7u}_Q`{j*PQ@52TthR?Nnc2sqRN}G;R(r(IQRZM`#B8as{F3||hjzR9zdIU~>P5Y}HkexX#s^($>s@-t=FXjdk@c1N z%OCHb^JbfL?(D{IJgaxvuUg~Dd7Rl<%CP4_>)E5M)^`>!a)>H>Y8`m4ed?Wr^OIDk z-#ZuJ8mn;9V$J^G(@xLMZ*4Pd3CVkAIbluj)vBQ9DP?xY-e+6y{_S65*fq0|?VZe7 z>09@|Zha-X-uS{MU!4e}egCbZoP|u5?JF zop1fuSspgBJ1_qGV{G&}aqG0@rnjaFuDS2{{rv}{921Y@TV}hTlj(oGHbt}Oyz9H~ zJe4Oe-4%T6Tyb{e^f_;C?L7K!V%pZF*3;QB^ABBT&iOs9 zno%YF_`>EW3z6O5H2=D%ZMCR6zv=$W%b(}%yS^vbDKnlsY?AQXoSuEkziX~;_3Q1ZAHzS>~@_sLOxp zOQ$8%XVbV^cMFBx%|X(=(+@-j_fAZm`tgH|{`N1um)Bpvw{k*glLAk3yHe3mT{{(9bN?I<=5wT->-ZB;CY|24I>p}Rc;Tde!NAQj z&P#l%&Mi;1R4(@kljL9H%O#jCkr`0=-T9{Xy=vyuPf{#oKl{J=EpI+I{$7aH^}Xj_ z#l4rf^)Vyj4d43PGQGkxGoP%foO8XvZoy)i36qtRZa)80yygAFf~cvLh2O;8>vn81 zJAYToblIB6>wHgVFRj*Cbtm(!yH)veJA)0STi9lw*GfsX&P!J}zn9K-W&XE)Wmb<~ z1g&-|Fn4S*+TOFqtom7y==&gb&U;=}rh67}?0UK5X31RBIM=UZ zd9EuZ@$m$=?ONX!-%P$>q5JDmTEMmH4d++p&fQRArF3h?K^eyEMZXq)k-qt#&qK`m z^2Fx$&s$%~_q{C<4wIbA^(kEMv127?-ri|Nv877_nY0yeo&7BlouZ;V`^*~mlqK_< zOSi<`-hZv(`Gb$|*q?uvowG5~Z>@;uG-hWjv$NL5bIvbyIhC=caqsNkT+ff@^ziM= z`Qcu)Nz!85Ja+S&CfB}gIJzhMo%z{{iYqsQ-aWLCzuKC!_Otx_N{8MVW|j#z`?)Ue zI&(Pb%YL^VYo4X$c?%uA{zW_0eB0gPj5+2j>{oxY@m_Q7wQXu;`jqIc@|9@;D+}^c zQtM~c7h9Pt$sAr|?9FWQ>~gUObKsQ9?N-9R#&UA0{MlP#i#D9OqgAtc;a2Mfx;r$5 z3be13&i>B$Jr`D}nH#;nI-hpo?*6^?S)w0Ouaq;SHTXTb+ z2w$E$O>mRxFTYy3H&N#-m2NJUb6dFm&G}7_?q0v8?xHFia`Iuuw}gXi+%xS`8}bvj z?>Drxe|g~Q&jZi?UTJeVetyTEm_FVkQI%^a@7V2U9Vq#xCCBY?&z7LR{VIB=+9!cZQ)DR z(z4cj4_)2;`RA^0h1|;7-wX$OB zw&Db(WA9DBODOiaFSpN~v3R=><4enWc8y<=nYHD94sFavb>DTWFA6*jn8!Ecu8e0% z-Q zm*HZb{c3Hm&K>9XnV9NYsPoNXNwDa|qZ1s~GOlw8Svkjj%biuRng7i#WNX*$ZB_Zb z`}beARd1|4+N0+cE?gQGAIKB)@Zz$~I|ZAv+ND~jr?>~p6+aSdwdT%PWIJIbO$p4oA~(AlJP zusV zr}nD*6|Ib9?~^&l}x0zpg($cbKuT)MnoT4lU{0 zNw>02b1Zy%XOGClO?A_vPjT$My#0!y!{7e>)mNT*-)fm7wc_v2FG0l*=4CB1eVZIP zYiqvd@|{iVCO4d1we<4Dt@*lN_nFHTKbzTl&Z+ue+HI!oYYuvEJK2|g@8gP&sZ9@M z3YKSYEG+O|wq$8!K=h68Q|vT8d&y>}9$#l48J9*6JeQ{G&kyg732bY9zRi(*$!zo1-3t~g2OtoSJm z9IonF=QgglFtE3KUJ-G?)?$g9g?aMAPL{c5ve($ZTV+~umwX7fUa>iH@rkP^_4eQD zP3}qE+jmQ>)V}b5%!Eq&f?spj$Nt~fyvc33p~tUdd};a4akuSKZ8w$N{PWrD*2{*C z8q;sHT9^Ixc+ht?+5YT7>36nr2bW#XJl@Q4T=-ktB9RU6%afm4S&6K9#%3IJJ$v7| z+^0-a=k%BIXonn@Ipq*xcljJ+SFW!sj`AyYifA?Ef>FV&5Rbw)3|8G+VTuKrKWdl>e?UIm?exJg;`v@@bmqZZ`WVz zTFUmw9QL@JFJG}Oq|h$y+MA2_*_N7JV;9__ulT(AvRK=(2Nr8p&ApAc@80%s?$ZhP z!XNIDsIbls43RAkap;*8y5-m@u?6=|ONN{6-uZEpZ{E|%ee5Lx&M7%Ln#EH}7Z{3Z zybWIWUEwt2&feKFOIDql6%@3^Sj+z=XaC1UcH6Bzoke@ua^`AYf8QhLzx=UDxrp7^{a&Bwl&Ot&($}57r<}1jX=4<#JZ5)Y$*|*355xWWnn=!vxKVUD0N(rK`TF=7r_db4`nN z^e~dVk@zGv;B4Qql`I+i>h{$?mzdLFbb7b*ja4$;%|~wDxEme#JY(KQt#}@-zZP#7 z&i--gS7FKZ@MlYmI`rNJeJQyguN%}`ti;i;9*{3Nf|8BUxULBCR#yUOY@7&2V zKQg`U{uMb*=gy;oKNC`tv|jO_EZ%d3`}xN+;o5?A3BMk1HNBVktRh7JnZwupO4P7 zwTtfknZ!5!)!FrFEqMvcU$07D+HL*#VhsE7$S-SF?{B?sWFI;|J^jP{O*|KBr@7fr zy=$R*?99oZH*3>gmSo7VcP^fEG&}IJzH4Lp7NhHa?vH!jj@|m0G0!ci`~Ho@M2mMk zFS=6oFXbFNS$OmAZt2r{vl&xuRU}>cF3fP-|2qA3t&GO|_l57*E-|)veOT5!~sGtd2PkJA8%e)SSrsGEPijNW0~sU z$9JM?{*wQbg+K3BQ+n-qwk%?5MB%&rCoh~W=(8zJD{)w&b*<>WiD>5W#Xm(>2Yx=v zoNuNO=6soZ{kH36D$SL`+wKGb)RJ#@q1F8TCV)!Ne7=t zI;kE!%sBUBSy}$VxqZ*HcUZ~E9?j7D5e1ct3P+=pY?vBy}0*sgnxGH!;hCLO{RR>t+S^|WI{~h-+eyTvS+9NI3Is3 zfbZzCmB(HedFh_5D3o)Pym%_dBhjt!*bJ5TI&v)zf#MT%hE{Ez^~=ru?eR;Ip{+ zed?)WE!$#FGH3K|$ql^yIL+4YzUOAqNw3#jSG#r7A~4W?ePsVf$?36fIe&A$|IR*> ze(Czok3RppYN8%Is;F3+nr<>tvG>xQt>wbkiVKu){AOHlG>^a7WW#I!+F zUj1?1+u5&L5_ZihKH*_x^161CkTK`XKEu%cca}8o`0QEu!`*uOD>1G3Q+a_uH$6_( ze1EMtW3Bo6>YaC#R&9&h-)&M8_|x;H$64DyKb!wg?!EHnxM$g_(}#0X_&1ab_$~Fx zwhoJsIkLOw$h*6|y}_IAS=aYD>atIHwDh#*YyPuGU(V~Ab8TL6Uy#?|viW`><>&)*_}|>RKH&|o{$fkx#Z9TU7H`kz zI?hktb)xFunhV>$pQ>y03JurrbD!)U+WhmF&x3xgU5ckBP7FHr@q%0M&ThBBIqS7f zTAs>ioVvjK^-~3g|z-nr!dbcjV86!^4sFUL_N6rxn}Fm7bom$>)XK8H)!ep4{qd4Rq7odFWmA@dZ2c%Ga~3{yt$# z`enbk9YznH&M+-^oZ4*nUW)6+PZ33X%|7?3msUN?^K-kjKz8Ex2XY5Q7WZdw@VYno zqSMrJPLcHF@3!CcxTY~S)qOvZb#BLNU&-U=8t+)zMZAoDy>t5u9=FH7VJ|~>JZ@b2 zsrs;q(27)!3*U8%%QptM?cVyQd5?;p;fl2fF5Ql47CT*66FaTEZI@d2D^2DphHsck zte5BgTl4i!Y(Ve6xa-H7zW$9lC#k9WSGND2O|R*djBQKqcKF`>qd#Gx?FEUc5!Dm3 ztBs5lH~92@KYdv&w=%_Y%ekh|O0lV57sw|cXwr~T-Xc4}{D$Qv-(=q{Ie(w8cd$Br zG3CSL%^%a#zP+2hyW!g8qVqh<`fa{m%Ddw%w{+{BX?)-Q6uSo9^T?gu{l&-f?B?$` zTP!7S83%3BpCy&>`hNB;7srXl-NnajA2YfpRSBC$zKL7$s>e-sk5b(Q@2isM)J49| zTlnhq-QS|Szm=b5TA(fNzN>*jfTn3=xi^Lu^shT`1E ze5cGp8{R1RJohp@Ur{2mb0y!jzZqEqk!cflzRUh{--w$*a`wdBbJwH#4({?@Z#v<@ zQ;CF|Qch0Zl_wKJ?O4qsg z_}Q23X$5iV>fv{6Prf|gG=0vJ*lk;L7cb*ly>G)gmgRp|hwVK$OKVN$QT+oqo39l+ z8J20>zt44b=O(}0;<-6~|Kr}C`yP>Qpk_%DL}jcgB3?2RY#3l;cH(VH1N*Hh1;?n7DNFKB1Ohg|Bzs{qbn$_ZZp!Z!e_v%u|o( zn5P~wUY{y9>wCUe)z%2wJ^9@10KG znvGYba<^+;eDPgkfyeW_b8F*Ejw-EN^z_L!bDq8ZQrYUGKV|R5ZF@J(?ziuJ-&`dbe&^rP2v*BIw^!s% zE?^3n@_WJWeBG~G`1+RoXK(V2RS^_i@3AA*`r7QDYVGa9Ki5uZU3u!=-k!T(m;bh4 zlWw_Ia9`Hoj;)sE21|CCa+@h%8|`kdl`X5ECaA5Nw8xrR{|bX~O;4^fS9R1E0hdGotN{ItO$-ak1S z|9APS?5-;}{TUc>#m)Ku3Wjal7x&1mx|sU$&c#ion;SzkIX?WFHTN6iQ=RTA^Pp~5 zfdxsK35V6se0*``Wo^LgQ`%Sa=e_&AOXeK=)s@?BC`)mrh8ij72bG=QxXJ3{?wsZ_ z{X!nWb(asyK7Lu1qqm}v!xZr~b4~{T7LZIejM&M1#HzoZ`Mq++GyW*`)1?cfWWs8T=cP`U zytLt)uIY|zJe*s;eJ%~<%{lY%^qudYO>dP>Dw^$g{lLVF&t_Mg++2MuIaEgSUhU;K z9d<#1o@X zIceS5KR@%{Y76PsZAe-Z}O#e?T z@ao+0ecrq054Q4Mdt3CJrTfeJ`u|K<-Z+~DCZ9OtaQ^T1-YX#oKHHR)+AQD*um0xi z8l{%K!7Xa7%rfDbRWDNtGUkY8TeJtZD0@!qw?9(u6L*zyj*s7C?iB95aygmrlEoKn zJn*z$@BhWwD_3@XUzYVHL4Q}&`p|0!`7Ncx*dG0oW4g9|$=Q$PSu3Y~u{kg=`tv`Y ztw*wBqh zvxy)3)2eg3)<({}s(Er!ey!F0~IXJt0MzH8pE*`_j+n>X%nK;tHs8$2XdD*w`5w>+e@8i z_ol4P)V`eWRGBzqakdHD#&)CcCyEko&b@3L{M_aBhRBpjdyHPisHeC_dzsZ=vwB}$ zAS2kr_r_EpFk9+Zk>!zDVSg^_2j2BOHp}tT<(lb{a?k8Pm*3e|=Hf1~_eqUuo@w!R zZOtYb=JV;BGMaDoEjiL(wYSygKFc$QeQisb1$6mym)||PD^K#%`DCs$XF-P%0Kea^C%-zT>%fa<)|U{!LqYvHg*KLC-sJW5qe;rg<8Yi?-DkS*g68 zKZpOt=C4(}a)N0qV*R%K{Az2|P;yNB{QuNvI@8L-wpI3T>SJFv!-l2ko{LP}O_^Gb z8sRf5?zrCezkYW9eWmaaX0K0kk4Na-ekRo#lH9yFxIDK?a^*B5uZg@F^DN(nG;R9! z`n|g4Wvd;&HWy|tc)0r8l;zCfrTVecKdul7{nE9>^^(`W*#SHY<<%EwssFyJJp0PW zRJ-Oa`JR?ne#mAuKPpK2n;hAHIby-KXW2U|WZ%u%SDw7%VB&Kt+1JklUP@kR4}TdO z8dq<}buUsRf6M#+yCM}A`mP@R_#^7eqTcV;k>(d(zwWR+HDl3qiKkQfc~%AfR*n)| zV0v-e!M*LTW7d2Rd@uRC@708a+%faXLF8MH?@zU&BrbXu~wy56^NinsFYx!l@wsc|g+69YFNF^`%<9L%dlSTShUb;q5 zug6IV-Hvl+cb;tEU&GX8-CUjCQm^>hux{JgD^WT=ptKMdmY>`Q8mdh$XTjlV5{yf(xHIBQ|ZyU}$KKQKa`H8zcD#Gz9 zr*`H^@lGpx^-G>(+vSTPPrA>2d_U9we6A(`48_++E9|^nYX3;?4^NO2X8Hb8fp=fB7l3hp@jjNx$;5D`DEn%QK#(ci)O<*0*K+`%kp_&+7AcYbO7DUNYPN zqU6qc>A8Y|^{4Ip+Bd1qe!zRY#EbuL zg&o-~nr$f;|8+pYv4yqfM~c?Ov`_uK&(kD3?E(AslZz%vHXgrM zUU^rbeO~1SKabB$Z!1i$JM}*C+Lxcxpj7esxk#RN|K?K#5jN^qJ33F4ovEF>NpAOV z6^HY?CTr*9t&(co{XOg0{rG#u`i^JQ-oDG1$~XD7L$?2ab9(Qa-U=x>v4FUJQ|^3M zsueh@V92I4m(T0>o$1H?-}Gp_u=YJUwajOCx#x!0$G`XT2mHJ(eqi2gEB@{C@9ST# zI(*^d4pXO1)+coMb{=ETd+9Q{`$)qMO^E}t+0za??vy)S=kY~xtL~ay{pSBEHxl31 zCwvc?;(a1hdVcY(700HZdph?{V$E64-JBWr|04c3wyuiU+x%qG#~r?!F8h~EKg-?4 zd3(j{w0}zGYu=xH7+-nxVZ*zPRc5btdCMsA`<)Ya)jxmT`^MCextpA#7TY!1*MImg z-m>}srjI9T?y{+r@BX~rXi8z-$!EW2ZT@jHNW1Ichuvx4-Ym%0T5S3t@AJO!eH9je z8+v-9cN~3bA$j)7Yuks{y4GJmuW#tB6tjHWj@)2bA#FcLp3cDe2laLrudaKu;L`qj z`S+foZnHoB`#6jDn``^7`yYRJe_Qn0S1{t-cjjKkr?%#|(kmp_XY3NSPTsNU^2hHF zYdPOFCjO1tU9NiU{qky~Ig95S@+|#&{JC8F)+K9F<9?U=ye_?&(0565b1>^l<~f~T zEetEAYu8?{QrgI>)5Na6H;nPz=RhWx^$&m9PY-X^+Hq%6XNH?w+MkC8iz`<;3%)DGOd()~>%k$8NjHBL83W zl589wpW{nQ_#An4g>*p5)75XDoZao;aoJ+Y>xwGB%xe!z^pCG=UYGyR+ggsvV5#i{ zmk%b%6O~?04-zxv;a%Un*4%{Wy2Y6`Y1VF;!S$75zaeAMF_&vIl6Z?&D8pH{n>yDZ|x*3vzbwv|7PkUV$%2d8D8Ig9?Un1+o-8f)Jy5q;g$ zYUVH@cmA5HrHf*sd$m;_2VP{{_#`DE`MmDkgn1R;RtECupX}S(w9#nZ-jxqZ0(vWa zXWu)=cBTDT#uAB3w;r5YXPbMaw$$!e`h`;Fmr`#_b}sQfF)?a?|0A*I$+5}YzYjT? zX$Ac}v$d#aL0P%S+jY_BBK38yukv0i^FZc@SW2qdlA7GZRgV_#usu;`r6j}W8y&Ky z(=yO)7>zU`X zHlM!c$gaQY#O8Ls(o&lRCtS4Ir1#A;-647Y#Vy_JId4ls=9Zs~P*y6O^n_{px(a)rSr0<2uXIUPQdTDE-{V zI^unxB!l3iiU_w>ogKas3txm^J`*zWrN&WJ$>#RU52wETFiShL_VbUv)zwShR!Z)= zaL}%PUFLOV@5Zgx`#z^!|6b#3CdZd*%~f99Y+S`H_gQS##}7e^w!75tjF9^jP`y|4 zdx%Ync3-E{5eq}xgjAP`Gq&I6H9z^+@rEP4M(}O6QuFJ-kBv1WrX4!<^TY|K5N@fY z3d<={n-*U;U&t9z=)EzI$7cSi^IOh8kzCVUP-tUfy8S}wq`GUbE#BT^`@VG5esg`p zqFcX(M0u{iTFN4D@9`bUcZ>61Z{1v@cH%-`T=dGt&O4|5(h+l$T+aK#YISA13=8-3 zF%bn-^h|8ng?nc{PRO}6S8>np zIYnpReSUSSC8;CBOeFnY^v7QZLix5^NZD`NB>lMf^uN7xnNA1EXT@LG8y3m7^4)=T zwrka&WE9OPUAXj(!@1)>?ksw{^Q>gP`-3M9Yp#bbm{t5GRio-yQNKguyXYs0+xM4W zUw?i(_qnz6i;t_$J^cSqYR46cZ3b)Vb9?NUzs`GPVt(rq!>Ku@mS--WiJo(C%|=J| z-nI@8fs`3lclR6f=ziT+(pUEBtnShaUvzVsnJ(WAtBp8qv;F<;FB6{L@jgE3;(y+Z zT)|T^_w#-i&gY(7?kzcGTk5L{7pa4vOJCb&TboPXh+)3`Nuc>z21ma3nTS%I0%+dCO*QX4}2F#rfoahk!>l8Mjt8d^@nMCQL_kyHt(7aBfLb?fH=4 z3pYO}>3$E8x3`&hc~eMF^@TP2qhHFsb<~rcy`}!NsRg60cgwwR6=G}NU%Y?Eyu?=} z*>6ixp68WWDZ-U`8Jp)`z22;}|Az6JMzz)HSGQdLUtAej*4?F9`Pw<>?c$H>mmfyn zTwD9(hSA(cul6NR>dtMQ)4*SnkUT&5ww2@6La|*2r+#iod(MzzsUZ1y#>~Zsip@TA zAFDT2`l5NgY!|Cb ztiS1-h1DvJ0$w8ixAaVv<>vmJar--$Ny5$kk8{m;Z(iATQQopI^jcg=&7v=+*OnhK z$agnkzg%u3B^z~E`4Z>Mnb{WkJt_$)(}Y5Uo9;vfaDG;7kUSgq*ZuUXmG;@ollS%s zu|D~>dz(tKpi!U=i zWgdTQxQE~Cl;fva%tDM}b9>U_th1BnUs}Gk(C=k+-hJiSOqPL@>MVYrS}l{kuTHlA z*n+PT>r40@Uq4=WS*hpKjaJ2MbH7YwQtEimSdk8*1p@vWoTpX}#T-OR$PnYO?$O3C-`H zK1q3%onyE7d}px3(%!%sJhi?Df7N9Cd0B45m9VjJ!K|Y{i~TiTzFxPmrE$?i(T)>E zF5krOK0o=g!|K5v*;SSC$@8N(R_8P9_A~1HInTa6>EF^7b0-Vmy#8bN^?MB|s?2ZB zbXn<}ev;%hJJwTJ{o;d`(N9&Y#}gaUTiPG7RBU#$4NG6q*ctR>_pLh}9idw;H`=C) zT$oe!b^X~}fxOk{?wf*EiCtPaG4Rd`BmEWkxB9>Tx8ZqD#l1=yUcQnt_jl|WI-f1} z{K||zIvuonX=~**jk`Z`{@vSkUN~Y)!QN#|lAkAERCjYb_R!Siy-2~Wb9&4%@29%) zXuH-a#%@(kdS7%r#n(kl;kRVC(G!E{Z|NHE^IRI=8lFhZW&fmi>tlgRmaucX`LmKY zcAI4`--#=2-aLuua5i1m=c*d>8zAPT*4O-PyWx)K-^iTrZm268!s)(7Lb2 z>%T_N-Tbw>-|qUpw42}Fh;s++T`@U4a@WC%Z+f@yd~H4X_}9#~P(I^xr`KQTYiGXV zd}f!vhSq^Xt7q?Z%&*sEB(|U4p*OpOS>YB(d&ijq7t49pH+yU1&f9G?Gc8`Tw|sfF z%G-kXzZ<7+iaafs@}VNwG2bm^*`8}XxARN>f0i)n*b=^?HmIl0cY*Wa(|m;@Z!07w z?qsY>n4KVQd12ex#J&e>-zNV(cRhNeUHCR(fwxamzP`MwU&7%cl`8gm_wKkN2lrD2 z(-a#l8LW@znCs8k_25h?R6SVlgu;6F&zG@Xd$%yfc z$B!(QysL_{o=;!r-WJ%G+Q0Y5X3f^FGL}uuu96k&ijUM3+^r!R9H` zwNB}suI#y2EyuUxNXE1?-*qQizO*R++)=xHYV-;nO|1+;bky z@~5{|&Z~{9Ir*XO+uyz%>us0*lpk~EG`ISu{Hx$nQBcdg^MNbxU0J1{zkG3%k87{u z<(C&W8CxBD|9R^T3zgyk!x_r5m;KfkJ*&t&-Q@9CF4JIrvD8V;TW=z@M7BnBrU@2xtTFv?Z}&X5MIyd! zOvd*Nl+(pIx8A6}^!xd56}FXE8-3>rX9>8jk~Zr7bn$<`$KE*$f0tJ${=2uScK!1n ztL{A!xsCGMZ~KV-Dp0+>Z*7Y4lmeT$b?hw>*+uy^+vYwj@s>RPVA~omSLK>x)i#pn zSI_)Bx0#Xg>bvB&u-2Ui)^*C4tuuTafL&k z9R+rI8#(>X)qdU|!poKRV#WVIQxCj%d~UBEH6hVp>FkUDZQ8ilg{Ja6_Fzii@A6pk zWz_ti%Y52P_J%PZS=DmT>QQQDNy2weV~rcnrDTsrp3kvtE!n*F-3hyTzlaxSO66>? zZ~awsF5$OE)VtMlc|~u|RWy#-9pmhAtogHmu1$HPYtnum6Y;pBxqIVnuHC)ma4n&7 zgI7=X>KDt~eVmdv8+@|yI=P^1-`S4Zad?I5|k#&RLfYg)hSYPkt4IMeueOIz3W1hJ6g-!D$PaC-&Tzj(B zF8=oH+h5Q46t26uv2SXT#=CR!E8c3XS^WOi#t8TK+OL-dA3MJ2?D{l2E!Ngs>$W^E ziOYC$>F?7|Wo8*6p?YF2dpB%(U4PW*(DKah?+5ptVs205^mNCN+uDLgQ>Q*Wu;PWwyKg_%6d%8@`8P_! zefLI>+e_A*uQ>K~=fdo@7wm4|Imf?dZ3cVFm(;!2jprot%_y|rciG|Ojkza^>=e|u zY~oE9RLGJx75hH@bhYF83XMNmpXJuNEatQIoNewBsg$B&{94qI&A;+CYq^DL)OM>~ zuXoD_R-d}$U_bSW%j?d`&MA&+wOGoUGgSGzF!p@rw`1?_DH>0DzFseXV)E^&jEUDnQ?H)fU3sR)ZjJuSxMOeTf1K+Y zee1K(>(|^{WVs%%eePr=xBJCe-M~2<`%L(EcWic1vzdGQ_FTSGG3O>;tIW+aDDwLx zWSQ3Aafk1WMeBwO`coJ>%^DcCy8hgEtET$v?x3$ccT@QkVw)#^teGascFMTuR@B5f zQ|t3jwa1$uEBE^oZh7b?Kf{DFt|{GHC(eCX zlJNPU?CD+M+Ha#zI!bS4H+tR~-F?p0=>4R9;GKQh3vH6GDljf_FIyTBX64ge+Qw)# z`}z5;kEQM>M$DUfvEt;n*M8I3a@K>^%_JOqAM?8-S7yyx{esz-6VCqn!~Dvoz`QGc zip}Ad3mha5R~hu}5106VlHvB$*nfnbWNQ! zTl8`+AJ4OfGYO}ne$R<}syOfS`A{{PRi}85o;~O zH(V?CJzC1YpyS@V-=bb2cZApTbfwqJ<$CVetM>EirFEGoSa5=I=Kk{y!V_$^ zes-QDdi_i1+|#$p*dunUtEbQH|N3ioF5AjCL8pK2YdI>n;lSUgMY_9vUyA-*d*B@B zVY4f%{W`BO#7;GM9>;g@?fea8d0Hm~%$8qb-d`mW%XEChC!;B4*CW1G8YzS^|Ngdh z>z!`V=I{v*NZ;$^5nuv)25%x-GAhq*sOZKxGTTawd{&3k0-YYJ)N=B zGRf+J-DmFvuhv%u1@9+6Sa@TR?5m#-)+nU!w)~s5BrDZaL&IosWc0ei{FgihvU9^_ zymhm;>|WHI7P+nLRA2O~to-&qp@OAp_A9>cJ=1$WXX4i_GR;qA+N|Wl_!pWU%fHjG z+v8Ywf?)UEt=3xBvXPJDf1fjP+aT0trtrVl?6BI*%ayr1`Wm*`pW3SZw&sttj`bAN z@Ea96x8>hDWt8?_<9qmp`K9~IAMv-PFE(1`Z}}u5_~(kyC;RFD8|02y3zf~ZhEUR604_l@BE;{#a&A0qQ3$3Ys zo~wO!ESVbRs$rueR3;TlQISD&x%C$LqFFuv`+$sOu3w7p%H4QclkYg=ap9+Z z{@)||n1hO<_AJiMwm06r^Q+pT{ai~umRCh(?!HyFC8Wqo=~&_8gR8Ihi+x^mak|*w z!cEO`H@|Y&^oDYrXjnVxXUD7J4d)uS==yxS_FAXm*m+Z}#n11|x-8{(BROv7&z#z) zH|xEQHLprZd${q=p5j|Vul${teQK%uzNG6?mxk*lsr-rOOjCJ6=ky-rBmGT4@_gE&r{ywQJ&1UX|@bk&Mp-hXd z_jt|L3jeTVYSdh_7d+3FR#(gt+GJKE+W({V`EtAFCFg^uX*IoZ&b(g#C8i?HR)@F2 z>ut)ksK~8}H_!3w{|(lBEFfxmPw?e~$f*m@zMb=|Y+u}A@8=tr{a?>|?q`55}Y@d3l>28a8u z+N;b2QbJBKR4lPHezIt@OnvU}{!>)}w~nvdSn|p=qe&~Qcy;9RU|ze_+6CWqR;2w& zO#Tt|?J>K`cd;UiTa7CwJgjWJ{>Jc}RcPI})&H0eGL~BId|Ti^B;E}w^+4V+d69f$2awFH+y|M zY-GG~_T#Tn{I~2@@w(s3i#V+<+kbGCz=jt`e%zeBdgjLo?a_;-%O&ugpMGkU-~GZ< zzio{2&66|VygkRY;{N4Q{nOvqO|i(z5AQhRZ8USvw&!KD(->Hnv2A}fceQN)L7Sh; zdGGL@_+8Lry}mAg<d)Ph)D89&bzz zUw%ul`Td8j-??opEz8Xl5~s}PWA)1Y(OcvxS?rQ>W7gH5H`cy?_m}zItab0_+))s| zA#-+qrS0)`?|E#luer6^>|c%I?yq|u8}9h1kn=61b6a|<^@d&9@9h-#y*u)Lo_+N9 zJsZrXKL2n!{q#x3&PjVC#ohK6FDkXz`FCwX5rlGziszPqz|gY1Nw4X0-7&sjTPYim=(rK#~g zQ`4Ew+Pf?@ohUJXT5Z*L*_+pWJ@{YSJ$dh1CFgQKocE1<_>BFV-|0WrY4_S;e7*ni zm()4QzVp}5FSn_4;97n1`LcRN&8jsM`P$R#&4X+G^8Q?(q>yLSw2!f-0zL27 z{GN5Yf6=E~uBr2-EaR=?Z-4w@?-1Di^YgK3UGH-OPIQG-$cx1nS{Qk?X~}#s-yaiq zP~-fGsy`K}{}cHfj}*J5+AcD(j(S%Ams{%dj%6F!wI~0RdRw96^53{J{$ZGV^0T9# zR_R;I+!9}={Qh!M>W|`E6Yg!F6lpF$b8m;9?SlLv47d^UO&(8_`1K-MU=kHnN+sr``&<8Q*OGki9K() z`e$zmUt-m=F9-wW9A#)NOqWnXsjH+owiE8h%l9XOEKX zzZo$lrto}Uu;!URH?KP%8DE{;_Q$12Of+}DxYFU+y5qa$i+5+&PkUXp`?KMV z)CUGDuGgMz%Ub?e{?vq_OHF&cs7WWS@1bh* z*VmtSyt=OcHdmiLC9nGL?;Ux|&ujkOv%xQ$?H&7d$;JowsyDB_>UX?8^LX54lgBFS7T#_Qth2;P<&h*&Zopy!7@zC~!#6OM51C z`S}!u<55NCcDrRyNJ>_m%(!|z{l}(qF5Klv^ycTP)doT*GUE4df05j_IWA&bi}0E%!FSaO z+ds7`G_b#|;J7KP5$CnEtMIo`#HzVWAzXr%|EJF7>pi^TTz0CC@|I#v=5NA>s^_hm zGULs>|0d-@Va^uLYCDUoCyBqPT5(=y(fM1k)f4L4k8Qi0e71gK3a{mS?_Uf09)DfM z?|5syo)Gjn>3EIlyn9wh>bbAHea9S(uGt^po^!`+PluN7r4vh4q$;?h z4ohYSN7)^Z%+EjG|Ek5|@kA@5n|vn}ZVOs|J$TkbfiU&7{QQsiVl^H>@h{ z|JUibS+TA9{BR>*6#L&N8jiJz^HX2VeRWgnRE*R43w|8(C;u%zSDbE{lX?8G#F^i5 z{Awo?FMe1kad>e`(!VuKVr?}d>dXDOuS;x-@L%OSq z-j*CGFlt-9%s1RUBdy0ed(P_{8p&T9l4ra>rt#9hnD>Zppvk!#c~yMpFL}SU33zh- zP@wI`+vjEWJ~->?p4OM!(EE0YaXhC|$|g2Ng+0uf@ym_n`ra&(zEIlB8?rR;;Dgms zZl$L#gm$pJJ+-OqDYsbL11r8xM}btAGmj^`EMKYW8us1syZec$q2CUBpS!lt;%V@- zf-g)a;zE%VHg(6O&p#UQjra7Kvk@n+Pj8&lKUwE{&FzbQ?hMwdmk#9|URPE&y>{06 zwQbL5_`Ur5Q%WoJ*@u#fY`#37JeyM|R~?kS@Ap3RKvvCWo{YI`3-7O+|MmUMfVp{I z50dgu|N2?RmZo~``F+-qMY5l-A57W#{Mx)S8>WR?FWZjmG4W0fNpa;04|{ySTIR}% z`(4W&1sYqKlPVSNig<3m5Hxdwh{#Khg31&i~zoYvvd^FVB{? z%$@)9qGW%9l~*GBaf^c@6()ig^HyJ)csbp?Db@bj`LfUHhWs~gDz9W-(7O1&hF}rD zj?#S*_4lB2WVxq3?Xb7`#y_p}#ECkGnKy%{{mXw~J8{`cuXG!sOjgC@K94||J}y6Y zlRlp1kFP)f!@lc3_r%RVf3EDC_O&YY>}He4ijwP1iVF|l33zZyY@2?3^785BzcO1utNyLco}>WxNuo!$#^tY>lCAr-x^jJDKHZ7lE*ZVBQ zkM*V2o1B`^WlAr0eqLxS$GAqYW4+7PHH|%qXI@6EU+#9%=0jBV3(ItizbP)_+KGYP zes9yKXLdH+UO(0FdF5WwxS8!5KUZ~JdHEow`ciAmwXf&3ep}Biyzq7T>shuJZhg18 zb*Zo2Sa*Y!g{qer+YZ$@uI%gUjwM*#{XL24n9{}N*}A{a8Kv!r=n1~$mNwx)_F2PC zy)pcLzYckar@n~I-|;kD)azK>;^*i4^tKi;b$ghY_;Ho`>L#l?hkBXl9An&?ef8VA zy|I$l_V8^#Vg8*VGJARcz2oM+|GzcIZPw3=SstpszQX4G$;8X&9?$pH%=+?c&Z+g! zUT=7vfBEW6hwS^G)1A|8dJZaa>#itSk@@7V?W~MhtoH&x{Ve#{X7xVqVv_%g&+N9( zeIq2|&A-d{y2RyG`DLtkx0a2Nzpy)UTFSfnyp?LpLsmCFOq)H+cg@mfN8=}5l@Tju`S?|bzhwQB$m4S|pDbLZpAer}k2a_y4!8;V^X-$=4jm>nCI{BPe}e%l)|=kA+Z z{Ox0(9B6jIubscxSIg}DXVaT+QXEgO-L&O2Pl)5EJocw`UQeu(V-1sCZnZtPeO)WL z$(gez;w0$&^1K`8L-sto_F3k^rt0;{Wy@}dT{N^V(w_Qcq0-!s3Y)q)zOYR@xVC-W zlN<*R%-$&3y)8I#LsH?2Mv_{@ml@XQ^fec0@tu(9zFs>)u-SD_ zS^E_ANoNl8r0?CZSLy9-=^Wp(rSpY$KIl=ObX}HDD`sxXT*mFwrvE!};jDh((><%b ztmQa%>$pGmo)&oQ=&CJVx31+DEXoUWai6g=@QPMyxQI^5<)ZZ!&XM}Pb*pB4&Di@T zf77=v_3d-k>KAl7&vM-Vn6be5$zL@;>9xP^L}_y6`hMg-bMf)aj;I@NPHf(CZ@<)( za=tjrn9bMkMW^k1Q*dTY)yY?XXPw$LPg)^Uy5s!0m483glpRZ6IF~Q_pWPmvxXL_R zZ~lF9rCl2PH+AS_&zbu3-fiB(-Zl61p0Bovu-I@jlHdPsnen_`cZ0T97F2!fyK?&A zlZUHIjwLUe%V(X}za+AE|J1K?>v=l1xNJ(g8Gf{`TyXb`e>NYdvA?obdVTs`*zcrw ziyJ4hDQ(CJ{hIOpoMYb!pZ#1a{PA0L>Z-SoXcl5TBlB<11rMEb`%fw5{^fyUDxd*EDIyGgY%Y z{aSZ!?Up$=nD&zti^h zVdGy0$CPee%U0=}og3oM)_Je}$Gs*{A0Z zZ@8TIZsGE{@#o_Z&u*UMwdEnB62@Z`cmvFcSf$w=BU7y z4C|n0aT6L>`LVMt*WJtx=L zV^eQ)eLi1maLiVy`QH`$>lW6jJ=f3sJzwgwJR$Ji?YaFwC3k%0x%*kwZ|2|I&z}Xq zuc(QfVA!}c=iBr-7HcW z)_VM3# zJhQ-wHzxJ9YJZvPu9)DerJ0MF<~*PAyv+Q3e7S>P`fc5FC#Eh9TkiRH)8>zlL)uT} z`d8JP&1*NCruEIPX0^+!l}{toXKry=oU;1Vmgjr!1{``=S`b!lv-I)jxZpm$v)8=m zrDm)S+{5<0t#HLu;}yLev01z!Rj!i%ZO$)eIDY+&?VB}wJB|9-T{qTVy?pe5nf$be z6SipY+|P8)Pq>UD;@d%4XICTH39-Ll$E~!QE|Lk`_K z7^VE_b@{Z~n$+AdjbouMZ8`5=yRCWZzUr~*;|poLS`3yMlPoPQ730f4)kUz(wwWtv ze!Thjfhj_r`j2ZRDkRSYx>(EHEIniXaO&R$C*Jt!tvO!IEO$Pm@Wk30$M?mhR!g6F zC70}dQcz)$GR2NP;{L3^?UL_4mzyWdRE(WF;UKqT2=|KfzIV05KBc{?2w*=i`Q^Ip z^}EZy6j;SMTANRpbbiv&@N35}J(zyx)pr~+ z{GiHaQvNT#$iiUFH$l-eoEz_*UZ1ek*eyEX_h-|y|C!F7URg5X5?k9z`{mY`9;(+d zziwS_EG-|nXTsYR4<=Neea!v)xYh2Jx#z2Frd6ES^tHJ1MQQ)Xup8D<%J*-1R@{8K zVny@bl%H3sD~#mg-b>ZYJYgBDY-pZ$LSuRJ?RB9oYrUpi zn-#n*abH@i((*fBSI_#pV#db>=k_m?KmGAs@+qg}2mb}HYkFG0$ZP(# zViCXAd54DS!2)mZcy!)5AGT|n694Y(Uw8hs>pZ@bZNL84E3@ax;g6EP$|S$DEq!(U zfEVY+^VhbjSj)}5`$6%O!-Z>4Lk|TvhJ^U7f4^}qvr)a@O!n@tr^_7Hq+Yn>d3@2D zX&1x$J-#X&viQvRE@1vbS-yDnxUS_q_ny`KIZ$%q&s^8v6Be_@UcX>D_pZS4a+_x& z5y|XN9X^y<#Vy<{`@Ue6`ctV3VVS@0TI@SB>tn{BIehE(yg!y$yYG(6wR_;7aPPu#eC^NJPD`^)+Q8&a-p_IdlHVT-cT@HFf30 z)aZ#WRz6|5=PS+_r?i}{X4u_+Sm*qVHTUc0WqfN)v#*rA7;xKs{lzuedrPn15#MH~ zf5SiW596uZ|E7M-cz=%VlucE-Y+RYbUL)t?-=ZsarM+%+=;c|In^Mz~0 z&C?z7E-_v`E;aYzjN9{%8~nf0^LWa{`*%0LYU&EP^72~oQ{C!|YtBE?jJ~qz;i0eSo|RPOf79Ez=%AtBipS5-)s`;b@af}ZrE;b0@l3fL=Zhybmg%ai|ECR@5Mf1w$=@jcJ~6Q;J7 z3a?8qMp!b3FSzYPILvu4tRw552$k;gtBbFDp*fUQ6&3NVWNFoN{eRc8a4_ z9=GHZ3)!nBeIe()pY^<+leuFr%L_B+&)Tz{Z5~J zxnY|AY7K4k>;pT`cjqiVx~RU(CgQ{y?&8#&+oxY<+?x3JO?Ju-C%2&6<@0x!9@un8 zZquC?FMHezH@rA<`oGiBGrcqUI0Yr!M9=K_DAoRi^}6E!8+-4pVSH}KzhS!Y>ctbg zrAtGfo&GOyCx^G>zuqO@yYF|pFQ}cnSAFN3XPc!~->Wp$-f(%n`P%EROO82vq-0rb zTJLoyZ$pUbl?@sbmN$2QEkAXm_x-i`0l(Fcvz@L>v0xM{a#GdW{iJYxs`Qm_o9{io z@mBC%?c=x?>Sb^9`Xd~!>QB9Iz4Ncmzg2%9X!=jw^+)v9M~xnnU!~eJ1?%~lZ$B#7 zoYY&w8@5>G)q(G;elB;Z)3#KY@=y2P>kU^Vr&Mm5}~b; zk3w%NG&Y2ZO*r^*>5C%|p5?f2{kq6PB+jqh6&T6h52I+IZ&e{RP2m zj#;N9|C4?7I;}lne};TVKqt-aGYhtK{2z6&5m& z>rSOF=G6?iIhA$duMaQW360s>))bc_ocG@Y;vc>v)-@vJFfjVG}7Kr z$|W*b2QiUxYKne=ecXewz^yT8MAkP%s#bl&(~wOzQ3H6 zu}J2c$G%rJ6}IJD42y0!dlFSFayH7$F|+h10x{C+9v z_8NbKjwgz?PQH_UReq~%M&GJ6*ZJ2f*X_Dr#6Ne#jOfmql$XajHl07P-b&tnO^Iu| z)w!B?_5yQG+bwZ2yEUW!U&BAYyEo#6ukkEbHd<|Ry6O1WI~yG$zD?gaZ;IvRbK1+a z7wpaL40BH`IKEbQ=H)x@H_C5Px+?ZJOvAV7$)zIwgxu5@?yFz#Jahil+VpGx7X4bo zq;~%G_s`{FX7Z^%>(?FrEZP6?=(&4qTGOq!Z>`%_#~=GUb<^BF4x{U{E^U7*RpF+v zme=fM#Adz*FLwWuV~1zmzIMSX;E`m*hJtsNxuMtBZ~wa7bXxq=l;eqJ^S7Pf8qYm@ ztI&B%xlnN~D;Kw0f3z>McJ!pLx42(?psw*2|24{r=`1Ey|C2$DVJ?y7lSQ&@BtjAB_l$KBE-z^q_X%iQuJS z*-|`C(ZO9;Ym?_k_dPD#WOm9|T4b{7xxZr9JvJC^TJw9G4u9nBOY5dDd;fFuv-_&b z7mJgxnqRN9oLhOtZt3rX&hrC~2`|)MEwD2EnO%L2@9}_dx4D)c@yf1tdVFF6H}|@7 z8^4JQJD3}O|Ga*~RcZ0hOS4?ktyR89zm@G`+GaG#VD99H4KDWEQ(|=%e3_l9;dnkH zRiI$r?8|Cp{jG-jd*>@HkL&YuHJT^-YO}1s&8=dNtL7RTZ|{zcpZeNst;Wh_rn%Ry zC~f}o@O8-9vWgTX#Z}i&1wZ^En)xUC4)es1duHuhG^g*Y)yd84*(QCd%Z@7luP^Fl zJv+v4o9xkv?n&jf zJw7wExy~ti_WHBiGIl6htdiw*?dOLtC%iIVSayH? z1Ksl>(mN)74!rfTfoINF|KRC9j_+Tb`5(0M$f+uwIp6ktar^pWLD^iB^NVwr&zjeN zVoA|clVX3~T~D;y?84tGUz&OE=84d2>z6!kT)JU)b%({Al_Aq)yc`m>0 zOx5Cxf1Rfk+i2}sIsfK&?i6d;o3p*N?BnT}z04xK*-J#`DK{3OCQj91iMpFI$#e%ej0mpWRd=*~R}$W3>}a z?XOr>t^TgK#gF~V%q3^Ds!KvY1QtEdJQICpV`;VV#NwErH5cB^zx;2?7R_AdEcV~$ zoZG{aPQ7JTd&rSA&li-tLU} zANuav){_@BMN6Zd**C9VeBI#c#~H0ixU%Gw^wf0$8u_xZ$)7q%rnol$gq=66@=JH0Jy*8H$) z3q9`Mr+W6|3K7RuBC)%9b)+Ivy3R&&ClDfi8FBB zn4*3B?vGVkUhA9BoKBqJFmZOqA|8(S>ATN%e9yUEZSQ{8vsGx;)H7?2cRl@+a{f1$ z*ooV*^I4znX@AqcZDYcwZ?p4B6{G4bK-!Xu8L> z?JZlo@b~^1ZzU?&!~Nc#FRtHp&HAz9+uNrVmVGLXY(2-En>qQ5>W{lo74O$p$}G0; zw|oBl$gOp2oc$mFlGa%JUn}&Q;o+Zrrz_UTg|xn~P~Y^yN}a!a?(B|T=~@?VXv*#0 zUO2UJy3yxV*ZeIF{m%*rId54L(W&7%h#CN$v0_j+m^3$f-U#@8`?eJmisa1=1u+gcAC|d>fOtY z4ZEb@cKSTCj5KzNjCk`?_V7o8das-XSLgKUAC6Vlm=t(1adm-%tHjj_h4WK4Bz&(r z)#183^4Ef0a<^O!w6{DzdDiIR&g%-vE?raSUF!3EJ*V=aXuv0yNrJ0%KQ3;%9MYL} z?l}Ky(_fZyivHnOAFin5sM=6$q49a*%Yp*$LmJmBTrR3+Jlm2qvnBmyx2u}^Wc^oj zqgQM)6PwxSwX|0Bw5e{%R`(6=MSW}ErcV2v^`>LJl|r(f%^P7}xnCESUg5g!GV|E0 zKgB&ySNpNEr0OlG>~VRl6M1)gwmz4SVY>9QnOo1BZ&-F^?flM5_k6AT7f)U@t7dfKfWX7y*DAU=xOZqeXs2w*PV8V zF`J<)^wuS8;Ur}g>uYyCa&=Of)j!5lUpy9TMTXcpY?>q6)A8L~<$L(74^wr-jSQEUP4T`!g*mU%Miyy7H!c{K8qE6HVo&J~o`v z`kZakBX7U<>$_6+FLqW;?h!k-A+-J)8zXC1V7#ul3!otMV#u-vsvEuG{A|udsZ& zZs}3R6QMctygrzSb!#kSds*YXVZu(YT?c+uuE=(Ld;OHeG>ghBuh+<)nEv$e?|nM8 zPCKvPj(9pxJmBZ%()p1Gdp)8bYxA9$(Y*82!X{?5*zCe%%*GtXBHtytOHZEQUBe_{ z$}Y(yzjxZTHkt2sIlAT9zDEyRZa-HR5xCT)K<@AlVZoPny-T@np11!N*2?_XU3KTu z6x$^kJSlJPZQO2>8ZM*KSHv>&+YHs+Ti0w!x4k)cz2y1+n}4Ph{(1iY&(HsVjvhFi z@oUC4@JTLU$CLGpz zRdZ|3^sXZdPH2Qa>I+_6zV`iUDWBD+a;_)5m)`TPeqry|y)%mA68jU_m#0=o>D*ppwlDU9ny`-V;G zAKx6rqs)D`&T9A8g1MLVZ*tvBFAsh8{9KuX-vsZqi^Q|VegCc6{P8h2U%Ts(^QV4( z2zs@8(uFIk-XEtdev`v~ytBJ$($>4R^-aHeZh7RpT$x?9f7_K0Q(mq}SQ4+Et=Q`i`#14br{9@#?be}$J*tQD4E%Z4v^uGs!g#8#vZ~t<;Q2(^&Md=WmGD_T6UIpMEk+1&2Ov5PI4*ZTcJL2VzFYXK4!GOMl;U zb)W4^T|K#~zQx{azw8vBR(3=DX6oL!dBSgYmT%j!Our-k_y2l}Et|Hvvj>(kFfcH9 My85}Sb4q9e03ZC`M*si- From 8f3cabcf76c75c6e49aa1a6da67f91358574ad4c Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 25 Nov 2025 19:13:08 +0100 Subject: [PATCH 188/189] Update rcore.c --- src/rcore.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rcore.c b/src/rcore.c index 61916284c..88448bdfe 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2315,8 +2315,7 @@ const char *GetApplicationDirectory(void) #elif defined(__FreeBSD__) - size_t size = sizeof(appD - ir); + size_t size = sizeof(appDir); int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; if (sysctl(mib, 4, appDir, &size, NULL, 0) == 0) From 1ac1309b247b80d3ca8dd447977a72f5b4722f8f Mon Sep 17 00:00:00 2001 From: Rosie Date: Thu, 27 Nov 2025 14:19:22 +0000 Subject: [PATCH 189/189] feat: add elle bindings (#5370) --- BINDINGS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BINDINGS.md b/BINDINGS.md index f2ffaea9e..07f590d7d 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 | [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 | | [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 | | [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT | | [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |

    ;?6l!&AfZ_jFzNa$_*Wpn@eAQzE-sQO`}+K0^js2QnySu8HfH|D#1VV z%4Jvo&in5?&MbfZ@pqg3k)MY{ueZrF`SaeKC?1heeIh}=?|y^7!M(kDZ$DNYVEkps z{b;?^n^KQx-iHF<<@&*v~a>AD%Wd8cLgwg9C~I)%y};S;tjaM|&qgl|Sre}X_q zjr|h8G$z}{DG{$ETTZ{uKY55lYcq3~%x0-udlz~iR@lQhnepP-S;-cDK-x z1$QUM##Gij&0KBaBRyft#T_lxZyb)ceAvyi?jq}|)8@`k-e3FawPOOW#tOyjCKHyl z7+$??b>Z{zOuN|srwipT^!<1mSAU}^G(WlSel)w(k|;l&^9(!Qe4bdQ%y~xDVynt_ zk0_yajn;AouSK+e@YXd)KPc)u{kCrB7XSR|E1maC=1zC#VA;yEyCbRGQ02+9)K}9^ zC9QMMa6RvEMxb(w);_!M=U;T)J7kz^htm-V8s@|IVEt2&O~+^7G4TB^Bo)QimzGKIHtyp8d^#BqI6 zou-nPu@diwyI+5+``<4UzxUxTH^+nIz4Iz6>vp%<-~aJ&t*w9Ez1P#XpVQtacY?Wi zv;K*-?@ks9ZDesiD(P@~gW4k1o_mjrruv=dlAg}}JCFCB^`VVy3(iN^zWKWQN~*lS z_`k*<=Ck+Jv$1V+d3}OGIEUMf_sZ|b)j!pa@BXt|&cc6>4an6NfxZG%D-`vToX37SeQ$BH&ZoP8PACRJdTcTlOy#AE6UBcp3yh4m)* zMtDA4-Xm-$SR2BBewyif$&H74FYY?$7{cvusI<)Ym0HUg%jzR0&$RwrN;}B6bJ8p) zn;j9hH(w;Cd$XRtDz^O2#O^)2<$2(FZtAclZp4IBQEED?pvLe_OGL-=ggWl zr`FZ+RkazX@N<}*RGl7Ea8~rc=OpfRJC!^d4m9xcEze%IYuDygo3-LUmY4_c{cf!k zGiUWgQEvAGckaa8ee>%31m#b{?j{QREuTzGc3ryrrzfBPlSE#tbe*LBIqx2nn-{kQ zN(mklIJ&T>S?fhqjh+qjeS>WqZPo2hizdIBzt7sP)+}ISXo9-vItfv$G}%?MUp+Z~ z$-3X#5`5yoi%%6_dSB%n*EaHGj1>|UjN016saM3-ZpqoypJT$)v*77nuLGyfWL-Wf zKizK9d!?osU!2}tNx!oGS;h3uAhuaIcNXTfS&64CZ(MbBkD6H#gS~#ut$F|c-I%Xz zW4xyDa`em1*QU=r{O)juV&ZfgN4;L2&7ODpPCdJ4$!7FWbC2nM(~1=f5)_!v8|zow z?!6a(C|@pr{#cr!5~yVPHK9HN5$}6_)ofOQ? zVf=gTR;H9TuZ}fs3Ez&|xF2g0%9OCuUNI@)!Gtu&30%e9QMIoldP?|qoN-`TCB$fT zNBMw`rPERCQAPdP;yKKzrEfAjW$zuEsUKYu(sW)z97GMn7cgw9oZx{C+yCI%&Gwvs)9- ze%bGGcVe*NgRbe~k4~--Fm!vuTJHeICKeA_uSrgMqa|anw)f7ziM(H)eqk*<@clFYBfgvuO|Rz&+<5-Cf!{pPoaa(T zaC!ai`dzQ@|NFB3@7>q`*SGbZmWsdnPcxxdLCILUBy9chOV>aDtn58q|KoAZ&!5Y) zWlwXL?tlArTi?;`rFZz>=YQY6d+WQcB|3Lot1o=hdb{<~>Ez2rJUSIFQgUvEE(!|I zB7Bc8;dN_yGVz2e%jzk7>TQS9Ht*fF^NGi{8%=@*EIEq~$k;qlaI;YMy72bjoX39Z zu7z*EcPcJ=vat0;~qfhroOCTPu;I){E>}oX1_ig;iN0Jh^?$&`nCPqS&zgel`}FF&b}%x z+@B%6WYK@W$h%pRJ_}bdxfm?vo#)gy!(pY*B(0Q74MH5rQ;lVX3}if^V+wf5DUCN=%1Idn#%o>d)Wj-xi0%ND{el*+PNi+E{|M7~hDSBS@vzIzpsP#5w z?hrXsb}L!d!}P6Ni}S)H*M%3aP2Q7t{7zj(-LCzgI<+_P7(5YO5iRgY>-yi^oa^b= zr8gLHo%}oP7IQ4&ouKo^p3F5**09bCH9Z)^u)%AI=s~sVt9Q@s zz1yZMuaMf;akS-Z(tB0elFW3W>B^rLRFrI-=bX6i*}g*7H?~D>u}KzZ@}^&wc)97} zyVW}7rP>QGb-vYGR2`<8npP5Oa?&CHmEf`E^2bk$obJ-Za1ga-%j$~I}Y+s*j zm&b6|;@S&OrsKCBSJ?rZNmk)s=mj(EltG91UmblGY&-Oq6 z!|aN=>wml||LuKuV(IC(shJM~@}dhi@9TR!`{8LR`Th6e_wD@qk=g!b#IE=GTlwyM z`&+i=_QS8+rj-a^+t{#2GIRn9Y)2wE8 zBep}6T3LHSSY|7{a8X#CbU$*axnW;PGM?*C^8yUSX1JIyJZ@%a^VET#zg_2RjXU{I z{qOf|-{sO5wf>ywou@{87mVM><#(=_lze)}vZoIM54sqP_WYUT3H zcRq^xeK^#yfH&t$v~*8Bn~@dwu)1a^8z6|p|L`+NEFlecpvvm5@I{mA@u_pUeJI_8komsmQ#D8(wY z9^LA<>yF2aJIgKws3odLYTN8jYYKmDTWt6!d2Ye=yK|;=v1|-uJ)Fio=D zEYo}KdxFohIrW(Qe);Xp_VsOt93L>5nf&Lvf1uH)qoV3y;ql$&tMdO`o&2xh1^)^E zz~g(9JiD|vfivOKCjCB z;KKNtFXGZW7+w6%@NQL5VC!)2;lAMf*ZsJr9)ETJ1IBGXW_{q@!z5hAx?OnBL*}@I zIhQ7UuYbaO_us`83(T9p&al+?dCdKI|E@oG@4uX#Z(m!um|I-eHOE`K?|jefV|NVa zT+coAKCbS2WzXr`zrI8T=5ODm}++XMrYz_7jtj( zqnF#XjFj4*8u+|@(cJfB!CkFv#+MD(do1{JWzF68|K7bkBldt&%T`wgjn`gs%GXa> zY2A3F)0VCGzE~$JYW9wp#(CO`yKh~H5Dc8BS0bzWz-RXkr*-cxYdw8%Dq!K)&zm@U zSl4P*$CX{2_=aiL%hM8;{O?kle%JQRWd42IYDseTjB=RGl!@%hHlZx(grz1n%RliOePbTGHnDvE8GyS3&q z`#Q-VlAnu&GOQUi*_k~9SELB#1QblTU0Hm9q2Pgda6OO2&pC~EitZW*t}eU&S%P)d z+g`RvMz-REoQK!E*cE!S#zocO);lhPP10I@hxWw$d-L3%`Nyx{=dXAAC)V~o?%y02 z7MZC2tMg@C!L}u5_eD4eip)@CocX|Gf9&&1j77F=O`YPO zz5k$J&gBlD+e-WjZO&5{<0v;}UVCEmY|UK# zDW*&*QzF==*dBcG^jzS>5|zd`XT`Qo?=%0j_jn5<-;o11FIKZQYPcLYwnKsc&*#}kDtys?Du=oj-Qco zv-h2IL-@&fDD+m-z1wkdL$6SR20oO8xiOKOesR9e?N3 z-M-b|T<_+WE3V%ud533abneHyRXg7q|KZ%eHG6I7?<(6YS=GYKw_UO}9Midq`j~U% z6dQbW*j_NHNwY7zk$==xI=OB4X6{=~%eoU?E8I;u^LbhJq~1&RUD7OlnQvp4&yj?1 z>C%a%Qmgnp&i#z!Wftx2VC?#PTXBuV$>gi8Hv~5&|17y$*(#`1gO_{ zcjZ}fzl@S5 z=PNUdzBAE(bY<_a`_i6DE-8m(Rg2TK4{5STX&Lyh-OT<@Fv8??Ys4yd!Nf}bCKl}D$(tmyrDmZVaat*i5I$G?g+RloZT6Rh2y`5{_}NJ zar4V~e+&2TzptNZ6I&zx{ZwK#58H&t5p!bRtJ&uq-`y+t{e8TlVEwnm`|p2vet6Ej z|Hg+uE#LJk{yzG@j>8GE%riMJ%>Lw;GqalWgWC0Nl6I#WXElg;T0Rz-^mLW>4z}!_ zAE!sz{@$$JX{9B&xP*sWv^6W7Sy;AI{}_vMar^dpt=}B^H+JaElwy0~JS+KK@{!xm zbr&!2n#SPn{kk=VSIPf!*D0on28IVOb*Y@ZrQMX-`u1BQgOZus!qsj{#>X#RKEVCh z`@H(y{jJ+y-w`VO@$c8+_vY6wU-p0Y&-p>{6q(RhI~uv39!T$QOK{rB{TlKBfQTyu;;`(l}rMVp{yux@V+x9p| z$wi%AJ=;aEF^Tic|F!z;;YT+;&RkrHMd{?*yZ>; zw{*g||NdGnqoXcvbID@vU)?T?NqaJ;=4B_$K4iOmrEAT)#}0QbI<1|%EzY|q2bATl zQa(H_uq}?mw(8(p710Zaq9lA&gVGIMGc2a%&MsWxwxmPiOzQ2Y$HcsrU1zx*Gq-%J z;Dp9A8zQ9`S*zM!2hC`4UvjM|p)6WaQQEh~Z1GJEAN5OI8y9R?5E6E6gY%0PA=yQj z3y+=9QMu-HL1=T(bJdN{%_b-ZMcuFY^wOm_SUuBANjk?YQa1F1^SIrBa{@%&&Awh}mhfN7rpTRA4SM}aJD83AG&9^ZM9SFriWx8hf? zuNQkWJY@c#F`b#o;@tX`+lAGaAKNZ?U#YJ6|BtV~jAx!W{Q9Oy_VYWhBA%VCVtkss zHnx~Me&3GTUrKS?PreW5+&Mj@PB*l)R^WihngXUTNqh@eyqKlNbZQNUun*I-K*Qu^ z{o1SM^eDJJ*s#r0^p?sVLDNagT-cS`z0Dtc3EWUmmX$C(VW5^gH(V)Q>ZxIpZu`-h zoA)g0zPrIPG^95ZlZS^@<_~!e@ zX-cv&Y<)~JGkNPcyc{l^?qg{Y)G&17ez8KD^;`?T*a>$@$NO>}A2xPAV=|ujWZJ%c zK74DX?7Dt@d0Do5^(paVqNSqOE-HREjs4=*&Sa!jFyZ}-E19)B&u?UHS>?1~wTqun zD4S#6r^K0z^1g-HwYKs`xL^a@ulsLWWjYVbm7HvUb@SmN$!}Zibg!g@eVMto zF+P;9Y3&O4W*J}aoYX6^cg%cCKZpF-^=0#y?>!PRN7(W^PQCiOZ@2d@LGdTAYMA}+ z)ql&BxFf+mDSAWm%YzX`j;mv`-?ob1IDdWrZ?Wk%0uD$2ZGZZDj{VBXvC3RFVk?fY z-o7&FILj3!m&uEn<{jUbc;g;(_JT?I6W2$sdLOoL^$C$s?!y+(uN{bzyZ9sLjrQ@+ z(tde1*^cfCGgI$d80}auWqkeb6RqMm7Hvr`kp_pasxMl1FQ;AO6z9QJcE=($`dCh= zefZ$#^K(yx!d*rVefRU{5)@7;2QE34zS)1`+C5F(6FZ}rgI6q6^FH2x_+p;$yWg>{ z&lY*kmQ?+1xN@1qO$(2;r|kbt=-WJXQTX9~u4YDzOq_Smo89%vk@h*Gt#?RiUYTKB~6d~+rPNg%{%u0_F{$w56lzF-bme8@ctmn_TyoO z5C8J86jX;C;aTCW)Y<$a=gyx`x4*8wzvthRuXoR1Gt7#KxOJ?or@ZU^wYvV@AHT?% zUi-MyrYPt8TkU;Iv!=e=rF*3I`&x_Kz^HE$eEBo{xF;{QWctFyD|1s-d-bLv*9^)ln=YK=SY*M(Z8B+$)8xW{>~pZqhCDL;Sv-v*m&vyQMB&5dD^iF0qsQsO&l=`?Sh#7>?C4pCE* z54b%NF}$T7tZ-POU}1)u;_BE30-{Z}4D3}7?z=ZjrP?=MS9mFONiQkfx0h3eEB37C zcef-ZpJd%6$8JHp+-dEm(MybkC!C3T-@kBY!xz)feKvdzA}R55Y88ur3s^5q_@E=L zQ*q(-n_V``&%Uu{6nLWc;Omb2{ijN6%kOgEzqUi`^!?AqPjind=}x(vU3s_oOv$<` zlZoYDPG+Xb$Q;ZSwRp#ze_A}#aO$y+x$^y`5;h4vef}rdgO=vy_eaV^y6dP#EapRecUInz+qquqBzb>W9# z$J5mf8dbGgdCa>%HvgRT=V|Fmi4WiE&O661(`PpPX!7xk+~=ZuW^zwA>^l$0a3HJlGtID`mfaY${NR{Z8lPmWwlgWSR> zW{x9{YY*-WXweljbZ5^zUpQgvK^{4$mdSx?#@V4MzhBQRTX|y3*4^u7=I(kqD{Q?{ zgd;;{g3s=r%u*)F6Q}Z)&-M}3o;W2iWSg&QfYT1OWS)JY_ZH05xh%=%ELvvrb(Qo7 zj(uqCk)m_11RmZq zD<)$8zQl{75ndvf6kXjmyi6>;%dc4(I4O|b?}6R)y|eiRna5%V{wH^(99U0F z^(C!Mmi?U@dwg!u+KQY1cG$hLtNfjK`?~6!&(De!CfV2>opom(bIhAp=N)ERZV)-O z{O)-UHJ#KCZe_EZl+PWno*Br(XY75>!a{aS^V*|p)@yL0M;k^(Nk@$rq#4Jhiqz z4C;_uRI}*s`ANy460S=&Em1idVHD_ey-GvPq%+e zpa1;4{rl^uw{3|nm>KuIaj)By`A)liuFrmNr*>??G1GhhCzt*%Uv>9J_T0M-l54+r zyS5lzsC2z*Ce#so>x>AWU(4eonH`MoZu8&EDjkt>_*wEunkO%6X~l=M!_0wyk1C!I zU{nt6OE7TVw)IHjG^0hzJDV*+lpAOLF514eTfo*RU>0NN-aWBz&srHdOgAt(yeT;_ zxh33CQd{Yo;AP9zeF`lW4pNe=8(-<1Tr4xu;m+1=cG5hjEFL7f@OXu~u}z8*O-Nht zM$O#nisH352DS$$oOpNDBRMzz*}t@@HZsk|CH8$=@Atib_0_EGpxhxf-|oYkuT5N1 z?B&1v{G&X+smIgw^=B$4v~nc7FluymFzQe0*l=r-bxiIT2_E4k#|^#}Y0tQ;d+BV_ zg9HnKuO7cIZYV2m*6+z+_7F~x-f}y|Xu})9JG`%bPF;Sre|i$nw-p8)r;1MsOjbBv z%JAr7>thac?|GN)7KOPkw6}z3P9rNYS zpW~-C#_Qj&`JXrAW#vx6(=y*#?;QWVo-d8zY|DbPOFz`u{Ym{^c5sGIcSp5rMDRzg z=wO}8G1{rcJ2p&u;}IqB`&6i4{%pNde#$N7eUCZr8ZB*PxD>iTR&z)H9gf_4{0n+b zoLaQj2&U|e5IgE-$CJbwb?khqd&8R4V^-52G&u4c6?9$X#>3Gxpu3Bw8!vOa z=7I3N2eL95?I(5~k`oXJPdI+(L1Eu26Ndz;eTz9_&i4lk6iBY^Uc^j*@vdH%q{hrpebs0tHjb> zPb&G^uEQRVZa&i|PAupApc-&=iL~0DB^?smIOVz=Ulp(K1x|$J%0zlCMnrx(LR1o$hCO62D#KZQLTh_i;p*rP-dn zaxa;cm6mf)JAC}#&))6fq8YcIz2k`qbzSFN{i1TM_;CicYxq6%Zx2}y5U9!7`8aJP7?hGhdJ?o0cOrsfRwoG1IxOlUpNvdzc z`%VeoIWwCJLZ2V4{I)(NZKXMLbK;L6vz^Sw9gPt@Y!NrbXYBj7Fq?hn9qqv51vy)L z*9cA)^LszxVNSQspTD{L+yB0M`t#qnQ!>$gzg}eDd$;d@-tQliCpssEY`pf_s;xj@ zRJ!M3NAK^CF~{4hsbJ?|1 zDt)%MzKZ8g=|A#xr*f9Y?44b!T7s@{g|)a^_g+k8R{Xr>SIC^F{THvuS>M_m^1n)@_gK-os*aeDdeT+)>(n_iuks{`Y6beHe7{2J4pcBo_7677lFEj=x4&C2Z@ z$9ZCwEPQ7_t6Hf?nJM>{`L-n|U1tSLo^IcwY^LMtGK;y@XF`N&tYd;Si$WZePD}F% zqwLeWznUx)@SV$WASznELe1Ry$-J2#UVLn8(Xnvfe&vGXX4$q0?h1n56HeQy877#C z@wCKDvbv)^{k!{6enPdt zmNkmG+|!pn|MYp)>DZ9HtCa3s`JoZKRBP?JdaLevMu*GhEp(naLr~hdM`ig=R%6qX zPdpwA^~g)Ae{*q=D7n-u;c@NcwrH`ly%Qg1-P$0T?$&ejaNJFSmm63w#jOas{o+8> z8(qF>yLb9H_gvbdR?JhCVlF5hVlshac_wec?P(#4uV$>?-1@L=hgAmyJM%Y|xYb!# zk4Giv+^^feZ{O8<;xYHG?pRl`@A~D&^rKI=+26lb-Mjp6Mg51&wV6vLy00JFx+7C| zY4Q=i8}7pUtPS5Cd&%r=anAjAfaM%5t&Ve3GuG@1*(2k=rfD*R<(+4TlPf)#PqUd= zKfkn8@8D&n+Mob@+g0)x zizXeH5Y*^TzWUm(u(GTCf7AW?HIMt_dPLqF^3iE~dh_beW16oEcOMonXcjF#uC)9i zTkF@=s>c++@|R7XaodqW`{D$jU6Uf@c+=1PUbFA(+CyT=nXHLP)4orb<`OrFJ5I<_ z>GOtUgRD+VkBX(jEwd~3FY#$n-!tjpi=-DVrk^%+9%xvz;?0bj{8LAlm@1}=%{j{K z;g+uXdk@DfKL^(t6CJ0sn^&pU9$E2;gKev5?9$E)r(Ptf^l1rAN^=$$F-c1~I63r6 zCUQ->x<fOIWQXF)7xSPpf&O@0wLnf`SDSp9|;2Y+L#9 z@tJe!($3+N=07yOR3dpe=E~lhJ=dNJ*L^gp|Guq$drPKb;m%Y49^Mu=)|ZdZ|Jw6> z^^xkm0(>>!)@@leFWdHM_X(3+na~tIYrf0pCeHU>?%}n$$;^EhQ&^(HZ>3{TI8uae zulgQc_guE{;9Iu4PD>Tqb(Y08&R#v?>{jIid51X!Gis-l*zervl{q)V#VM_6Z_~H! zOpM_sp31w|b<~EpW=xUZvs59h^rIlhvW+T2kzH%9uFPYv|HE-g8h@t_F}I$^>)6jn->vf+THkYjZ}s~3@9od)|GM-4cCWAh zv1^;|y7(zcN0b;@OI>>mOfGG|-&?r0=KRN^>mLk19Z3Brxjp{jKVOFjKey#{x$bZ? zGk(2b8^`rig4@JJT)xav?vdEQZ~bOwrBGY)-RGrUL9r*LA|0;tmu~u^^zMUz_>>@p zjUvS&#xJJ&9SoRJDJG(rd}p_agw3%9SsQQoAW61i%3o_&Zfr-SQM!_zTqlJBmbf4y+!l{=z`FUwgOHaowTtSEFS z`kpNy9ou1X{)o+!2?Fyb#!0x$Tt1)0C^=<|Z6i~bz*NCy8gWYB_GznLYKVwV5^k*#P z&6iEITs&>Tx-uS>sz0x91ZWrU=Ga_g`R;ax|EhF}CRI+@WOQ>$iM9ma6dBgD zHs`IAT;>VREI8-zHE>#9nXxSEVZ{=`RE1yHlq@9KlMEJUDR3{|*xu8$V8g^WPG7~! zrOsVnXU}Y-dQtco=aB<}T#TMOn+s0zth&I?*|^5Zg)537aO;`(cC5RkYn$Kmuc~V< z=ljw3qAph9_~EF_4_C6BZ#&%{Q*8NPy|%BoRAGH=dVQV*N6UgLh2LLSWXtpC`_JpT zp!tty#qxchMf%RQOg~rp=M7W#bN~51ujH>D%DpUvG51wzHo-R15~)8IPz(0SG;My?rrQk~y&%s(q`R4FOf>z;MR%6iI*w~LC+ z76^N?`+RuOWLurW^^hriruIWoO$}w0V5#Qa3qzYLP5WF5x4cX~IOV>D^Kn*z^Un+0Zauxd{zFuS|AD339G-b$BC zr}7R2sd=W&<6E`ND78i1W=3jG$4t8=4h`p~XqBuo?|Y#pxS5;j;oCO{)PA>JymI=o zh)a~{+}7k1u6O&-tkdD>>1c56ICEjQ%zc^Fdm1Jx7%6j=Mola%>UC}FJe>EXrbD?P zyab7Xr$lpypve$DbZ=YW;VZY~Nb@~&T=?gPIzbq?=v1&eb*ns(QkjL_G zP8I%J-ukvF1+%)byi-n<)tF$)aZ{D0N@e{%|EmXgsBvssc+s&h%3pEW^_YX|uP^;& z36pYF^iNpCxyUOdAUJ2D>XV$~`Sr?c5AaR8Xuv;pdd!`0k5271L+3SqR+TdCK^p%el)*SLR;` zPCeiL`}4mK4UZN!irq-^>;8IHPwsjC+z0H3SnoGB<@4tpR#tzrul8uBx^291Bjd5; zd3)r{E|l`gZP{>N@YwCkzyF`E{}ulK-);W=wbei8@B82V|I6X^|5n7;{Vt2QJj&Vs zwCl7+<7;2mgv1TccHgSE+V}JD?)-mMHGi+y{XUofJ^6pl`YS&|p9(L^p7Tp;!ow{| zbC0R_s}H`Uv~!A=F-cncHLjaw`0#cPNCwpCAts&R$ohhbMIJB&xspu38xK> zm6zG@a8$qCnl<XP2eUoYXD6j0vADeP_j#6?5}#nET1e<;XjY120dX z*nYQ2P;a_>**E3_N#h;L4GT2et-@uja-?ky`4R#;&*fGsJJwB$E4A^h`MRg}XHnzy z7bTL)$IiS}+E)>0xNV0`a&@`Eqo0$eukMPHc5R-NQ+oPVo%&uTey5Hkm(qq+VeCsD z#H=a~O(@fIPQB5cEdTh$@1?7>C0<*Z-U~GeHFjE^Ar^5cFtX>JKz8Has#mJhGa?gQ zJ}ue8mih0*IR>j%L8dt^g(1cFUSu^NSTK3Tx^2$U8>Meo2Hd(3c_u*m$8NS})@j@) z99nsF8M806E@^gJFgf8wK||E5wmoup3Iw#|MJINbD%t6{D9N4s_1Wid|Ab%5U4#!f zm{_lv{;zV~a$Wg}4*cQf4_a0sZ%3SK zUYH!4Bokn<>m$<{uCjT&J*rFhK6rS_sHnBe`|%l_YaOD|m(3FSXLF{Q&J8iXyh>e1 zE&GF9?0Ig9>`w|aMHX~%$fQn6b`uU1Iv1p~yx{DHORL3hh>Khgaw(l=}y=oMBchw1n^WAYSTW&^u z%RHbcFy*?^tm0xu$5mHy?bNH*Ok28P7H@LPOx8V)t(%vw{(5E8O{r3s%C|RLB!utq zvQ5@mZCNsPWec<5l?QwGJn_z8@s<@%J9y%Qf^mOB+KZY)IYrw=3+F_n8XHI`PvBdm z%(7S8xi8uLdg0H9Z^h+5pSO=;p8a@|=hKj!bG@G*-LN<#`0eSpnSC>pnGdD(Iee>0 zbQE-1yGnLzQRa%azJm8_9-nclUKoADy83Lvu@!q0ol_Z4ES=;0zP|AHho^?^&%ZQ8 zXehDYJ~xFw`LR^A%=VNi;ra_Nv$!X26}{G%!Jfy`z#*yG+4^Q9XY+xi**kOuV`eN~ zm95>|e)5`R(4GPx(?`&|wly1C9o?oZos<@#+0KfGbjQ(s}m zN;KG{$EO0bfm@{FyfXt`IN`->0OR16U4K6a+FKf z)=DP^Z*}Xb?sw}I)!;FUm)&sYiNwb=e@5d_GmZA^wMS&$Tu9d0!L+zvwcB*(g6_a1 zMrNrl>nx#05#9BYcY~jLEZ_5@`o*!wTVLt!Xx%HHAHtaC(5KZu={lFSQsvAA+4gU^ zDknw1aJum_Kz})-sMf0O`6t$WI`bgP+bQM1*)J?LJDwYq%{<|*?Yi3hZ{ER4>E9a{ zC~+(P z*Q`19#3Q@#R(WOfbnQC_yk%N-KZdQ%dcanCUwRfFi@Aqt2BYxCgc;3uVpp%Z^mKN< z{bm37nm<2e)@v)dJGlp5)MftOw?{meE$z{Q#cOtc^IELR5q>PDi?f~W!M9wwZAy1H z7wIG|3(T4QhQs0;YqwvoU|8TcuC!xoDm3plOF5UdER@%tds;%zZ9y1+%M{L#39s(` z;#tk;!{uh4zfnKh$}EL7VUb9uQL~OEyGoSdwECR0YBGjvu3B(@pVR7)+|r?Zw&`h4 zpXQ3HD@GZ+XDGT#S-L)0vaLMegrj@e7YjxgudKNTcRhR9nvwiewkAWz!msAQ1LdsW zE5g#n_41bM8()YQ<8^&=?6>fS&yTZyE2k_Hj{c~wxR3oxT<^8li`tBN3+$5n4~WD&a0dFt*}QhtYB-d;XMY{d1_xyf6tHq^Xl{S+qakJ z*YAIIxb(rx)AK*iJdpZw|GDMU9~G9$t*?*R|F8bX5A9bP`xGU2vPC?&eB)u|HgASA zle3=rtYPTC6W6&mt4E-9h7)i2G^GIUnT3<*34Px>BYCQa;$hWYQT>+XFE#Y8KFE+_ zSz-2|LPBkCSHGRoddq;RON>u#Nv*t?UdSnVa_hAd3xl??PKo4JYU`O8T2{&2XPEkP z#STA>zEvkfBD@*HvZvlzz-1-leQXA+$-@Sd?_E=_dpWIhx^t+};o!zeZIuDSJNTyW z%G%u)GH1Qag($5fbqtp$FdfJ{T{^vGRl{c^%S9S@buI2_upEqgv^wTks|BCstdE%w zRq`B6kC@+B@y4!gQKj5ZrWf1QWUCSm?{b{s(7dkK#bmWKb3}qsr@So7Cdmb}zH_<- zY}y@j@43{QEM+C8m`z4&A_5vLcYgEZWl!?`6lO6^U-=#PbnfznyWMm;EV_-?cpvf8 zVOfyUu-0zp94Jg45T%JX+kUF-IAUVit#NA`KHxzFFb-f`+VZm@vYqe_J7zXrSRgP%`S zcjXKHyb)V-=x;6iHsP|ja>4f}#y`3%y8r*{KZl>s|9AFvxcwcwH`Dp+el^tG`^Xa4 zxBma%A8+?d*MD4edb)9pd*Vswv^1rK-*3O2zweJ;{onup{QtlEU;W&^{^#=lyHESy zldqOt-*vxE`as=p_UEU!oi&_!=lk;ihvMyH_3uBwoc$o*xa-Jt(F`IBY}O!oF+I}`m(3ozYj*$ zYD`If;4Y(O{)3_5gy3o!<9x9#>&_@moygN&AhT-bw5y+|CEh)BJF1x_;$_3uGrHH~ z-mFp5=TgjgZ~5s-Grsw- zrJkjp?LxKD%Z_#@zl(;4)hsqoJH(UB_U@AOpPU%uNujD5Zb41_zGjI^Vmwg}6WDEx zSM#_XaMhcaa-qdMNxdoOebVQZ?2l&tD!HP#_jrZXtJ||bP51w2yH-|H=} zu-f%j_C?moy7Q3>Iwi__Kd#_-DyYMh2Q+SZojVfeDMA*_jHHP+k1?Y z&uACe{8_+xC-K01L!tkV_G`q}{n-6?`u~sLr^{bEF8|}8@{89M=I@Tj@A>=h`uW@c zXVibp-;pbmd{_7G_A?Q`+o%87{5HSt`~AQ7?PdROKCS}XBp;P=ZH`;GBLDw z*6b}v4AHe(Czz(QIPE~!0h!0!9!n}lU)zw7)f|4oWLML^d5KRWN)^&3wMVY(4Nx&U zk9fAdivId937&7~$6CNRxyH(!&YcA#VV zgSl0`TMuZ7Y`7WCP;m8A6tBaDMOmknxBb3x%<9pKt*6X7Ts1gTH$~<7>{=f#y3xC` zPkm$5J^&PcyyrgZM1(%b?ADHcwK zDEIZUcB`2sBs%`CI3u?`VJbWG13le_%aRi+?6<@&I`yi^QIV2ITaA!%P5JYg zQ(IaIT5Z6zpr?A(GsY&M2*q3b`1FWsNA_xHok`F59#kKI|Yx9oCeh^Mn)@{wSd}rP9)0sGcxszUHxMQ(tJ}1s?xT7R4%2=Xxgnx-#RX;YO2e!$~Quoc_1@-p$y& z?AR&Bji2KG>eus3l}K9b;_ty zT7Y#?luDq5V8XQBjr*2JlnHW{2-cXWs49GyS8lP8={l>FiGw7$sZEu`g^P|tN|0VOk!*BgfE^O{hZe*F?@KK@m+2PI> z`^3jH4zTtYA6guc!@w&0TUCS6040S}f|eWaebHUDwsm?_zU%rqv`d(N{7>O=Dg~ z#Iz|qlTzco9x9c7JJIB5tQ32KXR_bY@<&mw)hcIiL?+%!JhaqsyNQ5a64T+h+E#9! zQz9m_f_pYE-RJM;(ckRky7TS3=U?t!I{L8HtozI7b#oS`8mRL22@astpluL~IhisNOkt)}vsvyNmfnr?(ds z8!py|+MB!d#k`mxp*Hc&1WwO4-=@xaqB#4GQfy1tyZ;BJ<%-uj#AU zU%NkvTb=nexN_ysJaNlyANapyZwRTa&MkM?|CgD0=HW)?&BrebGJnpzKe_6bS*48e z_qZEw7jtK+N;rEjY0oH`+H|vjUSRIch}E|KtSO7cw#%$py#IQn#m6-h76?C(m=M*H zIB&a-RL?TbuQq$Lw=Pt25=}l)#;EnJz%oY5@KEnQhr_#EqUNc*?zzX&lUDg-$|ZJx zg%*`#9nB|?&;HyKZ+q?C*S3lYMzc>A|9buT;<0^l)eZ71qwMYEmd|Www9ndBRdu#z z!Mx88&&lv_`d@KJ-Ot}3q<`L~f2Y`E`tLaGZex;rZgHJyUB6nhji~w-)t7G##X^eg%fe*q?O{_lIxzuOY z%~Bz$BbyE@1TW+%2wg0{`qYWqZ#?C^#ico`t|kU74N=Io_R?<7scODmyFsYOrChdG zhvTT}436c?GBP>B625Gfn0wE53tzVL`uDeWwH8Vo)S5lh;3XM;2jocm3!){!l{a_@w!hQhi-E9z1p}S&(C1 zue55+$@k@Joqjd^sk^&>e~cvK(dK_MWPCK;7JVySpL|3$?PKeYlUD!KYK}$Jh z-HMX=iq4@OmxZ__l9^VAo=}?kV3pnq=}k?aRCgD7zLMSlIhj%Vu2|*=p0ZZ!g$Jb$ zMj0c@@$sp&5L3s*2##u8Hl_{ogM; zKe!Z8ulxJ`|I$8xDR~q7bIawq?61oIJAV53{Kr2&W!8Lt_w(i6Yabu( zulw~>^k2>Iv-01zpSQTTronLg+h2e3`fk6zz0dw{%`w^QhmJ|qG^u4+zbEA#aONSGRS0y4JI$nF# zv~o|iq=mGv*F`^rkbvn8UYg2}Cxjb`A7L_dOw-{`J$HaF@Lk?RqZvzYExEyVO|fYD zHjCXpO)`OI8*c0Hyj$8i^~omn2PT3MA5wH#MJ)xMelgr)uCe8a;X6t9l}<{^F0yCC z?rp!&p}}4K^wT8ky~T{jvb_0O-p;l0I&|u|!?%dNbx~<4db2MU_gt`K$veP&i+PUh zzl}M@n^p#_j@rSzHYM!-on}V$D<&_UmP}pi*pirX#3(`a_SXAXmb&ja!Ln6;BdcdT zTVA{VMmGn+*a?Cu-%q_)$~k&?lZwjDCywtPs!H%gi5=X#TZq|&PpOwxC4ym%|L*)l zpJ&LgJ6|)4S@k}HV#Xw?C;Ogs8gZT3s<&hPBiEP{PrV)lbu8dF)C+U9e4-J%`JDFN z4xR)-p0-qrjeFj1U)Wr!D{w@3!%GXj%S!j^b{uID&E)+io_W~uvX~Gn|H2&%Qd@bF zqFQcyW=}EJoPBGd3OiT&vCj(%i>#|p9hNMSJYXo1rP<5lRM<8vQq)0GP;BYCbhVR; zGAs4+lKvMnE}ec%qD;i3V{239dcHX!ZATm>R{Osx$?eGM|4@3m|Ge(}g>u>!`KP}GbJlOf;+Y>W6^G;5`2mc;09i4f__WD!#}%ie`}wfASNz_-R9!Q@XD{da?yK8Yxn}NE|M&I#42lj& z&EIGF?)v_k@`WE?KjD`Q|0O2AI^YyXTkxf(l^!Az)ryBFu849-^;!IF@qxs~H3@ID zjr=%Odn5z7H*!j_xhy;7{w(8}^+T70*XG+K7l&xYvE^TDk+hh$H%3Nq>nc5--6AFj zcTNp;+97);yJzEcp=sxvCo-O3SL&EDAuuT7UZG3!yRJCryVaYE6l+_wq{=khKl^1r zaNW2Y1j8f^+>s~-2CfxDQH6IL5CU2$)QgKvhGjy)LGAG!Ev{A>EtZ2ywKG# zZ_g^dZCAWK=Sg0<`(q>bXb$;TuRKqiDhC#w|8_S~#rc~-q_0Ww*BQb)?p{kheR7BQ zlIcc@7X=R4EvT5%A*h$R(YIdLCV_>2`w{8%tqZJwv)pc!IKaEk>fW2&`1ptaKEA52 zXx(%1_{{fDZP~I|7o0lnqVf7|X{?>y-ES{%1toGxJZf6~ZDnq>=(SD34sEA+7R{tt*Vw3A>(N?Ki=h@B? ztvpj+eo->MI{72dlW5ICt44`JE2w^Y7FNwb;lxH^w!+e<6J2 zrQ}y-^9$yj^Nz;VzhYbA?veXfv+TnBnzqw&<$Utb^XCR8nngXGyG*VH$Uyk6%a32f4j}$RneahFaMogyYJ7> z_W3rce|oQ7Z**XB?!3FpqQkJ@PI&Hum!bj&AzT4ndj))2jlbC`9W-TX7Yu0$wAqm4 zvip+p#GSX5n+gne1TI*z^OV_HIpwdKWf`0kk9QsN*%oCpTYT@1o;%Yw%?|opAZDY) z-eVckwPYa|yYcm)r0w(lKG$DYN{nc)FgRYQu*a=PwDZ)Pht2YnS*!#SLeoyn%9(KD zRp0ff_9vdl3qu5sSY+|NxpdY#iIdfE?JG~=Y0T+{e~qR^8FzK3&U~h~EalLbW5&w* zj9-}a94A~9NL-f7wc9nwTTgrX-HY$sf1R(bs`ux*Jj7b@7Al7`CNIf*=m&9 z6_b(dV1Me&he_;-(aRclXRj%+;OTDl$odu&?DvQv@3j6y-M^KVmltGAyY;5H=v;^3 zin}7WtD79y&%QJ`lh!A_TVP_6-7JAo4>;=r?~xadgJ2xtU%YTCm#XExq$zIe{7|JcEAMiOr>#5@0(5X-)*;cjU0 zB3<_)j?}7y!M4V!A1B&R-`mIa;(Yzax?fXgO+Mqk`p(Lu&y}Bu_A^a8&biC@fPInp z4#(dsZ_hco-s1fA+_o1-r`ZR|e^PuFb1o%+{-g5_pX~W2{++=YQJ=&v*#GL=yf1zW z4!mA`I_J+~+m-uUZ|~eUUuw$v^EQiln0}=(XSfT_lPIqh-Tzyu?(42s4^qVR^^4EE z-fe&W=jHcxKaR`@Jf8bMMqj>1{Q2nzt&1P5`n_6oX7Szc$N5@3s{gfqzIyCtq+~oT*3QgAja$qqy<5C! zr$Smvc)x@450+yJ_3R@2c$Km93ncE$!7-lzokz?cP~AEwug6lFq0Oom;09 zbt+Ee)Y*!11%yo88*%Ny%@(`H#wDkhXx?7^F=LYQWyu3R(TU-6B_XGEuO^8tY`-q~u2spy zGrej4npcMnRXn>UzE#>7(8C;e?1aW{f!ht!UQLOa6UNqWHSvOaEw@AFO&zxLQ9?5n z>^+4Im0oULt*<8_x;A<4F=P2Rr#9tfJ!6eDk*{2u7G?k9qDGMsYlY_9%7EVsb<`&J)V6?7&!pGjfjhfN2K zM0jG{GE%S1n`x{+{n0e#FWVM$dG7VfU$cDrt>e9=N+Kdjl6_ehiY5elOg|dqR~oQp zZk(&NS74t5gCcwC^~zbf`TU!OPpUAd&J5LE-Kr!MF;n|ehepXR7FX#U>)`1p%$Z-O zs7f7VP~cp7?1Sv1L=lNsD}9>MZO+Ybxz+K|XM#i&OEk3YV9dFQ!92l(y@I^;c1 z{J+HX%<&uF9x82GQ2NU0mi&@B`$;Tz&gpq3SCao{SWkV|zvxWW1Ub3Cho9f9pPTT? z?bnwx4_YpKJmNHGMKA9T2F~~V+x_R3H?5nh{_n`N7fdPkTu&AhZ@5|(B)wCy^RM0N zx^I`?cK2UD{98NWsld;t^Z&nEUH>WGc7HWv#Mf_k`R~hV0d27u4kbLu=g_hG|f0^8??RY(1^5eIcKOWmZ z`22dlxSrq{iMy5)J=}DcJ(|Eiab51ruETlpmy)h2G`opBXi%O$XQ^-YM$&A`HJ6RsH^&2galyYNjlIra46cPOX;S`s^30IAb%F_l;#e6&4 z(>)u{1}dLW3g_9f_9owlvrZg2LV8P!u8 zPdElSt?O}Z4xQkAtthl9dwZS~+ioMfroBh!7AkWY++=fE;B5U@n5A*i=D*I&JO|HB z(>;9kn2_~!FS(WyrG?BQ8}Ileoj4cpo>fI`&jQJPH``t1WnJxG7H{F5Y1O~?)#?dv zIaTJ^JYFSz@o#EVf6>D|59e$tV>;mQ@<5ct_oKH9Ir0xRc3M8^Y05bgA{z8I=cfJo zs^}iYe8bCgw9U@Gob#+(^H`v7aPrN>%iX+62@O1MGPj(b2(%^1S+4su`J3|kZQkW4 z6YcNbyZ1gnp6_dv!2-KK!l7>JKQ28##BRwQma>VjXq%6?qU(+mA2PqLm*f!4wC+_k z;8ti0J9%+KMyb3*`A;+M)Qd7-lvMaj{4R9YHghX$id=PWxmeZTUSp70bgKFr|AA>U zG|Da3=B98TQTk}}cz(^!{OGUl4|LqUXhhJWanBKJYyS zv4!iizy6MNQCr;?j)naKw>-4Iny~Nu;3}70v;B{LdK|y)`mHI= zp?#XqpE_mfJz4)hw)XGsk5BEtp8wx!!S-~{g{eUwp6&RM+5PciY5dmbMLl0Wi%PC4 zSjv=tJa^A;p}O-O6JJLhH{ZYa=kxs)_w=s6{{BFAUiple%{4!yoUd%)PAg1~J}nsa zWXJSNa!W1-C9Toj?gz8JJ8HYM?2Yl$KBZmJQWmu$D{kG4v)y)A?dQ~eJ`(g`-sfY5 z^BGmI^=>;cVbk@3HM?yVZ7qyQy8mYO*0}VJ=w%m|NxRLT>+jFH$y{w)`=#H>D^_H! z^SQaO$hmb_aNWwLSW(v7b}bHqb0&85evPbH;aRKSc&b7F%;LXx?;4e>luRTvr(K&X z=q9v#OL~j|=el*l?|&S&G%Z#y_;vfY%#PnvdS4#9VV(J1g&{riqx6Ox+2eM_9Pue@ zPKq`PbWaSOXD1{wrAC6$_S>!Zg_6aG3ptjAb7bDyw|t|1k9t+^!OY1I3#xl1{n%#4 zajofc>0yWqnSS(wt?=cjJ?AV>3eH*i%OJ-b>XC^t6Dez z=6#xzl_kAp`(DOtrhL0FXSqm*&l6jz51cc1F5wAN{LII1*{Pt-kUqsBV(aIc;28_H zW@vRd+pMn4;R`J;mhw8Zf!pJdhETzUubZboK3`w|M%te?CSm6f$KX?+uVEhbyxM1)MHO$a0~ryWhiSY@6;EYr zSMOPcBQimK4ZW+jgldFq>}pxYmt?A*CuqSJ*MER(*;Ka^wUgb|k8OIsW2%V1SLcPZ z4__wFou0?IDzD7e_PP;|%v#2qMl+Udlop?TP)(p&h=_3z&e z)j7kWnxj4`rNoGA+svoFzN7c4d#zjk#^kFrEH~;K8nr)Sven(^;j(rQSD|BK?dqRS zd`jyUpEj8`WAPIY$&1Nzgl`>T5QtC;&zZjKYn_zA%mhm%Rf7#&3=@wBh+SIeD8{tP z=y>LQtB#QGJ(@OMtJjMuy`5)q($PETiO1IGJ1mP|sQk$2UG8n&a7#94Qee8a-%I(m ztQ(yVSZx#B|Esg^TkE+K>*OrzY`8Yd`TVzwxt{*yn?*eTj|vthvx;_W=@|Z8wSOU3 zN{bXeOeoBI&Xzo9e!Y-w<+sBNLT4R2@bJseIsD1~OxOA+8sB(+K=Sx}HxBz{rBtdUw;0YVH-Eb^@5|r&#s~ZN@A&`GwC#b%KEKb)e4iH9-v4(y zw)&2}YBEm+WAJwW{N(D3e-Yaov;6<_xc<>!vsNU?FwXy1;qdSr z!*NUV_)tOZMXwxYrHJlaRhwcvk>j$mHLpadaT5QVZ#{v5yi0Z&IvMU|->lt~e2!`H zx04}jr{1V=r3E+Mzm~>oIH67C+rx8)4?Z-6OQxLUyVCV+&W+mU z#yx4mVXH1|_`V`=?)LA;j$V#`^I;K3RYc3Q+%<^_981kk3x4W|D(%>Cf5ZK`jv5;} z_BQ|D;&^#tz^8Kz{igg|9Fthg)pl#|Vf9}2pz+O;(y8n_c;?JCNSQ9AloG!FZPvPe zg*R`uO%?c>%w>0H?c}|=Tt2^S)?ToS?RP0Nl39^KZ_&ty$8I3Su+eroLAE9JbM2 zN^#eoNnVLtJw!~DcE;N@J25?(Cu91}?74fFr(bsRp7y@xjmbTMsVoL2;_ee3%V@Yr zx!yTgFUxRmensq5(N)cb8&l&Boa6{CS*5M?&b~$Ds6l|UXYETFw>fFL*{Sb$-OXb& zPApHc7kPK*tC#RbFXwexnwbYyrA%p>$hkG(aEyAx!!O?*(|)yFs{5VyH~s&Ir+0;C z9QgV~dyY;!+v>ZackBw?@2$*bj{9zKUAExrI*vO}8}0b#CN}BcO=R9T@4a~00)zLa zaXY#XzxJE)A$IxSBEFsM{r>WT?|lCMb}N!{sLh|A!*kJTxxw4b)1Tepd;at5{(ZH-bm#rQ{r~*_`e^Cx`Sa&3w14sIOaF(f;isQ|t-PycptSwR zRr{;Y_dotPO|{tmo?4Q9)-A5~XTICtKYl2^lEtvCG%|Qur2d*l$Cw$@8TSV7ss8)1 zJ+ZHRKiB_Evw3&jGO+`e%-Pne>9wJVJ6|(-J{vcY{bi{Yip;UJVmwPyM!q ziSH_hh>P-@g{)quPjqMnUDld-Kw;vVrcl-sr`YPgu3R9defOvhXa3WW>g~1%Y&Ud0 z&be=WUVQ7S&*vtvPP;u(is|wmXC+OyZ#B! zlYaGdw4FV;!T8*5?p^jLYMBcZmt9pXRDQFM=h50fnZIT)uko?Dru%5Fp+tCi5ZAd& z&5xtDOI06aZsy(HE^Jt&(#H?VoULNr-BI1SB!F>Wtqs#fy}F}GjXM`CJa=lLQb6t= zSJo<{vS}K|9_;}pzm99%S?~WMoxwX+~4J%-Pi7}s%JK{c<&f9Pm}Td@1pzc3oGMX&c**a>36H^U8d+?p@e7hwOaR5 zpUcjBP$m^rc*itl&Q?a5@AIuLh~|5>1RVLy{^y(d{vY}Oe|>&kv*XXp{Xu*8*8GXy z`}=CuAGKp@E1%__W@uKyJ%bMR+~lHdV*!YAD6McUeUwj z&1xKbXX4Z};RK!P;>-rOQ=(_JqZ!@gS1JYcC9GjhxvBlB_l?;H7W2jr%NQ0f^7p)W zt=j2UpUomOrDgV4&qMeoU-n_OVPdI!th=YNch6~3KrRX96oQL496 z&xxxE8(y5eRh!GG@tUFRWXY|+y$kt|Y&d&6D93QNiKJYgf>CVQyk4cbSNGlj#LPQQ z-|5-Qdkgb}oHabSB5ZZatgq~xrO5ewXJKQ?+}Nql1)BwhtTtb>dn7#RR&>k3<3FC7 zKaQ@rFnPh@EtA)YvFUfMRz7p%TkPR`#~SbG%~n0yIE%|gXRGuLcUdWo~vKZF!!Uaap|UqlN_ds zZ&s?5n$?*wwdkVTZU3Y1-r8{8%Moix6i}S=O@HB0?9Rh(+#g?GyQiM5y5i8~Tld9%-6p3tl&+7TpTHz- z3cZ5o*^9PV2m zQqy@+w*A)!b?u8gyYBB+IbSb-;Bc&pfWf=Py7%|LJ~rjrPH)q@QcT?Yqxb(Y|DoTv z{{PL#@qdu&K9GZEb%Z4uAbA;{Lyzxp#F~ z@_Krs-R{iE^jXDGsN*7Kl~rD2{PW0}JDzuoVvcxM9RHJZ;iJL4d4K+Vo_T*w{y+ch z-_K81yPf@dPEG7n%gHMe+n)r*x*bTHlq{@sY{H~O(=U?VU5gKG{hGQ~X2X)dI$A5c zV`cJtT=kSMC7%BmB5^Qx;;Cyhf|nRszA*f?R!^oeps)G1iAPj>>iMHLpVvl<6+g{T zZhWG{8pPY>nkdbpy)BOAB5Rf6yl0)aB0cjrR0_OSns{riZrJ__R_ohrC#yaAQk8d^ zE7_QxX<~c$`l7vGCiNVxs}T8Sks8rHx2N}>MEk198E=x-q^|Y~n(D=}Z1>-O_4w8Q zWh$3d{xa-c(XrOMlqvW2B?$>-qg$eZOj6sf*v%|zm_0RdHB0W=)zK3UZ_<6d=87@b zp6TazNR<@MkKop66JVWw#klL@mdqatGFsDKxEdxMGB~u%U*d74OwR4R0}mF7zS#0{ z6Z;L@qb8TEmz%!x-uappJ}=UumqunfZaAcLup`Ph>YVWQ&W-~A z?5-7>A9en8ed~`_b#<8f?&q9ofv!hpEKu^(l3LT`dP6isVyhJQ(Qh}?c6n7AEfIO> zlhJG7XWgz8nDRSg*Y%l>%DGEjfAH`s{nFtJ-{7a0p;9>KPb$}MvHD*RZ&>fBK413n z+(SqAU9a^{mVLhSYo+gZm9OhB7vJpL@tJpGdQA`GwY|R#>n|m5oN)W@5y|h(Klh~b zu-v)Hv-aaQ?JbQ9Yd|KC(pM!x@daL*s1&j+3!uBr^q+ZcZ;Vrx!lPsiR@ z!t?HDZgI2ZmFje@ypwkC*^KR>btZC3+dBj;Hx$~~>E(Ef+x^M;{cG=z&p*X`y0716 zytB^e_}9z7ejNU4^^afT|E4YJWlua>JyOf+FTRovHcZSn*yW+QVWrH9Wrvme6K+kA zTc{hmJ^FsNr$%Pb>m3U&ozn<)b@9-#4lcWK(4ytbov3IPwj(^}HYKy=7k{z{h-zIr z;q;bkTHyaIoCHb|ZcSfw4rH--E8|A?y^KO+hz5Cne6&=WpuD2>tk9c;f<}qP1gGZgB^T_Z+pRXGmUz1>9l97?wmouk z(#b_$ykF1GnW^5ZccWg6Wv!sX`xxFXL5apEcMqM(vJohhN_Jk%U%c*}y#L%a7kjQ< zxwH0Ywq;ZHPaV$9il@7NOlrK?8EY-C0_P+17?s)ses^^a@nOZ~pb(|&a6u0puXc~0-dKlRB zR(8(`F!wQ0pPzK9Q>Q|~+?u(O%lH(#SK{pGBf&pcZ@njYc=etMJX#5QZ&)sIs?DBP z@+wR1s#nmKr6<#uhR;5?h|92xvrSyal20eZNokb_w2#oSZIE3Lzq)iM$5_o1#oY*Kb+0%0J7OKc|1yovR;uleyQ~e%<_C zuJ+c~mme(CO@9hcZIr&l(s6s`KDT>s7w${XGk3XNq}J5Ycth|z-}?DNJI_iUwG|gD zm$|*G+U>fm&MpV1&o)cuf1atI_;}y3ci$iV(3gDn(cQ{%-WtXFg`%}DJM|q(=-#2ccgp+F>o>eU8_V4n?Ks^& z{rvW&N869TmjCzd*SBwG|B9c+Gq!#ydS*~$7<7&!Re}A`(TF6)&3D^#x%?Fj)+DUa zS9i@k$`*3!=_%(mX)}Am7Psx}N}AJGY#|vPa9H_(56=<-w<)*yohz>hX}R9e=6NX4 zt+=*UGfQx%i?To&+a1+6 z?QJ((vuvTV-+qnaBc5KytM{awylk~9JeGY*tjVz#?^gY3ni_Yjd988VwJ-0@ zV6Z-SCh&UdEQNr(DGt_5Qy*s;TwC|m)ZV$x#OT;My^Y{N49c9j5^ODCgxj&iu%|8{5-r(<7phfLL;j_*tVZ@K@# zq&Nn_RyS|j^Rn*` zkKBz3xlq`~?ALGqJ~ffIM()Ako7aCHXEkLo@Y@yR>~_9t)324m`yTTxKU;FISG*xV zf?cN~N%H@{%k%5Z=gY~}ncsqZq zZTA0w+q<{-@85a%Rqp@wUG=G!f~y=RN^pj}N%0U|d~BVIl=h4z=MPWWGcDE2nKw^x z&V@O$)MQ6Ab}8>Q{9I4ZFCex_hN&9nNZt2;I1D=fy9dCh3Y*ah(jX z6ncBRI4#q6O?JZJ8>e|>#kjcZjNcv&jXAQ&@X&8Nd9!%8+$ZyT7(`F<+z1Q}Dt+%U zS9ismjM>6dlN*!XBwM^#QoS`rJ1lpKm1^kDP3+5Gef3#q_ukpZ>PW_6@e_{oHh=wW z@kC$7b^g~qxl0TdP7s#pFj)~LJZbvIU5V{|PYS{h8%d-q_xfs0$W8J*UU}7Ie~lTl z>W(A#G8odsd_QqZOK!nX+~^>iyE;9|exi5q)xP`uaO^Cimi>Pd@fLbzSnLhc|9p zPBYmlu{uBUZMD~m%fhGlHhk9(>zP+B+4dl+y}RdZYpP!RtADeKL?YgtQ`O5TJsjPi zVDyqsKrkj3@h`)SKL`6N1IqsomZy;oj*+COY*as10%<#(1_^?TXl+x~r? zlUI6G_1!$Bd-8LQx5p$XFzq|Yt-t>F{ha#3+Fy}2PrkQa_upRe*KVDBtZ9Do*`4c- zl&(FW|L=#hjg6K35)(G1eBsqep;H@j-^AM%SAP)Pbx!qaQ(tt?U8$XKTVDUzv93Ex zG+DOs+;`da>&*L4A2~c{#*OTCJ7OfxAOC(o_Ilmj|KShj>&A9?Z!x~%;iK*7G`%wC z09S78a#ua^Ia`;qv0A+?)2m7~J7s6|Nn%AK%Z~o0vH)-YCw;e0GJcQF6=ixTQOh!8 zrny_>>VC8Albhuo^T2TJa0okhC(!jfltcK07_=CV4p#VYB@=5TIK zuO%z3s(*60u}o%dNnH>tU%TVhIe}}QAG`K3&RFccV7cjCm&Kg{`{qxvvZ(vUzNP#a zkNV65ZhRe2*YXONaX;5hIU!fOz*r-{M0jJafBnms0rw2cG9}I(FxVb(FYrq9^YfL} zrxqvkNi+v6`pJ>W@AhIxR_4Aq!~RbfwuX4`dsT7y)KO1U;53Mo%{#`yy*DAq7=C)jApzJ)W zd;5~lo?w4+sjB;L;O*<5LV5E1E3CgfizwI=7URITzI1`!8Ht2kk>e4^jm_RWzkd7m z>!;Uu{;yX58^7Rw(o%QE)Y&WTUZh@$VtC~JBg*I2-6F3kkx5Hhh40N^?kMea2{4)_ zxX+ELuvOObTHuLQ?$b*1UfQN;_39!5@<^L^-+dLwkFx!T@#ZPDC~Cfcj@s^gA7 zI976Q)+uhwU3Lizm+2&5k!qB9lFEFUb(c2#R`b0PbH!h;tYo`+E!bkhnG0f-SAz-} zPTzfe;=xM+UZrNexqB2hHQ#xw_cE|oL1)@{y)-WlhzOwm0*M zeLg4qT;-mXe1%U|T$#;Uz2f6Ge*Y8cvGerr|6zV}`{Re_pI_Fm{}aihVlnCN2|Kpp zErHd_VGFwVC?99yJNEE_*fM5Or>1icWn6Wa3s_k%oAboA`>4+46?eEc_HEju68>|7 z*nNv@bDFd6Zk|?rt~bzgx62#V#gTcooXZ1yj$I3#7T&oo$H#B;wa+m}^VY?5TWJb5 zOlk|?;Z7#g< zMk4&uwzRcZkJURBRPXZW^0}98vf+fNy4o7)@Y+whR_qTNCf9!Ma0s7rT*1uc*6iZq z4ey@|GIYB=@Bf{8W#*NT_c?iw*seZ2e)-T{F6&wQk~eSl*>X|PqqSjLkkGqjN_u@( zdKXq4omFZrUHGU`#%=MXFyA*Hzs%bxY3nU{Ncoec{QaLsN%AMvf>@Kk@9^N~<}a*# zAm?MHe{}7K4O#m9ihJKgetC7->3G`Y_ES!d5(zsb|MG6+G_TXXr5>frdcSu|y-1yx`1|L(_g2vl}~Yd0iJ#WGr{Vcu^i_v4z0{KgJ@@nNzN8i@d>6 zHFpt*(}x#Hjd6$5rl*I^lPz%$u+M*86j}e%``_#M>z}KW+s!lXExom)dtH3a(p>dh z1y--DZuf59FkSouU*vBkp+86N?y0u&SL@$B|3%!tb-xud7#MXQ2&O-)ZS+5|Xa3*s z#`kOG5{}twUtn^W8gq&31+b*Gu=_GCn@n$CRoO}D>6IY9m@AIZfw;w-PSGspCfA(|c zYi4p&xu@TfTlDJXw_k$t|E~U4-2dnPwqLSI!7_UO@l57hxo4`_C%m|dMJBeS zx6GYizPlvt#=G+i)1I`=lz#PKfy)8aUbZEw>{-n^ELU7PCMAm=?z(mEL!j#E7Yp^4 z2o=4qbp0l<`IOQ#>6s_Ir)-FeG2Sk_Hs{uA_ARFwFPlCPocMHY58G$u<=L#-AImb> zUF}+CYJNX4{l+F&YuD~K%Vd?6_N?mdY5m<~)hMX$?v^s=o3xXH>~ovzKZ1I$yx6fh zV?x5*{F>l^$r8KtY%XsOj%ZoKGwoc`3gZ|7p54~>SyB%io0OSS;ApFr`L^=n?#Lr- z@@;py5AXf>=8ovOf@lu&IoDr*HlL?pWc6mT+NP`@xhy+YPxGv7oyy@pO+8R@x0>AN zy{~2z-dx%cyoaTkznbBwmv2u0*I#1E=IaHu+#fh53(K!Lo0P)!aHFAJW5Ba8_a7^? zw&l#$W=P_jq@mYn-P^>ZIpcKCi{c%7XFPX%bNjT4tfJPeZOTRqbiI7zUpGqc(oPPa zt$EpU*Zy1Hf(DQ8y%wE#WKGAiE3J%c+A2?TYzg<`@tznbdLSwH4eNTwd2b)MxG#F@ zWyPyvYWDwR_^rX^ftJ3)1=hab=08e!?yC51NBv!2YrA~W#$eYM6ZaP8|J$Xk>UaFr-CsYC zUZ{L$75~Q5?thAU`}sZ5-rV0$#4c`(;ZQKoIQ)mt{>c2lv#;mJcO_3QuIj}NtL|5e=SyTUDNSawxf(r?$cJvP7os{j3A z+m?Sk>bkPL*&BHy^H+>_S#75YKB+r%`^L6Ab}46mJzSsv`gz^=p6{iV-yK&^sH&;@ z{_*ni>;Cs2uC8xW|M>NP)a&G9%^~Uhq8V%V<-J?8`uL3qzvo`>R;^9cik>s&<5I&* z3!5KY>X`8Sg?FCHb)ibJxe=c2i&MV6GP^3;ByDj!Cm~nToQqq~FxFvZueQ;IR<6Pu zceWShzP`Z}+7Ld8vuMYgMD1j~3GV)LEKHpe7TVm(ZJ; zH}5v{On<8OJ>-HJ*R)xQZY+iCoul4c@g6E&8vgAJ4Qn(Q=N{Zk2M4#oT48B8?KqZ@ym1rT1;|;h*m|{yRGV_x!&v zU;qB@(QICD?{ZLi)%i&7lI1P_^@mJ6}LCvMdO$M zT;A*UR`Zi>^RaC;A9|R!Y&DS+{9UV2vOn?9lIR~_CM7W*w-pokQ26QDK9(a^on@z( zf4Vmn&t0s3H(>n*_am(J6~Ec-W%~EkM%{Z=cI5HqYYR1-w?8eC%b&mg^^YGvzx}=c z|L@yhZ8C?-s%=-@vynTpoORvy` zJIA-dC2#r4t(qnu=FRk(9G$>&?cC9hj(cf=KM_WNSP$tS%gI*TnrFJ!gj zLaoxdh6}c^Gw53P&Tdp)Y~)y?%-hYgA;tAvT5{^WW0Q^t^Yv9eo#ocy9Fte26xp~% zRmd%~es(#w{whr|2OT(3(e17+2IiSqxWZ9%(5fi zA78FuPdtC-v!X@T`Rj5LvSp8Bc?EZm850<10eAvLOVPtenfB(Auzn*^m8JK?i_hH%PhlL;K+&?>)?VIql zf~5L=D?B)5JNEE*9IO2nlrT@)ZE^njl*q#>|9(vV^740I{^0|iHS?GAoUSe{nC@5> zbAbEK`?;ytcT3&5{g|=d@z3|y!OK5f(AimM|C;q92m2qk4@WM2y?%`G{sZRi(*N@Q z{Cs}?zW4DP`&OQx|2pj|^VdTgE$7)x@B8#;PyOGoALkkz`n|jAX9TO(HeE}XcdJEK zs3jiP*TE0qx(vJ!lBn1?9T6sVCt#O5E-Luzo z!jGPJXr126_NGD5M39>+_omzXCx36nJlkM&;fM{}p$m&7rZ4a+b7@=Ra_ppkfTVBg zjJu-BYwQ}EzjU&7SiFC3vzz%ATUY8C4hwHH!&%q453lfuc+2r-z3v;(4JEoK_?%<3D?gaXrWWg?8y4Q;fql>g1_JZk#AxFhxw{ zk)U@^rp!baH<{I6I&$q9le2Q8txhVu<)5AIcEVxFt_2LQ;8O*LCGT?0W97>~KNuI~OK@d)L<4 zSKm}ly7jJHWWmlWy1Vkq>tg0q?8uX|OHN|U>v(IkWd7{~(>Hg$b83Be^Knyuu&#oi z%u!9R{`qGXs~_e|*v=i($aw7Uh{5$?ueAe|dJnJ1=~-9GW>AAPqwZSiuu7ZQZS!mQ{{Q5^z5M+i`%AwM zv0BPVD7sCO-mW;!{lQDk?RRf?yj`^2|ML0cYtufKt+vd5vM*oa{r}_l|9>;L{}sQl zw|;Gv!Z8k;q_(-r-xUj7at!k(ZrUC-JFI|lrh50Dgm(|NX>OaR&mOC3-Kv{(fic!e z`QW#9>!OyIBF!!?2^08oY7gC?aZTV^rkdJZbGIw6jP|-->3FsMWLBZ(VN)hgcHYcc zT07FN38`kY%4}?CO8b(tu66Udb6QdhwU50@ZVl(-S;G9~;a8{QCwz4G>}lIIkBzTu z;l|R0%@tO0CH^b@6DH+GIHtX5vmswwbwXq)m|z) zR5|D1)okw#{;h{6dLG)utg}&dy7kFb3nwnWe!)Rhe8&a5seSFgZtYDfnZDGFb0cSN z=a~$-)YWIyZ@U__^4@%>GC%cbdb#KQB0t$J%9oy6Iac)rmpIJJSS}D_vsN+V&zI$r zn|Fwu?g{#qSU7KD_5#LT>keO?`pt2{zTaoIeww+{SCe^4@$Kz**o_a)k$iVAhFAAi zACDv1*Z_UbBM|U02+GAgSeW>ga~IJkgrFOE$gR6tF2Q zYQgU1li!_c_c<^_i_7tvr_z%BRmZ|NXFF(KW zJmVdP`FD->F$w=T#1XZ;a!c*seaTwqW-y(vWo@!^JT7VU;?>Wn3!+*za{GVy#UDNF z7EqJE^V!+WGo}lEn>F9w|DAZ8TylSp_G{IemJPArB>Y1Z<&L&5J*_i+_j%bUPi=jc zUX@Ra9N+j$tK=AUHA-|>mrk&iOHefX)c9NYSab51ONu+Q&R&1LCWzto%Zy$ z`>_50VfR1F@9+Kl^Q*4)JG*VSPV_vKm}ner+u!_ffq|CElC@e&;;eo*uI!oE^o>nq z`fQY*?td zM*KdXwc#ZhKds`EfvgA4ED8(Qa%+Qm!R_RCft}$=hT<~}Z| z&W!3dVHV7q8QJ{M@nBj3cV$+VNch6rX1m2U1Tq=Ltho1!ORQA?^5KUC&Q`a>u5hg5 znENkeMeUor0;Ni?w{RJB3++{zSZijxX5}l!GWiL2c1>FRYx08XjZYJahX<;brd1g3TH;qh8!N@p55))OjIIK7OI8%p0ekj$0)plH456 zz3(KG)2@t76GFd)*yWw!I%`^fV(YpMBB^@SO4Gz2Y}wY;F7^9}T|{q-da8yNuj`GC zb92x3J;-=`ZKlmuiN#x#G~8b7i{26+*B6k#F#40qpT%!jZpy|g?wYW0>m0saG80SE z_i|tSzIuW6j%&B;dQ&nRu7-S5SY~$Vp^`%mUpeC*(UYlH_Vq3=fA-Ywci;TB-}~mD z@^3JHS5`N#+hX(kigNXgdyu1FUgseUPz`DTU_{*wQ zhju+m{`bh*l|}Hg#XXz#zdpX-$#4HB==Fsi66Ur4=ImJ8|83swRKsm|`c{gzdutR( zZ~fq~XT!a1Z*7-MbW_-#-WzCsQAQ?ML+AAG9R+eSf$8nf=Lx=KdMUF;&k+j(fOanJ0xE$ zbp3g;qSGTeO~!57f^T}q8x}7*C%nZ_OWZ4fNpOZ}2|w#$z3_P}%M}94geFXI(Oq&p z(r@)r(H``aA3ON(C-i^anSNwufAkTToIN@^CmD0Dxk}Hq%;)cVE>T^X zEM_|Q*qlbm*Ch)*CX4nRXPPm4=jTr{*EqLK@HJc|eqe&c+oulSEiZ@$HFSt{nZ128 z&9>Y#=C#L`z;i)aoO?aYl$j@q@|?c7RiE*>qiMw(CD+75=_}2Umk5SiqbceZOSI>`ziWcq~7n?=vR+LVfWwWrgvNdmeW%bgI>)QkMpMaPCLK|WJYHhcrqAJ)_xNRJa!!Bsv7?th{@lK@uicM7zkl{| z*S&joe_ldt6iH}(GnwHmg`aqIjob@93l*Mzt)?a(y>%9 zd!0=fgR*EzWPhiFYgX`8GmnNv&k{;{m1Ekr?3o#&(WMSaFw=I&^$ti9E9(o$9 zCuOI|-=D4Ha5jk}qDOgyi)z>%&N+d>p3b7ZyFX`q5$`N0Tkg>hWB1%?Vq9MOn3aHFI{%>yW$4W5_aXYgSrD zHmh^n&Nbf_=r5VjbMeRwmL(LvnPEF(rJ8hr1;Y{9Vy@+)WWqx+A&#E_Dv`*V3 zd2eq@i)9;Y$DtJ;{eA>&|9|aASiWJS^p81wzb$7L&pD<^bN&dBU$NHRh1?x9m$hbW20LR^=x^+$0ePtef*tWW4_oE#}MOUJ>wgr}QY}zK2B)T_u^|zo|FDIRSG~@B2 z+y@{3-jFYT(;+LJe82nmuRkwyllt=G@^1%DPhR`=)8F0oU(Vat|M~ZDcKrQ$|E|xs z-*3H6+G}A+|Bs2CqH#-YnOC1Mn5!JVztXxuPknpLtplDp4AX;eNqT4Q{+qc{;p|p{ zz%N_wa4$P_`KI!EcL#eI*y zh}7;oOC~t8+p^CLD!Z8M=pkaxV&o9UW6)iom=w}m{_(20%mu?n-4`;BOHwi{H!9t$ zT97ERVadrAJ-UBZ++u7Je$Dzi>u!^1L8xfjTGq_9S2==@m`vOCGn`wih?W14f^otO zLs`BFk2+-!AJIA?c=^PUwN(qtJ}XscoDK8bwf6zv)9nrh=bSYA7Br@E#k`X#tiHcn z?!}fA75{U`cqBP~t6jglF{C`D`sV4_gaa2t!w(#^OJVy;1G4OlGeSOVg&+^Wi(19~iBTn6%}A+@ggOuf5BeYjUt_A=B@T*2c0t&3>CTFRVU#--|KG zt@wm?WW<8MN8@DfrY&dU3d%cuWpB92j?ZTM{x$!*xq83T)5wfJtlj(XALM+U_c{K- zj_PBNu6(`w{BP;2q#R+}#)fCL3$A1r9pc`aaQAz&+;yE7Y}*;XSWLZfihg8R{cY)+>fT|9lz_p#O}SZ;91W)3!38l zzrIv%(Y51E`1|mEr|9|f6Qg&;d^*h^{qD@(R~*`2QKC1`FFLRy^3FZksZxS71^Mrl z+3kO9ckT47$y>wjUMlX}rKn$6nc=Lo0-+f^^1#t z`B}b8_V(k)-*z1R_w{wZ`T6KSZ{qj;`|*Bz{QuALf7jd9{n_xWO=ps%7uOA?xjNmA zE44DhM0uZ`nd6x%w!o$OW4?e}obo9z5d*b?6PK?_Fi+odZNjFkf;Z1rST4|;Hu+9M z>O{E>(+>x7izy2(7V_L+@kCa@^7q5`V82f1 ztUck|1JBco7OQIICZ9e&|0(Mc-B)Wra5UfX5q&InMPYkS?v>OG?)YOBGW?SL2hw6@ zZEUXCod3PZ|F>=mz?P05E4tEbxWc}{vwiUmqqPCCbh z?!H|S+SK^8wo)e8D&qFC+uj-lRWDU<3T|%B)2f~$YQpe)*X{dRmdk4n@juvi*}+jO z)1~mloA>{pFtB-dcT6b0DSKCW=b;tTYFk;?th4l9y*p&9&yKnG4l*o0S(tj>Pw8^+ zeU-*pFN9;a+Z{Qay6?ZS-QSn(A8)V!@&ANf)$z(lb~Ari*|OQ~p8bybum0((yVD;v ziJAB>-(Qj@Qux2rs-vcT>%)K6?-d*NY+lBiqh2M|f8d*Y_O1t&>AWA+o4(BCTKBvD zi)D|~oKxF+cg!hXGMV*?Yr^%<%)e8wXn#;W$Z%jT!~VQ}`A45@!m|@Xn*O^O1-K119%5SIs=Fq7 zP4)yQ+k{RnohZj`tsyTb?4EhR%|KJHXW6yqCr&hSxyvbZ?DQ#|awejadHVdq+mYsL zULVln=abs_WNyWcr20KiKBv}yf3y59KfiLZy4%krw^GR|y?<2pJLYeQD9)U=yk_eC zzEtJeud?UlD$f0pF1O5L!tN&3j)4vOw~yR(iav!r-JIx}puk>xVfFXUbN)YL z)F0*DJ;AXd*CS%Xi^?e5k1{J(U4MP&;OW5R)z#;J88~shV#w(Ix%e8(qelvFXF274 zVvy3d_KIFGLt9Vg{QHmZnC0jF{PX6o&}_k*i6%2OLJo#3(7D*Em82{`s-0Kb!G*mHDH;?SF6Y z|1-D#@9dxYYWpqupB=Ycy|dW1?$NTj9M|=?{k2%g{g=Ihu{6qHx9%rD(KgPU?~DIF z&3mLG(NXBmY08%|hxu1A$F8|q#w_>$bv*9>edhVSr%X)NKMLwj?5r`*+Vaw&{Qsqu zK@vCK9k|G3R>A0G_y3~V<2YVN^)idct87?m{`S`Yo&NKz{gUbRKVt8y#l=6W;J)#3 z!PVZm(q5M0S|5KNKXdSL*7cso4!8BX?Dy+e*l1P6)JObY)_z>nLT&n{FFNnMoexdB z_s#dTc*P2fZFiKmHA?Up?deti@a*rRuAjeNR{Sm5bLZK^juRgP?*Hev{3ieJ+x=sg zAAfvjU-|RPho7k#xwjb{jk7j}g&mEF?ntprwWhmw%wT6y5q=-LQjLv#eQo(H5YTt?lpAF zv7VT~a?12f$l6u1456V3vA?r?eIC82GV|WFyzF}F-{S_%a|axxbD^u{Clha^{V|%xetl|ZNDaOzxJn)Yx{EZ zi~r{6AJm?+x$gYs=gn>|KfXNM9XrFk;NIGq<>`G4XN6A}f8+ho!&ksu{(*__i15CU z@EXZ~b9#@|-uSQd_TIt2_7mkx)DPZ$-F^PA!u!AR+$*ZZT-8}uur};+JYKtLN`#w= zk>go*C7bp0?bg3uex~Pn{6qhLhTqG7eOP|3{MW13&Aao>`<7Syv+Rq~{`!;s?Cg_L z=RaEPNPP3)W9HG;JySxoV>(oxE$kB3wtM;5^jXujs=qNuBX^3OP#4;oP@#LiGUUzG z#di&xZnMgN{`vZ^(W1WF{rB(3?7oyZ-Z+=l@SG|Ml(h z@wZhembshPK8UT+R^P_<^}r;f$HGN=wrhVj+~Sb*^jVM<=;hqE@Yb|l9t9;CFW$^% zRla9*@$$J<>rR|z%9)y2tvi2Ragy(3AqD^jm7@M6FHwxVP8?5lxJ4bB^$XVlMm zX)3jvS?#!64^LI2&s13*_PGv4FPtVC7ww#Jd}_s)!|XGn^7Upg^8}|}H98$Bx;kQe zgnQPpjeA;*o`$LxvvwIi?a$sjjeFfH)fHiZZ;lJzVOwoITXxg+U2XkOqZ+SXHI!7@ zd-JBfSKjY?GJ7o3&j!tOnbYnS@$b>UBYUTJ+wk{V>CRGJGh6%Nn?~czDxD3ELN{&7AyR>AY!V#mz&8!E` zW*6o)=EkvyrSPulC_A%l=JnsnMq{&DZ+^Z}@9W_X@%vk^1s~OY;jQsT zkMFx~OS$;6cmKRqO4#ea9WT1~wW0drsmR;a`Zez}|5>iwAH3MMf$`|xexL7>=W09u zJ8k${%TluFf2o(?H(MsLa-R!#y-Id9?7N`(%lqxMEv!CAF8}=gWu5RLj~-tC+aLMd zWAA0(R})VD{&eT0&z~MFKmF^&TdDW5$weKrHeNmU@t-9B{cGX%D^Cl5Z?D{4*z@a) zbyZ{O;bs@1c`8mG>kieh8tFaxx_d`$&#t3^f$V2GV?OWFd8uX1pv5I_%=NNs>5apJ zXUgL<>rDc;pWohp|GwS6sZ5U_etiDl;NJhE-~Ye+pLyrc+xnk}%U?h4?|&^(V5Y6* zP*h;B<3gA;562_sfX3Ay)UJj26l#gHTroQN$>z;XxwMTIM^xUNS$DBwj&aCtmgKce z+f{q7&J0$ZIHN&_x1j0hijECWpE~W|I`!_(t7Z*GF6*ZxC$G{l-Yj*1Q>0UP7ONO@ zv*heXnbLi`&$RLcP5K!2wW?tC^7-y!`S}WSZr?Cd>OZu$)WP!EncEYO-Ra4cmGN66Q_bB#X}d*VR4VuB zdDl#GbXK1;w#%It`#ME&+3cUqPmlS!8%VOuSz9wpLrq{}X})!gP5&z%k!V#r+k4C} zq7F8#cl#>4HgaLn*5_ZROqpvIv$AWA-R-pF9lfdS4?ZYzpV+q7+xPJQ0&AfL%}pj* zg8SIZcI;MB-#B9-&jm{X+Y61%qKh+LFFB$nGNtnO5zEe#swY(?^6 z!+8C_FVnt?t>KX7+v*cka%nG*dGh-`ySARFlz((Xtog$it1vgt2^|?1f~OxTF>aGk z-`vuX)-<25Tw!MR#B@Ia&0Q~da=KVP?>xq1z`w_38V9&HIJOD@4vXLKU%Xy4Fi@>%>atIdJ_;mX=nH#iI&*cJ zPNkjA`RVV!esX@f?b_|P$K_4Rk4S_zhd)1jWn0+8h*|BbzO%)Pq~-TrwQ9?+mfKTz zUjBdCiR&jzmptFXy6&Br*tWxuS8$u~8yCK~8!qYPYgcFe*P#B->&NZ)<>uE(SJ(aR z|M&9tWBb~lf9os$i~s-8vH#D<-Pfm|PY!k3m>z$*`NYySsV^33T=s4~)v4-Ic(S{! zELF~Vo@!Z&)~~ZUTjj(OGf%gymElrm3zXKJdYfPs zTbyxkk|<-Jtr6dfUk>VvyMj0FSyknA&+G+P2%CGEdD=|XyKk0my%xpb96Rx<#W%x4 z6T9EeYY$n+8fvf6%X}g8h{)EMxV_6J++6(2ZVj7wfX(h_w=YOOS#sd=qT*+2oXUDC zH+#I!3z(%eJ-pWFw&0P=o|zn3lUVayZuxiY*?x>=zrubEg$}MObFW;y|Kj9}SLUo$ zX|5BvL)~^A&X#C+8Chq2?by${dvZ!j-#Z*vB+jt(aM^Qvg5$k&lXTg;RtO!Mc;=m( zkAhBx@8X$@_z(2m=CAl05;3pas>UOqy|BkBDbCq1X7@htsIT9Y?fw^3?s%49ap|za zs*_@yYroWPw+)S-FLxrXWP+pisyi`u*(noJ*PDF~E~->aXxBa`QOfP4Xu_sC>-ZB@ zY1KpL{Bm!kuQiDEInBkdx%S1;$x=^MHqYTceDta<)7&7pr*elZ$cZ-4gnDZl-` zS5I$b%{^jr_jXj2)YUe(X;Kc87ct)TOG&$3ee1(zr_0mrT(9{XFY=51dSQO~=HAD1 zZq4U>s6Tm*{yoLJOYhq65||^Aes|;Cc&n6m`xfl@{PJ9XZ?)&&$CdtewtIwE%|GFk zKKI+(J8~y>t1;#rS%3WXgf$EODws~RB!4_8c;d;6go*}l)6>(KnvX61qcG`aZnd&; zQQbW`{oj{^d!Mr&ujnX`@6G?`sFIv=PF|AxcU*Ls*s;6?`V}&>Mcmd@9xW?uQ@i-{ zywI~n$u(b>N66Hi?*9AbbkM_JJFnGL+>!hDCjQTl+5gYoll%Ab|Igj`_y0be|N84! zqp4Q&BPJ*5C_dMcjnJ-|c`oC7yilN^lS_`k+TL@k?k;WZea96k8J$=l@+oUkPpf5r z$DB({H)1^lpI1(Km~he0Fsw{FE4i-eA=B)*$jIW=hdmbvu!=`4aMM^UbZb_CN~+ts z)+c9NQl3mJuQ_Dk_E>a|qvi3WJ(}Mtz8Bl@z3PhUo2xw0M#TIo)2d&krd+o@r@u`J ziT*q3B*)aizN35rpIl%2epPdGnKQ3QBS3Gn@X-yX4qmE)d3jNy)iZ)sy!n%@^W5LX zEI)oIRE2gLHf!J7(<{wTbivVm!-4bH-iHTz9GR3Ds!)0Uv~a5UqaE`% znLToP^UUo+#9M2V-1{7js^vZD&n>MV&1`oNX!dbCXkKl|l~s1pByFy*sjF??uWvi{ ze%F2+VVj@s>FSnp)a=bBvw(~LSG@@O!m>@F23DEBjmv^dJ%-y8e?pYXc* zHvH?G3(qE=-nNA+!tGh!)9W|=pZx#v`+txBJp4W@+dk~j&Bprh zKl9ZVrdE$UZ-5z^2ZGA^%yRE)9PnJ%@lLs<;_<7Xk55kabWA*&u;^T|NU~&_mGY&tk=mOc zY}CEsWT^i8-O5Kb(yvv&&EN&Z{h$CQF?FpBt}qcb>M|Thws7txUBr zKaML-G1`_Q(c8qu<|p0NTg0&NRp8|C`|heDm*Q3}(dAos{j~ATr1BYC ze%C~sWNRika$n55&&YR)V@9OGk0Tu&b$7Uz#}+g`6^Yo;l6sg!SmtFOLmI>0@agAe z*VQUoCzYICXgPaR%!Y_fKGT;^IUsuDyr9vceP1OnEvcMqyfXh;Rrwh~<&7P#t6rY! z(cw{JU^l*z620nOCh7 zUhvB3Z(ZznM)xabBEKCjNi_Dwd=*M8$&VAaf9?1Cb@hU!VVzeGa8KUW;=#0Ovfoc1 zcaurC%S8MhwdqvtK0R5%Q}t9p=nAdqd7{ftN1hEfeIyqXb@jlGBtzC!6S%rUJ=tu! z%w)umgvTGfzP}}|r1tdBkFxcjr_7hzCcOSyl|J{!qaTtJ<_LY{{QcyAyoNaQy$0?b z&Hd@~!(-m{#-4v*{ej7D&KCK{Ygp}cFYnkaV^#J+RcXQRHUGOGw%4;%eAvq{Y5AoO zsgoZ6PB{K|rhfUZnD|sHwwQEVm3K?Gq(6SeTow3I&Wq;>>-}r_^&e}VetYm&P~x`P zilT{?ogx~AuaC{2eMutfkj;m8>09GP_#bubnWE^D8R>e>>R2HAw-x>SzrLP5t#__v z*jk~7=1*FGPuSTvJ9o94THg9=ci0VA|KOWaa&Xp${PwNWoPWN1_^CU8@`|X2ZQtY9 zZr}d%Q)bMgPjBb%ty@?5_ub+6f6IS8+yCQkeEq+N?d?&j2dk96EiNm#Aey-LY}}{7 z;5VJSvaWsF*xHo2X^FCV%%l|#N22B^Y3Z=?2OKcq?+kO_Ba`yoRLbJ>%Lci4V@nZ5q-b|$uM+>?bXCilHN*K2ToXV-}yg&LLcXZwni)qfo9Xv$wIZP{vR z+RLW1S$(tm*0qOc`wFjMT>I?<%V~{@mC38yR4vW#@tMo-jGSaP%jS;8n~8V)C#*c2 zo*budYrD=aHu#cj#jQp9e*`zyuvZJY#22w-Z!h1m=A2)c@z)0C8M#(gn?uv%4=AzZ z{4KU*4_^07`2ORAmv;#`S#P?t@Ya&+3ptPNs{Q>_b@$z~S9tEJ@g_{zwwxiQ^I@v) zPQLj2*Iqy0CATff*tU}~-zOtf_tf-?ij=&4dJk4@mww)}M&tF@ZFwtl8SLV&|M^iQ zxjrGH|LAg4qmC1KZQoD&@+wOT&g|2=5WDR0v2f7cE8^1=V71`^~`}=#QOSX&4-Fn&YvX8u94-szqk48=0ARz z`TXhYe)~Tgu6_L}|F8S}_4q#z*YB_Y`KM3BhQB-J(4KqSOwGHpH}3wsYocS7QaO9h zN-o!=FQHbKL}t3mgbIg-Zp_=Abv8L*uke`xJ{oQ>>#V<}O1wT78ZzW(9D z(%<(MTd;lS7GSq{m=$gCNNlmh+!Hlh`IfNjpWHiJs4(o%JqD8x@`ViZ!xk$&KD}dx z;F*pdyA9I|6`AaI@9j+4k)m~C>$5%vm5wiI%g#sCdUJOgU!E!{t$g6k;xJ+R(nY8F zqEpz~tc4|;0~__)Jd2X~gwDKUOw8Wyva^!^#tp_(5l6W64}G((&paqC`A$fJnd7+C z??W>l6l#4fyTAXA1M`77*DDw9tNiR7F?oiDe2y*-1p^X(ayJq2|gAJ;{c{;60q{cyhfREcHJ=NZ;; ze$r`J{_^VoCtE~azj3zq-ak`aeLJ$Lpv=)kMx^}X&Ae46x23sEH&5$`c+PgKId877 zOGn$Ezyi^CDc)sqO4eV!8OX+TScXP$?F~bHSgpWPX4gjk<*^J{{Z`srX3E}e|YShepgC&xId7rVYnoQp})rPCr)<_5^%dWX0 z<9>B&+_@M}hOXtN$%l1IwR<0%O^n+$h)z|L^hJr%xXq-o5&mulD!1 zpH|oZy_^4xzkYjM9)Egt<6fH?+p@Qsw5}EDIp!v(6dt0fb&O}quAn&_D?e`&T~%no zUGQF^u}fjK*s5(#tcfea(oz(+xMi?RMtR3UpCx;%3X)V$ozyFtzWcfacbTiS zr@4h__r^B`c|6~gbPRSMxvQZ{?&HWjki0|IW5=7v z>HLpp*Y2+9v8?E+>GrM)SpDp{Xvx0wX$=KS+$vI%FL0Oeq?UD^Zn>PO+fo>`F?XZ1 zynoU*9_397qxcLit!8jpK7ZFX^@jzP5u%fBNiGvG?1*ZcI`%R0&-KB^_q>E z_*O4C#I<2%;a>UKii>ua?~FaLzWy!${}&N6Uw>1)_wUuq^8Fq1KT~%#1*?VXcmH(X zJkk1}aAVW~){2&S2Y5fSZ0~)}6tjT)4@=GgHhX6N2YfaR{s$gg{yE5Symo>8ME(c6 zmJ9S*uT%fOLfy!}&bi+9&ikn{-JjPd*airQ?_0w{$NA~x^YwGuZdnPFUz{Gn& zUb(r*L{1gAN3S2V%Ew=S`+{8~DY;rps6$s`mU%<=+DF$^eH;G#Ql7pcckXjRw@l`5 zv)I^=UF*-={&Cg46TQ(z49zDx_817=R_nQ%*Q{}F=e4$oS^C)vvu5w{=(yvpyiqBV zJ?H4t!oB}?JWIOrvzHqK* zSjAyz#ID%C*>PLIE4y23OpPWPOr861!vdxwCzec>P;e4#s4~hXYb=^*)*TGaB}mM2Lbm>g71h*ZxCcuOU`!pexKOG zCviaH&=%dC1mR`+U$Vz<|yyYH_Poc-s;#_-=WjHha(}p*qomz~l_ORWUw?o=z_y2Du z4zEP|Vywa!=~Yc(UL_=Z)%Rmw;Zh5c_=u_x9%g&^f|M;%tk$MYQgT}2+{Uh*WE8!A zfijcp1pnlkACq_3aO`~f?YV#bcl)1L_y4`T{$JkXmCxpI-q`heW5YX5gP&iroj$Nu zEnvFgH`V;}mgFRN8zl~#gTL>7-G7kZzPD}H4Q}ZVq8|#}ZR<6;rPCQ_R{noqDb8GQ zee!zs`}5;BTzajtdv5t7>!2-D6YsuzcCpmI<*1}ihOgK5`FbqL`~43zT=o4TEHBr? zA0NE=nDEByr?vCj^S9dlR|tO^oIKmvOVcEfi$(46uiYoyW8|g=p7YRQ+3vorF4(p8 z+J^0wPiHZd7f(08*3B&=F2pP9*R;`5oB6}LpnbLS5u3Lio<38$=yFfR?>AeY%_%zR zKW|z8={m~~51*FT|NVCRf7#1TUin|&-ac-h@#yjW7w`YwUHrZKm|=d&Tl~99+sX-*@r^ znui^I>TFjpT(>o*=1i{o=LvDE*L{fo)w^SkKBMnxOj zS9jz0C4RTMc6+(u{`-GlzAQ5H`m#%N&c-#9XGkhcY~(l)(fCTeYO~Vfm4CxOv`y?N zR;?q&qC;D&o;*Hq%3CsRFp_y{$dxPH6&SHkIt{dLgGJUqY{WHk9&G`RO zMm4{xcRQy0KGM^?ADvnwZ*rBp##NcCfdA#(Yf*{kZ$JHcsGVId{~>4Fw(l}&aevB; z8C&>Y3xrkpRaH(4U2S%D_Gj(Bo{iy!_qBGvx!vWmW0#lJu|qq4R5-plp>B}$y2XE! zzj4sjw!gBQtQRYlt4-ip6TWw^t}J(GXy*HgS_${B6<+Xo{V;KL{GaFR@BjV&?@#Ru zsrdg#-0i%iZl5U0_U=f)lntyo>z$gS zRW5ik^A&x*YjF0MtjW8@@>eqMXU$j58JA%&A(Qh(S4M2wWLG$Ytxws&6XS0CDRw(M_53N)ZJRI^mHE#EO%T;AaJt-<8V0OJLcw733X;+tUItW@^VIfeewzFovX!qxddz5br8UE8aaP|Ft*&FAWHWjH$AjL=`WC9~taxNUyW-;PM!S2)Cy)DY)PH0mJNH62qul}F!sFRr{SP@Y zc-ows{+(aiv>@jCTkGPI!YYG< zNnd}xjsLapuAg6ft8O2A`*L>v-+%Q>ewsgisQK-n{m=Q&Qhz*LeZBwZ-TSfm*XPR? z>*TjKemN!hV43a&GiHucJDeJK-x0A}!#QQDmXEIIYX+O8tEMjNwt77OqzA_ZPp$UV ztJg}%eHT2`@P5aKNuE=W_Uy{PtH$-IjY06g{knf^PHs~1ymVxSYsmS%X?gGDyxr1V z(!#G@+8SUQAaTgZS)rkUQSL*FJs;D>3qJf(!IxvJL-RKN%sRc-J+$ScLe-gMftfCn zf|+S~x34OnI`pT|R3%U$ca_unDV*$k{f&%bimmRJDXgto8em!gZ(BCGclL(A_Ou z-!_JNGrn~(*|k~AW{tx`#o8N}efIB&$$R9r@YE?MUrEW$VQn*4w`sAPe&@K9=cwJW zQsRN1`=)mruiE#DOtjWL5xMzmOpNl<$;fgu@_Px!W?D~4z&B+@=D$+QVbl23YwMiO=sId+iR-x$bUPnQa*)E#dzMbv%3Evt=Gph_v z<*50KHJt@pe}FQor-cY>N-OUhGVB%UZH-qKWdER*o|~tCzA(b}LSNUE)1!_N<%RwyvJC zLSg@`%Iv@EOqJ)BY}QilnN_-C<*SK8Q>V6Q#=ED!yrZRhp)7EV&yEXT{p!)V3YLU(#sFu=(0r@3TsZJjY!Y@0`4jRdr6 zq{&*2jajO49?jwAPAldaExr?9#J#fV(bp?0m!(}hFga0sdt@BLvbByY>P{6ey)v;Q zHb_nC#I#-2jnnH@Qt$n*xb*Mp%TMX+{}&Yh>U=U+n}2D#<}wMpZBKrDyW<;JMoOQa5?_@5`6Wkmr7KHKxkv|MkV|XUwlk4%_{{ zYzfP@!-rDl>#^UN5dMVy$@7maTb>H=W-@gAvTtDCLx8=Scm&N!0Dlhx~>f_n3Z@*7pZRa0pDp|$Ptn6o? z=A4)KZl|ijRLdl_3|nI!M>p1nBQ8}e!IyuXaD6*3(xk$L#nfGgiHQR5; zX=97|RWTJ-x9?83eCIm<`R%A%aSiUNX-^trm&Yz=ofWqKJ>Q|ZX&P@beJ_XZaxz`a zXk5%*FZ0>!(&Y@lGbUU;XL=NbCNfn|zb?nxd#%S!!}e@m-nQV!IW3h!&Dm9aLaGz4 zUi6U`oj7gTraPMq+?Hu5=Vh%v*>%a&p^fQb*xltG9mkSlmqnbulH{lJ#7j$9wxP>D zOR0R}l7n8M(}W+ixcEe@?IJT{XQdMx2fXiyi*}A8pZt+geEzw&8SRYY|SHkQ>3KI%*)(x z*Q9H+WYu}QCah{ny|pPn{GMZr?!|N^m&h=lrnaN|H=YSCh{$$#~1!qM3qN~3y-TUj=CV$2J zil1M*-`jovzMR)bNBQ8w$d5DrX6GkvU89-*RQU~~+y~w??#0_wem^&Pf6*sOgX7%e zok8atERIyIn8H;uImhqYyszF^#`b#epA}pd^MpB9L~Uf8*YDNbDRY6r`VHSV zDUS!gGIw3S$hMhf>Enk_Zcp0t#xgm_;lQ)wyDuB?WS{ar^4Qr;=^KxR($rJDYc>5B z9B^A!waoD9Yen@A_s-mS zma)(`&dk28=7G)S5ZQ_Ul=Sb<460lF?DNCNGX7Uof6L~)xf*VHKO$yxeeuuj{~4v0 z@7_Io{{PHvIs1Q{u9bhkzxwlsFUB9HPApizM(hozS!2#N_Z?HX0>m9peKh%Ao2620 zwxKWNV*AaO<(GWqX3gAkp{L=JZtBj;AT}3vL6%Krnb{j%Gb7F|t}&Y#yz7I8i|VD< ziVr3|$XZ;nSor3y1;L_kR1JF5jCP$-y`pz|Cg0BG7iVv0yQH`L-@_~KmM)vUzJuRT ze$)ILvuD43#K&NclP9dd6yM7&9v8}d6~eY3%|bhpRsy(dbV6l z-a>{2JQ|a(KbR$do!i&(Y)_!yyd+hP#?YFi*FFg{bNwf-@LC<9Wx8sE(Zo)zUiJu) ze}1nYaaz?zT|Icf&-<0;YUQ)ehVJ*?eD2;j-(td~u&6~Rif>h|tZD3vyFKk%^>Wrr zyq-$NQ`%~om;;YTYArKdpk0s}*Pzhu{Df_LO7L#aYRCPvGgtQBdwADF+0}cp^^0{( zk4*$hTIHYXc6>2MxNUvGEy zlr__ME?%=((w4^MGSx23)yLaZ_ucA~H_bka$8WAztG+R-w)WS@e*gd9vV_?mah(Z0 zwmX5d)Z>{^q*mhrm7@4>Ug{eT&r7)OpS*9wfs3bGJNC=) zjG!|-PfJfZ%M`ra_w!isX5G@t(?9R|-pg;Aw}bWWt+PL$eS0Uqe^dP5_xkt$Kl^le z|JLX`HQ%1vegC&PKFZ$q-;Zy9%in+dSh;lyw~4vC)2RVW)%IR)U zkkP?s8&;WaSa5Q~Ok-A`%~F3dO;XmSCO1nbFOyumQKNI_NwL|HkDX8R_oi)M?{M>< zz_(L=cVBw`p75h%&Z+Dy-S{OZc`ltu<7v~G*SyJ;jW?s}wv3+l&)qBejlX?ODrVZ9 zD79>orDRCbF`1+%Es?W2)tV;wrWP@1+UKV4n(Cm~v1!G9OTD1NX?xjqvKlqBFBDEW z$?`QxH|{k{+BC+CE^k%eFnYS&bXdt5x;A2si_WG+7hGiEe%{j^oP6S?jx8$OdMf##2mM04K zOX+VgNb_;tCa__7WR$no8L3U;YmD~VJZZ_l702SQJmZ?t$pw*34XIbBPxQQIX3?P_ z6gl0(_<+-lAfF7OfbUOVX&n}MsQpFMK*XV=?ZT>9-GaExN>M%Mufp%Uen|=oMWvqQ zVLDtJAm*9u-BK~5NpZ75SkD}`$8UAxYlMsBcg?o{_v_2|`YnGM!_RbSK9$7JCz`F27{nh4&PnJrV0^=nSl6M&=@SvgDpRpx)@#eaUv*o#r^Icondf?J z^{L&@!y1@n<`(BJ7vHj6_N`u>j&7f|^k=y;&W<{>x;uvyvu~etsjfMkx6N1L>nGDQElIPq*o;{>-?QGC(Ze?5Y}3(ImABli zk8;d>^Y;6eLs5bOyOK(jvbP}*|y!9^5}5>%MUyK z=S*7uA-64fa^oBGM&Ve$Z|iRB@9+D(UcT=8{BNgowlDwpdH=ih_V??4K7X8*|No)A z{hsP6QZc7|X9~`9RX)@4;qNP>G&hyYRr$&@7<6MVE6nnHW?XJ|>1@)snGFJtkKesC zo~v>7p0d>?ooKP}%^K~RPq)sr5DgA&br(|7NeoI^{6J+h!>LIra*{K|PEKQau+T4{ zOQF-#?beBg{H6sulmDnKDtCBjX>-p=@0$Jh$=Pw2rGKr=o$}G??}Q!Zrwn*j)~I|l zI-@MOiDhdXFYmR7vStgj`<~sK>k?N~_q(Ka#tqi0(sD&(-AZ1z?~NTYyVHaW7v?YhDiPG$e)1SXM>JzS^{CR?y~z#8UqQ zw>B|##rQPMv@|x}Y~;kKVXB?OwRDp}lH=?{Q@A$0a!@xr6kgD~gh}agubcD*SA$yz zRb0;OaGPg;Xa9kvJ}r3$i#xAHFVa5EIz`Z=jdMm=_WOX~EBcq%BDQ8RT@{`?^MrSV znQKM)%5MEBQ(fMrEl=5hFI`3Ys9MD4Q$34UTnJs_Df?8`CuOFx>8aiKMW?NJzU;V2 z^bGezGoi0fdN<8mu4MX9^;T#1^Lz(!BW^?Xou6;_f2ayfiMY;kV~zBrMO)XJGCis5T-_aQ%Ou{@;n)TlXjL--q@0@9(!yl@Oe@ z(zSig)3DcSMJf(wjxCqSHO)5)YPuD|CcLaC%WdxJxiKNze3XlhEQ$-ui=Cq!xn%F*Xu-HqF3$hP04i@!54tcBUI2 zWtfn+`1av6|Go47d@DZN{*d>%_&L8@!LQ^#KACYh_wz-YUGAT|&TV>eRW*0F)n>yZ za|HX1g^RvFd-kARl3!VWqHvf^htt#N9&Z(jG?b@Ya@p}H>BbD<8^QhymrE+IUs#Yo zH;hH!;IiQi7?&p;&lx%7!U#A3uwqIx#I(Z{=z(_h-(sFD8j|-&z&rAfhgG!L-P|uU&n=+V0M1 z9@j9rM<-28Sp!clYHilNQoLP8sVvFExG2T#oXF-LxlFZI>kH-C(`F@@?`PfabI#$w zw+k$HRo=Kw%48A>Q{@g_pV}hc<##!AmV-&^@(ei<3EkI<-by|N#$g>nJH>uQGDS{J zkDAq?bInCetS>EL!8EoRPA7~Wvau(mXw3-qb}(w5Hc!)Ks)*pskPw~?tK#1uvpN6z zt6P8kll^xdC9`i!TFGI#kUe7VxqqG8mT~e%th0z%D4u0fR;TpbgZ=2i>sF2JwZ)x3 zSSMW$jG1yed;dDtZ6|nT4tzbpcvUc;{dr~L2mbC?HqYjy@8K8!lvo;ltcg{3^4bZ^ zHH`BXyj{_xx!yUJuS_9P`b)ut$6b~&@h4b>Z~rN%ewQAQzyEywFaOHlQ(x?{TQUEF z|As1wLq$sSom9*(Dy^P#-s=yChTzpFOAU|8HFwOYN_}7cSZ#mn_FX)AH$MJQGhVrO z{<#Osb}H-bsavwFS2p=Vd0+LB+Nj{JzbYU<~`kV zTkiRr8L?Kx@{ zy3t_LQt|DtHnh7vlSp37doX2UXB8Vy@0muKQycH?J@ij(nO3*M*O`j0rJmf8%`;=B zMPv$VrgR?fnzZ(GUa-loMWWmxo<2`(8hT4_OurT_QNnorm8^SNb93yj#JxXWD4fW& z**(9b<*cjA;=@~Pe=-Y z-QS@SK?+`NJq67hrCbvyb^Xe3$Xwf>{X26>#NC|&-8aMRPOj^#96`YIWZtvatOyPGW~ z!ST=LvJIS4XC{UpdHirs&W7|2{CrsxCY%qMZz0A|d1ULnTpRYromb|i{#|o;yL_jv zYnZ>CEXnoWb@8i5#ncnQ{&P2OJA3QkCFR>uJO}J|PFhubBX42ntTitt z9Q+kHwfJYnDZ_t1_vcr>O{*%D4rQM&_`#=pNlL*X{|!}MY6X+HXB~IST|9Tq*Url_ z&R(DAid}2_ed70b!DD4zb=npldw)#gn)dMfpDq!Tr20)C7k^{#>EFdCu#oR;thr(_ zkBZ8`-P>-`Te%NJ3d~o-}nE+?bFBKJ3f8MwtV(%`@i=;eNCVK{ntZz zIlDa%4Q^?tD4Zr!!MSbl%t8af>Fh$~2hmY%(jDDl%0X-L-)RpcS zS-VFr?Jl%8dbZ*3EW-mcCWv&cIkjR%UN(9pNbdEhH^#^YO`czsfefHJzY*%x3N>ZKfMOvB8t(*4#7OW0I@LttxWK zM>INKQgvUq=C*?W0)mR{=2>ob*R;%pU1lwemQph@GBRqdbkX`QDXn~yO{sB$&S4QY z4W_%SKZCMQeb)1s5+uX^Ek)__#FnPU0=Q?=uLTy>LSBc8|2@Or8Zi2A>Y^i$8W{ zcX`}|R>@s9p3^3^9WgnR7U~mnZj)4HV3psj)J1Euj+B}v-wI4=Fjr9{0w89427t8>zlJG}kx3r65Ocx5xJ9%Z*M_sqP@Et}HtaD5)lwSH6-}X%QMs=f*GCOEVlJ6QYp7VnzAM=`x7 zuMZwm{g=|T+`olWq9k(u!gU(Kp|QJH9e?)hW8C}uPy63*?ccL^vd!OPX`enF$-6Nt zW$G#E%QyViF3r+Bp_aTUiN|xPM|P-5pw8Lgs@qq8l)NwG{h}#+dtI(u(22KdPK$1} zaXz?`zPo#E^6Sfa1yz}EIw$XZ_54tw{6!;4!8>th3?_WZJ=e2j_uZ1$<@4kJi1XL~ zs6KeR;=$YS=kxy`Jv;wTxKZ`5f4`pb@2as-Zara=mS?%$C3tiJ@*YqYd4WT%2Dukq`7=5D4dCV3v38Mb9>T(sY& z2d90EwbUcUf_k<@9w~jjByyt+@0mn~Ig7ZGcP(Ww{&h7+qIFL6zPlepZX7T^{`kvT z|L9^V$pfaQ#)g;I?~Z>O_-)J6-P@mDd+?Cc+^p@Uu%)u~+Rk%(QqmqN9e8sk`t{kf z+(O3QW%`X>Jj|*3yV)Zgo~=Apvo^f`8iT9eE9H=<6E2%D&Rjb6+JOy6tEO8lh@8Jh zBkiG$@$`Ad49_nub@YjzahH`VGUJI-RhH6v?(DNmSj4iQr)-NCDE$rIUGI z#K?B|W?Tu7?PvI5@=WgVy}kKWLe9n){0xMnE(nWFT`}o_?q<=T=-J%8UP@jUf~NAM z&N|}rBxL8y8o%-)2n9vxUJLe4}Y~Q|Mao8zu%fmpPl(nWT0fbqh0v#b{@-#o97iK*rp{{ehYni z!0Os^E4Dw6m}2=3KHuf{eAC-(`+&vU{*FNkywLe04(o`eswGrA3U!1F|^cM15>2O)pzy107{9p0^VL&L z&%g55qv_Mj?VmkOj;_vy!v*Ir2BUGQ6>T~l|>V(B}R z9L={L@$vb*YKv)FX>+@zrr_KjujE^+4y1lG;+=e|XWh(@ER|&ff{eaOQcq`^KDffz zTCzNPRivtBqL=ic2=h?xO!3g48rqY)B~v(4i-H3ddEZ^xCCIU(N6l0->h}4!&Cjbp zPyT9sB>9(G{=2=~_qoSS5!ZBc%V?Y6r6R1!yHxn>-PPv=7HzEjDS0hz?atE8CujIg zoPI=S^}^~)FXmhd3DUMqzA|A}WxiSQ)jw>PCMdpTf0CiK{K0`Mg`Crcc5yK4CU&k8 zTJ0#!63nGFJ?!m*r3MqvsD58u<-6)AkIyQmJ7qt1pZ;=dRiBIG1a+w=Po~{ka{5UO zyL?kwdfx>v_019rFFczTAF2;ywAy*|#F696-wJ*>SJ%{Ol;Ys|#^7_7{x`{u+;ciz zCYNpQoYCQ;BD!YdTuxr;t8XIIgqWk%uJ}C6^kNq5y{x#fQu~@+u!p2GB=IzEMGEJ|;85+OM8FSURpslF*r)^!LoE+NC0QbTy4# zpYqIAnl#hpia$?U%7$H+W(Ymty}kO)dZ)*;^jDrveG=NSQ{b-Eo)1MS>o}{P=08^W zX0uvv8_)FfnQKBn9WBj!W^?ZECbp+VPsMj~6}z&V9Q^z9Z{4BKC!LjNJ(Z1~FSpLU z^)%m`6Gj|Iw0cZrmj6$TT6_EOuQ|W9*0MBw(@fmZ_4s*V>de*2MX~WL7I!YL+P3fD zqlepUx7L4m|FQc2uTQ_Ocdh)}TyT2l=a-I;J&Vq4sPS=Gxxr7_Y3J_i*YksR&D5@t zbO~qw+?XC5%$2nL_x7@%C(0(5Z8rKcrzeqP*77AYCDo&rNndn0|9779lzDrC=k4gf zY+0FQa>Q<;@i#@&tXZZ^%M!m_{`u|OH{&n*^Y8r=_*PW&fBv`Q<^MM4{}Hbj{qp+u z-^cvovFE3Wm@mHg)b^554!`LtccBQsqNPQx0*a}po~_6(RPb3jM{H{4+WCuZ5}CSJ z$XyrnOilYL#(2a&mYDcu>7OIFWVWp%~n;L^(}B8MaGKSyzy+-wojQFn{v+9i2O zCncbG`N8Ug$DD6u{;asIKQD2wzmTg@{=qeS@*E8|6{A!3vrm>3 z7uNpr*ci=>8U;_}R$m_tS?T z|E?2%&Ug9Hb3J1pIdg_}i#O|7nI1Hlu6$z0o2jLo3)V{?zQvY2lc9rIKZ?0d?iP35 zBT)v0Co$1svM;tj?sahbo%sCtFP_(T;@6$EIzB&~b#X()g7xffclkH0owxoMi=Ayz znB?b6yTt;2H7tx`Uu#ttHYfLV|80lYXC=~h&o6poEq(UDPUgnT(<~bo-bnUIS)x{K zu5fwkX6Y468VlE^@qbrPy}QaZyG`xKvDdaXFJdhkLyrh==$+wo{FtKn>Fj|2}+K`|(coy>(V;XH?G2+;G=2CGJtos?hHtCxX@OpI;fv6CG)I2>ycU6*Xm@j^NOVWR!znu zD}q-pyKLmyaXn!f=e$Gf=FC#`d8G6vaHYFNZbs&c)iREmNgT|p+Gc8eJ3P@o%k+%X zaa#vIwU=9&70e!m)D}4{(Aiz%Fi-0F(_2-meP)UUC@JO~+hxKbb3s9950~4VhUxF^ z@2T9rrfs)6GbVPAXn%L*LXiVs%tU5xa_H7P#uuBM(zCkgeBl*=11ro*`EDD{HodPu zO;|WU_ABQlY263P`m5&)28CLQaxXqsw%UR9F2m}gvM#yI(0_?O+tU-z9eI^H{T1iS zuevGP{l$tGf>RWW#UCEl7Czv-##=RY(%PzBp+#pWJkTziD47%#c29Sn+1Kg6FSF;& z_YEqvjhuENF!ON@+iKndJ@IEsPQMFxY)?L}oua^aW~t!XlfNX6UAKRC{J^^At1_>v zPd@*v+kdfoLBiG($x;>T7F&iLKb_t3R5Qv#LC$XeVg?8IGZE(-GTOf}yWd*<+^=iY%&q5j|&StuI=E`n<6_d^T zdL^%a{Gkx}ZgOR4*YnB7hH@M1k9-Z<6VS?S#lTQM-P6S}x?4{=R#9 z_r3UskMlpi3g@r?VZFcZ|D*2sJ2jubimd1V_;KS&2DgIC1~KOT#~swttsW}+?@aM< zTefDBQSq%KzLU0s%PjM%^`cH1oPKAYO&81eQ!lrlZ6k6q??tbl zMER4)d(IW!ZS4NoB_pIDJge~3vM*B#Rafucme*ff`fAaZq8V(uF9e>Q==gLfz=>Ju z=~asasZ9%9Ⓢ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 z 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⋘*B=&K#XK(i2y{ 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 z⁣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\`OMCpVD*Y_5Mo`n+@t_yJ^iJpziP1dVnk5w{ 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 S>t_ZA1_n=8KbLh*2~7YVNBA88 literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/mandrill.png b/examples/shaders/resources/mandrill.png new file mode 100644 index 0000000000000000000000000000000000000000..02d058eb0d0d055c85c42f08ae2dfb34709642c9 GIT binary patch literal 197452 zcmeAS@N?(olHy`uVBq!ia0y~yU{nBM4kiW$hS?7-uQM<*FnGE+hE&W^`JFyFm9y%3 zyX^b(JD=Yx-s}IqHtpxDb>Gr%^)MSqY-SM4*5LA<*b|}Y;pv?vxpCnGZbO!dN0_>g zGCk-!I79Btmh!7tpRP7qt+n_3o_oI^|Gn7#Q=ne_{AcF>m*@X~k^leQ^7HpAp1)Z0 zsi3yDFf*yhNcY1Q9j*I6zWwp9|5UiP_DncE_qcH4?QKFQBlgCv)w*)%jYxvm^Y-ZI^Je#IKI^h8 zCC${lS#sA=zDc2LNesI~z@Nwd`vY{+lk)UzZB!!fE}nb$=){eOPM+MmyS#n5TJ&AH zW}~%1$wiqN z>g>&(Kf9-|PiEP<^|PyrNOeK_-ivR_t1r#}_t`%Cq|l?qKMOv*|NqWDE%+tF$pD2t zySLh!S=ksG@2%Yv{?cTB<mA0T8Z-gzu&%R z=&Pt^0HtF=}D2@H*VZK`SNME zc+BmpihJ8~tJBKZ)IZ#vE4%aRzAYQ})P2`W*?DEc|4T=^m#xa)WMpq1t{YxcSNFWY ze)8EOi+=~%_s@)k7ytiH`d3YL+8Y#lh1bZT#@)(jj*Fx{`;dzAk(in3DXs&}ilj z`x~#noDDE|^7zl~+w2>jpID@M#Fk}Q_ExW@Dy_-~ckb*A5c&79zkZiR_0LPMu7)k1 z?A0E%*2~}tx5?qwnB>H|W19|MzT;P>@wK4#?uH3}eul5PzdYMk{`Av6Z3mteSF4hq zXB4Kreeu9V;fO;=Q0Vl;Kk_vn9zN|}&rr7G?zGtRfme&xhMi2Cd{^zrkIpJ(`~3zt zUz!Dq+`4`H{a3d2`+j*@OwlRHo>;IWP-yz}X}YntmUfjdzn1Sv`0?T2ug~J)^+xz)jmEM+F8yoRCZ&#EDI3omVM4xW^odR#58?&sI`{&|IVjR#J=K5svr=XfDQ z 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