diff --git a/README.md b/README.md index a7ee07e..ff74a93 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Manually tweaked, auto-generated [raylib](https://github.com/raysan5/raylib) bindings for zig. -Bindings tested on raylib version 5.6-dev and Zig 0.14.0 +Bindings tested on raylib version 5.6-dev and Zig 0.15.1 Thanks to all the [contributors](https://github.com/raylib-zig/raylib-zig/graphs/contributors) for their help with this binding. diff --git a/build.zig.zon b/build.zig.zon index 7830a6e..31512e1 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -4,15 +4,15 @@ .fingerprint = 0xc4cfa8c610114f28, .dependencies = .{ .raylib = .{ - .url = "git+https://github.com/raysan5/raylib?ref=master#bdda18656b301303b711785db48ac311655bb3d9", - .hash = "raylib-5.5.0-whq8uExcNgQBBys4-PIIEqPuWO-MpfOJkwiM4Q1nLXVN", + .url = "git+https://github.com/raysan5/raylib?ref=master#f83c5cb6e1b3462c9b723c0ab3b479951aa48458", + .hash = "raylib-5.5.0-whq8uBlJxwRAvOHHNQIi8WS0QTbQJcdx7FbjSSOnPn6n", }, .raygui = .{ - .url = "git+https://github.com/raysan5/raygui#1536ae35c7b42d863135f4181fd2a225e531f68b", - .hash = "N-V-__8AAEp9UgBJ2n1eks3_3YZk3GCO1XOENazWaCO7ggM2", + .url = "git+https://github.com/raysan5/raygui#6530ee136b3c5af86c5640151f07837a604308ec", + .hash = "N-V-__8AAOQabwCjOjMI2uUTw4Njc0tAUOO6Lw2kCydLbvVG", }, }, - .minimum_zig_version = "0.14.0", + .minimum_zig_version = "0.15.1", .paths = .{ "build.zig", "build.zig.zon", diff --git a/examples/audio/raw_stream.zig b/examples/audio/raw_stream.zig index b540ddc..fab963f 100644 --- a/examples/audio/raw_stream.zig +++ b/examples/audio/raw_stream.zig @@ -1,17 +1,20 @@ // raylib-zig (c) Nikolas Wipper 2023 const rl = @import("raylib"); +const std = @import("std"); const MAX_SAMPLES = 512; const MAX_SAMPLES_PER_UPDATE = 4096; const pi = @import("std").math.pi; +const C = std.builtin.CallingConvention.c; + var frequency: f32 = 440; var audioFrequency: f32 = 440; var oldFrequency: f32 = 1; var sineIdx: f32 = 0; -fn audioInputCallback(buffer: ?*anyopaque, frames: c_uint) callconv(.C) void { +fn audioInputCallback(buffer: ?*anyopaque, frames: c_uint) callconv(C) void { audioFrequency = frequency + (audioFrequency - frequency) * 0.95; const incr = audioFrequency / 44100; diff --git a/lib/preludes/raygui-prelude.zig b/lib/preludes/raygui-prelude.zig index 66b106d..8f6069b 100644 --- a/lib/preludes/raygui-prelude.zig +++ b/lib/preludes/raygui-prelude.zig @@ -389,17 +389,17 @@ pub const IconName = enum(c_int) { warning = 220, help_box = 221, info_box = 222, - icon_223 = 223, - icon_224 = 224, - icon_225 = 225, - icon_226 = 226, - icon_227 = 227, - icon_228 = 228, - icon_229 = 229, - icon_230 = 230, - icon_231 = 231, - icon_232 = 232, - icon_233 = 233, + priority = 223, + layers_iso = 224, + layers2 = 225, + mlayers = 226, + maps = 227, + hot = 228, + label = 229, + name_id = 230, + slicing = 231, + manual_control = 232, + collision = 233, icon_234 = 234, icon_235 = 235, icon_236 = 236, diff --git a/lib/preludes/raylib-prelude.zig b/lib/preludes/raylib-prelude.zig index fba5ee4..8835267 100644 --- a/lib/preludes/raylib-prelude.zig +++ b/lib/preludes/raylib-prelude.zig @@ -8,6 +8,8 @@ pub const cdef = @import("raylib-ext.zig"); pub const gl = @import("rlgl.zig"); pub const math = @import("raymath.zig"); +const C = std.builtin.CallingConvention.c; + test { std.testing.refAllDeclsRecursive(@This()); } @@ -1996,12 +1998,12 @@ pub const NPatchType = enum(c_int) { three_patch_horizontal = 2, }; -// pub const TraceLogCallback = ?fn (c_int, [*c]const u8, [*c]struct___va_list_tag) callconv(.C) void; -pub const LoadFileDataCallback = *const fn ([*c]const u8, [*c]c_uint) callconv(.C) [*c]u8; -pub const SaveFileDataCallback = *const fn ([*c]const u8, ?*anyopaque, c_uint) callconv(.C) bool; -pub const LoadFileTextCallback = *const fn ([*c]const u8) callconv(.C) [*c]u8; -pub const SaveFileTextCallback = *const fn ([*c]const u8, [*c]u8) callconv(.C) bool; -pub const AudioCallback = ?*const fn (?*anyopaque, c_uint) callconv(.C) void; +// pub const TraceLogCallback = ?fn (c_int, [*c]const u8, [*c]struct___va_list_tag) callconv(C) void; +pub const LoadFileDataCallback = *const fn ([*c]const u8, [*c]c_uint) callconv(C) [*c]u8; +pub const SaveFileDataCallback = *const fn ([*c]const u8, ?*anyopaque, c_uint) callconv(C) bool; +pub const LoadFileTextCallback = *const fn ([*c]const u8) callconv(C) [*c]u8; +pub const SaveFileTextCallback = *const fn ([*c]const u8, [*c]u8) callconv(C) bool; +pub const AudioCallback = ?*const fn (?*anyopaque, c_uint) callconv(C) void; pub const RAYLIB_VERSION_MAJOR = @as(i32, 5); pub const RAYLIB_VERSION_MINOR = @as(i32, 5); diff --git a/lib/raygui-ext.zig b/lib/raygui-ext.zig index f27715d..f2b35e0 100644 --- a/lib/raygui-ext.zig +++ b/lib/raygui-ext.zig @@ -25,6 +25,7 @@ pub extern "c" fn GuiSetIconScale(scale: c_int) void; pub extern "c" fn GuiGetIcons() [*c]c_uint; pub extern "c" fn GuiLoadIcons(fileName: [*c]const u8, loadIconsName: bool) [*c][*c]u8; pub extern "c" fn GuiDrawIcon(iconId: c_int, posX: c_int, posY: c_int, pixelSize: c_int, color: rl.Color) void; +pub extern "c" fn GuiGetTextWidth(text: [*c]const u8) c_int; pub extern "c" fn GuiWindowBox(bounds: rl.Rectangle, title: [*c]const u8) c_int; pub extern "c" fn GuiGroupBox(bounds: rl.Rectangle, text: [*c]const u8) c_int; pub extern "c" fn GuiLine(bounds: rl.Rectangle, text: [*c]const u8) c_int; @@ -45,7 +46,6 @@ pub extern "c" fn GuiValueBox(bounds: rl.Rectangle, text: [*c]const u8, value: [ pub extern "c" fn GuiValueBoxFloat(bounds: rl.Rectangle, text: [*c]const u8, textValue: [*c]u8, value: [*c]f32, editMode: bool) c_int; pub extern "c" fn GuiTextBox(bounds: rl.Rectangle, text: [*c]u8, textSize: c_int, editMode: bool) c_int; pub extern "c" fn GuiSlider(bounds: rl.Rectangle, textLeft: [*c]const u8, textRight: [*c]const u8, value: [*c]f32, minValue: f32, maxValue: f32) c_int; -pub extern "c" fn GuiSliderPro(bounds: rl.Rectangle, textLeft: [*c]const u8, textRight: [*c]const u8, value: [*c]f32, minValue: f32, maxValue: f32, sliderWidth: c_int) c_int; pub extern "c" fn GuiSliderBar(bounds: rl.Rectangle, textLeft: [*c]const u8, textRight: [*c]const u8, value: [*c]f32, minValue: f32, maxValue: f32) c_int; pub extern "c" fn GuiProgressBar(bounds: rl.Rectangle, textLeft: [*c]const u8, textRight: [*c]const u8, value: [*c]f32, minValue: f32, maxValue: f32) c_int; pub extern "c" fn GuiStatusBar(bounds: rl.Rectangle, text: [*c]const u8) c_int; diff --git a/lib/raygui.h b/lib/raygui.h index 39908db..6999bd5 100644 --- a/lib/raygui.h +++ b/lib/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) @@ -149,6 +149,7 @@ * 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 @@ -265,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: * @@ -364,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 @@ -427,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 { @@ -727,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 @@ -754,7 +750,6 @@ RAYGUIAPI int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textVal 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 GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth); // Slider control with extended parameters 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 @@ -1010,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, @@ -1058,11 +1053,23 @@ typedef enum { #include // required for: isspace() [GuiTextBox()] #include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), snprintf(), 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()] +// 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 @@ -1329,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 @@ -1494,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 @@ -1686,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; @@ -2026,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 @@ -2213,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; @@ -2238,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; @@ -2507,7 +2513,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) 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 @@ -2565,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 @@ -2639,10 +2645,10 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // 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); + bool puctuation = ispunct(nextCodepoint & 0xff); while (offset < textLength) { - if ((puctuation && !ispunct(nextCodepoint & 0xFF)) || (!puctuation && (isspace(nextCodepoint & 0xFF) || ispunct(nextCodepoint & 0xFF)))) + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) break; offset += nextCodepointSize; accCodepointSize += nextCodepointSize; @@ -2651,7 +2657,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Check whitespace to delete (ASCII only) while (offset < textLength) { - if (!isspace(nextCodepoint & 0xFF)) + if (!isspace(nextCodepoint & 0xff)) break; offset += nextCodepointSize; accCodepointSize += nextCodepointSize; @@ -2687,18 +2693,18 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) while (offset > 0) { prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); - if (!isspace(prevCodepoint & 0xFF)) break; + 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); + 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; + if ((puctuation && !ispunct(prevCodepoint & 0xff)) || (!puctuation && (isspace(prevCodepoint & 0xff) || ispunct(prevCodepoint & 0xff)))) break; offset -= prevCodepointSize; accCodepointSize += prevCodepointSize; @@ -2736,7 +2742,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) while (offset > 0) { prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize); - if (!isspace(prevCodepoint & 0xFF)) break; + if (!isspace(prevCodepoint & 0xff)) break; offset -= prevCodepointSize; accCodepointSize += prevCodepointSize; @@ -2744,11 +2750,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // 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); + 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; + if ((puctuation && !ispunct(prevCodepoint & 0xff)) || (!puctuation && (isspace(prevCodepoint & 0xff) || ispunct(prevCodepoint & 0xff)))) break; offset -= prevCodepointSize; accCodepointSize += prevCodepointSize; @@ -2773,10 +2779,10 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // 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); + bool puctuation = ispunct(nextCodepoint & 0xff); while (offset < textLength) { - if ((puctuation && !ispunct(nextCodepoint & 0xFF)) || (!puctuation && (isspace(nextCodepoint & 0xFF) || ispunct(nextCodepoint & 0xFF)))) break; + if ((puctuation && !ispunct(nextCodepoint & 0xff)) || (!puctuation && (isspace(nextCodepoint & 0xff) || ispunct(nextCodepoint & 0xff)))) break; offset += nextCodepointSize; accCodepointSize += nextCodepointSize; @@ -2786,7 +2792,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) // Check whitespace to skip (ASCII only) while (offset < textLength) { - if (!isspace(nextCodepoint & 0xFF)) break; + if (!isspace(nextCodepoint & 0xff)) break; offset += nextCodepointSize; accCodepointSize += nextCodepointSize; @@ -2831,7 +2837,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; @@ -2848,7 +2854,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 @@ -2949,7 +2955,7 @@ int GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int 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; @@ -3024,7 +3030,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in 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 +3051,39 @@ 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)) @@ -3112,7 +3147,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in 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 + 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; @@ -3143,7 +3178,7 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float 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; @@ -3164,10 +3199,38 @@ 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)) || @@ -3222,7 +3285,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))); @@ -3239,7 +3302,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; @@ -3248,6 +3311,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) }; @@ -3265,7 +3330,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 @@ -3285,7 +3350,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; @@ -3330,7 +3395,7 @@ int GuiSliderPro(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(SLIDER, TEXT_PADDING); textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2; @@ -3341,7 +3406,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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; @@ -3353,16 +3418,16 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, 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 @@ -3421,7 +3486,7 @@ 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; @@ -3432,7 +3497,7 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight 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; @@ -3651,22 +3716,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); @@ -3877,7 +3942,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); @@ -3890,8 +3955,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) @@ -4039,7 +4104,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; @@ -4103,7 +4168,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; @@ -4443,8 +4508,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; @@ -4561,7 +4626,7 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName) 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); @@ -4611,7 +4676,7 @@ char **GuiLoadIconsFromMemory(const unsigned char *fileData, int dataSize, bool fileDataPtr += iconCount*RAYGUI_ICON_MAX_NAME_LENGTH; } - int iconDataSize = iconCount*(iconSize*iconSize/32)*sizeof(unsigned int); + int iconDataSize = iconCount*((int)iconSize*(int)iconSize/32)*(int)sizeof(unsigned int); guiIconsPtr = (unsigned int *)RAYGUI_MALLOC(iconDataSize); memcpy(guiIconsPtr, fileDataPtr, iconDataSize); @@ -4647,6 +4712,68 @@ 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 //---------------------------------------------------------------------------------- @@ -4875,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) { @@ -5003,6 +5068,7 @@ static const char *GetTextIcon(const char *text, int *iconId) } // Get text divided into lines (by line-breaks '\n') +// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! static const char **GetTextLines(const char *text, int *count) { #define RAYGUI_MAX_TEXT_LINES 128 @@ -5107,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) @@ -5171,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) { @@ -5315,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); } @@ -5697,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; } @@ -5733,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; @@ -5902,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/lib/raygui.zig b/lib/raygui.zig index e1653b3..1489c73 100644 --- a/lib/raygui.zig +++ b/lib/raygui.zig @@ -389,17 +389,17 @@ pub const IconName = enum(c_int) { warning = 220, help_box = 221, info_box = 222, - icon_223 = 223, - icon_224 = 224, - icon_225 = 225, - icon_226 = 226, - icon_227 = 227, - icon_228 = 228, - icon_229 = 229, - icon_230 = 230, - icon_231 = 231, - icon_232 = 232, - icon_233 = 233, + priority = 223, + layers_iso = 224, + layers2 = 225, + mlayers = 226, + maps = 227, + hot = 228, + label = 229, + name_id = 230, + slicing = 231, + manual_control = 232, + collision = 233, icon_234 = 234, icon_235 = 235, icon_236 = 236, @@ -599,6 +599,11 @@ pub fn drawIcon(iconId: i32, posX: i32, posY: i32, pixelSize: i32, color: Color) cdef.GuiDrawIcon(@as(c_int, iconId), @as(c_int, posX), @as(c_int, posY), @as(c_int, pixelSize), color); } +/// Get text width considering gui style and icon size (if required) +pub fn getTextWidth(text: [:0]const u8) i32 { + return @as(i32, cdef.GuiGetTextWidth(@as([*c]const u8, @ptrCast(text)))); +} + /// Window Box control, shows a window that can be closed pub fn windowBox(bounds: Rectangle, title: [:0]const u8) i32 { return @as(i32, cdef.GuiWindowBox(bounds, @as([*c]const u8, @ptrCast(title)))); @@ -664,11 +669,6 @@ pub fn slider(bounds: Rectangle, textLeft: [:0]const u8, textRight: [:0]const u8 return @as(i32, cdef.GuiSlider(bounds, @as([*c]const u8, @ptrCast(textLeft)), @as([*c]const u8, @ptrCast(textRight)), @as([*c]f32, @ptrCast(value)), minValue, maxValue)); } -/// Slider control with extended parameters -pub fn sliderPro(bounds: Rectangle, textLeft: [:0]const u8, textRight: [:0]const u8, value: *f32, minValue: f32, maxValue: f32, sliderWidth: i32) i32 { - return @as(i32, cdef.GuiSliderPro(bounds, @as([*c]const u8, @ptrCast(textLeft)), @as([*c]const u8, @ptrCast(textRight)), @as([*c]f32, @ptrCast(value)), minValue, maxValue, @as(c_int, sliderWidth))); -} - /// Slider Bar control pub fn sliderBar(bounds: Rectangle, textLeft: [:0]const u8, textRight: [:0]const u8, value: *f32, minValue: f32, maxValue: f32) i32 { return @as(i32, cdef.GuiSliderBar(bounds, @as([*c]const u8, @ptrCast(textLeft)), @as([*c]const u8, @ptrCast(textRight)), @as([*c]f32, @ptrCast(value)), minValue, maxValue)); diff --git a/lib/raylib.h b/lib/raylib.h index f42ab40..c9fdab5 100644 --- a/lib/raylib.h +++ b/lib/raylib.h @@ -5,7 +5,7 @@ * FEATURES: * - NO external dependencies, all required libraries included with raylib * - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, -* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5. +* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5 * - Written in plain C code (C99) in PascalCase/camelCase notation * - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile) * - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] @@ -36,7 +36,7 @@ * [rcore] msf_gif (Miles Fogle) for GIF recording * [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm * [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm -* [rcore] rprand (Ramon Snatamaria) for pseudo-random numbers generation +* [rcore] rprand (Ramon Santamaria) for pseudo-random numbers generation * [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage * [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) * [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) @@ -1129,7 +1129,7 @@ RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text d // File system functions RLAPI bool FileExists(const char *fileName); // Check if file exists RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists -RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav) +RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (recommended include point: .png, .wav) RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png') RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string @@ -1424,8 +1424,8 @@ RLAPI bool IsTextureValid(Texture2D texture); RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU) RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) -RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data -RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data (pixels should be able to fill texture) +RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data (pixels and rec should fit in texture) // Texture configuration functions RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture @@ -1514,9 +1514,9 @@ RLAPI const char *TextSubtext(const char *text, int position, int length); RLAPI char *TextReplace(const char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!) RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!) RLAPI char *TextJoin(char **textList, int count, const char *delimiter); // Join text strings with delimiter -RLAPI char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings +RLAPI char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor! -RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string +RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string, -1 if not found RLAPI char *TextToUpper(const char *text); // Get upper case version of provided string RLAPI char *TextToLower(const char *text); // Get lower case version of provided string RLAPI char *TextToPascal(const char *text); // Get Pascal case notation version of provided string @@ -1646,7 +1646,7 @@ RLAPI Sound LoadSound(const char *fileName); // Load so RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized) -RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data +RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data (data and frame count should fit in sound) RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void UnloadSoundAlias(Sound alias); // Unload a sound alias (does not deallocate sample data) diff --git a/lib/raylib.zig b/lib/raylib.zig index 974701c..3cc0f4e 100644 --- a/lib/raylib.zig +++ b/lib/raylib.zig @@ -8,6 +8,8 @@ pub const cdef = @import("raylib-ext.zig"); pub const gl = @import("rlgl.zig"); pub const math = @import("raymath.zig"); +const C = std.builtin.CallingConvention.c; + test { std.testing.refAllDeclsRecursive(@This()); } @@ -1996,12 +1998,12 @@ pub const NPatchType = enum(c_int) { three_patch_horizontal = 2, }; -// pub const TraceLogCallback = ?fn (c_int, [*c]const u8, [*c]struct___va_list_tag) callconv(.C) void; -pub const LoadFileDataCallback = *const fn ([*c]const u8, [*c]c_uint) callconv(.C) [*c]u8; -pub const SaveFileDataCallback = *const fn ([*c]const u8, ?*anyopaque, c_uint) callconv(.C) bool; -pub const LoadFileTextCallback = *const fn ([*c]const u8) callconv(.C) [*c]u8; -pub const SaveFileTextCallback = *const fn ([*c]const u8, [*c]u8) callconv(.C) bool; -pub const AudioCallback = ?*const fn (?*anyopaque, c_uint) callconv(.C) void; +// pub const TraceLogCallback = ?fn (c_int, [*c]const u8, [*c]struct___va_list_tag) callconv(C) void; +pub const LoadFileDataCallback = *const fn ([*c]const u8, [*c]c_uint) callconv(C) [*c]u8; +pub const SaveFileDataCallback = *const fn ([*c]const u8, ?*anyopaque, c_uint) callconv(C) bool; +pub const LoadFileTextCallback = *const fn ([*c]const u8) callconv(C) [*c]u8; +pub const SaveFileTextCallback = *const fn ([*c]const u8, [*c]u8) callconv(C) bool; +pub const AudioCallback = ?*const fn (?*anyopaque, c_uint) callconv(C) void; pub const RAYLIB_VERSION_MAJOR = @as(i32, 5); pub const RAYLIB_VERSION_MINOR = @as(i32, 5); @@ -3116,7 +3118,7 @@ pub fn directoryExists(dirPath: [:0]const u8) bool { return cdef.DirectoryExists(@as([*c]const u8, @ptrCast(dirPath))); } -/// Check file extension (including point: .png, .wav) +/// Check file extension (recommended include point: .png, .wav) pub fn isFileExtension(fileName: [:0]const u8, ext: [:0]const u8) bool { return cdef.IsFileExtension(@as([*c]const u8, @ptrCast(fileName)), @as([*c]const u8, @ptrCast(ext))); } @@ -4194,12 +4196,12 @@ pub fn unloadRenderTexture(target: RenderTexture2D) void { cdef.UnloadRenderTexture(target); } -/// Update GPU texture with new data +/// Update GPU texture with new data (pixels should be able to fill texture) pub fn updateTexture(texture: Texture2D, pixels: *const anyopaque) void { cdef.UpdateTexture(texture, pixels); } -/// Update GPU texture rectangle with new data +/// Update GPU texture rectangle with new data (pixels and rec should fit in texture) pub fn updateTextureRec(texture: Texture2D, rec: Rectangle, pixels: *const anyopaque) void { cdef.UpdateTextureRec(texture, rec, pixels); } @@ -4472,7 +4474,7 @@ pub fn textInsert(text: [:0]const u8, insert: [:0]const u8, position: i32) [:0]u return std.mem.span(cdef.TextInsert(@as([*c]const u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(insert)), @as(c_int, position))); } -/// Split text into multiple strings +/// Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings pub fn textSplit(text: []const u8, delimiter: u8) RaylibError![][:0]u8 { var _len: i32 = 0; const _ptr = cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&_len))); @@ -4485,7 +4487,7 @@ pub fn textAppend(text: [:0]u8, append: [:0]const u8, position: *i32) void { cdef.TextAppend(@as([*c]u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(append)), @as([*c]c_int, @ptrCast(position))); } -/// Find first text occurrence within a string +/// Find first text occurrence within a string, -1 if not found pub fn textFindIndex(text: [:0]const u8, find: [:0]const u8) i32 { return @as(i32, cdef.TextFindIndex(@as([*c]const u8, @ptrCast(text)), @as([*c]const u8, @ptrCast(find)))); } @@ -4918,7 +4920,7 @@ pub fn isSoundValid(sound: Sound) bool { return cdef.IsSoundValid(sound); } -/// Update sound buffer with new data +/// Update sound buffer with new data (data and frame count should fit in sound) pub fn updateSound(sound: Sound, data: *const anyopaque, sampleCount: i32) void { cdef.UpdateSound(sound, data, @as(c_int, sampleCount)); } diff --git a/lib/raymath.h b/lib/raymath.h index a531b3a..f246f26 100644 --- a/lib/raymath.h +++ b/lib/raymath.h @@ -329,7 +329,7 @@ RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2) } // Calculate the signed angle from v1 to v2, relative to the origin (0, 0) -// NOTE: Coordinate system convention: positive X right, positive Y down, +// NOTE: Coordinate system convention: positive X right, positive Y down // positive angles appear clockwise, and negative angles appear counterclockwise RMAPI float Vector2Angle(Vector2 v1, Vector2 v2) { diff --git a/lib/rlgl-ext.zig b/lib/rlgl-ext.zig index 2d7e117..f434eb8 100644 --- a/lib/rlgl-ext.zig +++ b/lib/rlgl-ext.zig @@ -85,6 +85,7 @@ pub extern "c" fn rlSetBlendFactorsSeparate(glSrcRGB: c_int, glDstRGB: c_int, gl pub extern "c" fn rlglInit(width: c_int, height: c_int) void; pub extern "c" fn rlglClose() void; pub extern "c" fn rlLoadExtensions(loader: *anyopaque) void; +pub extern "c" fn rlGetProcAddress(procName: [*c]const u8) *anyopaque; pub extern "c" fn rlGetVersion() c_int; pub extern "c" fn rlSetFramebufferWidth(width: c_int) void; pub extern "c" fn rlGetFramebufferWidth() c_int; diff --git a/lib/rlgl.h b/lib/rlgl.h index 2562ad4..17c854f 100644 --- a/lib/rlgl.h +++ b/lib/rlgl.h @@ -710,6 +710,7 @@ RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures) RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required) +RLAPI void *rlGetProcAddress(const char *procName); // Get OpenGL procedure address RLAPI int rlGetVersion(void); // Get current OpenGL version RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width @@ -1041,10 +1042,15 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad // Types and Structures Definition //---------------------------------------------------------------------------------- #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + +typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc) + typedef struct rlglData { rlRenderBatch *currentBatch; // Current render batch rlRenderBatch defaultBatch; // Default internal render batch + rlglLoadProc loader; // OpenGL function loader + struct { int vertexCounter; // Current active render batch vertex counter (generic, used for all batches) float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*()) @@ -1114,8 +1120,6 @@ typedef struct rlglData { } ExtSupported; // Extensions supported flags } rlglData; -typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc) - #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 //---------------------------------------------------------------------------------- @@ -1153,16 +1157,16 @@ static const char *rlGetCompressedFormatName(int format); // Get compressed form static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) +static Matrix rlMatrixIdentity(void); // Get identity matrix +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Auxiliar matrix math functions -typedef struct rl_float16 { - float v[16]; -} rl_float16; +typedef struct rl_float16 { float v[16]; } rl_float16; static rl_float16 rlMatrixToFloatV(Matrix mat); // Get float array of matrix data #define rlMatrixToFloat(mat) (rlMatrixToFloatV(mat).v) // Get float vector for Matrix -static Matrix rlMatrixIdentity(void); // Get identity matrix static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices static Matrix rlMatrixTranspose(Matrix mat); // Transposes provided matrix static Matrix rlMatrixInvert(Matrix mat); // Invert provided matrix +#endif //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix operations @@ -1885,7 +1889,7 @@ void rlActiveDrawBuffers(int count) if (count > 0) { - if (count > 8) TRACELOG(LOG_WARNING, "GL: Max color buffers limited to 8"); + if (count > 8) TRACELOG(RL_LOG_WARNING, "GL: Max color buffers limited to 8"); else { unsigned int buffers[8] = { @@ -1902,7 +1906,7 @@ void rlActiveDrawBuffers(int count) glDrawBuffers(count, buffers); } } - else TRACELOG(LOG_WARNING, "GL: One color buffer active by default"); + else TRACELOG(RL_LOG_WARNING, "GL: One color buffer active by default"); #endif } @@ -2219,10 +2223,10 @@ static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint default: break; } - TRACELOG(LOG_WARNING, "GL: OpenGL debug message: %s", message); - TRACELOG(LOG_WARNING, " > Type: %s", msgType); - TRACELOG(LOG_WARNING, " > Source = %s", msgSource); - TRACELOG(LOG_WARNING, " > Severity = %s", msgSeverity); + TRACELOG(RL_LOG_WARNING, "GL: OpenGL debug message: %s", message); + TRACELOG(RL_LOG_WARNING, " > Type: %s", msgType); + TRACELOG(RL_LOG_WARNING, " > Source = %s", msgSource); + TRACELOG(RL_LOG_WARNING, " > Severity = %s", msgSeverity); } #endif @@ -2568,6 +2572,8 @@ void rlLoadExtensions(void *loader) TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + RLGL.loader = (rlglLoadProc)loader; + // NOTE: Anisotropy levels capability is an extension #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF @@ -2625,6 +2631,16 @@ void rlLoadExtensions(void *loader) #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 } +// Get OpenGL procedure address +void *rlGetProcAddress(const char *procName) +{ + void *func = NULL; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + func = RLGL.loader(procName); +#endif + return func; +} + // Get current OpenGL version int rlGetVersion(void) { @@ -4178,7 +4194,7 @@ unsigned int rlCompileShader(const char *shaderCode, int type) RL_FREE(log); } - // Unload object allocated by glCreateShader(), + // Unload object allocated by glCreateShader(), // despite failing in the compilation process glDeleteShader(shader); shader = 0; @@ -5129,7 +5145,20 @@ static int rlGetPixelDataSize(int width, int height, int format) } // Auxiliar math functions +//------------------------------------------------------------------------------- +// Get identity matrix +static Matrix rlMatrixIdentity(void) +{ + Matrix result = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + return result; +} +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Get float array of matrix data static rl_float16 rlMatrixToFloatV(Matrix mat) { @@ -5155,19 +5184,6 @@ static rl_float16 rlMatrixToFloatV(Matrix mat) return result; } -// Get identity matrix -static Matrix rlMatrixIdentity(void) -{ - Matrix result = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; - - return result; -} - // Get two matrix multiplication // NOTE: When multiplying matrices... the order matters! static Matrix rlMatrixMultiply(Matrix left, Matrix right) @@ -5265,5 +5281,6 @@ static Matrix rlMatrixInvert(Matrix mat) return result; } +#endif #endif // RLGL_IMPLEMENTATION diff --git a/lib/rlgl.zig b/lib/rlgl.zig index c592cf9..43d0e24 100644 --- a/lib/rlgl.zig +++ b/lib/rlgl.zig @@ -679,6 +679,11 @@ pub fn rlLoadExtensions(loader: *anyopaque) void { cdef.rlLoadExtensions(loader); } +/// Get OpenGL procedure address +pub fn rlGetProcAddress(procName: [:0]const u8) *anyopaque { + return cdef.rlGetProcAddress(@as([*c]const u8, @ptrCast(procName))); +} + /// Get current OpenGL version pub fn rlGetVersion() i32 { return @as(i32, cdef.rlGetVersion());