mirror of
https://github.com/Not-Nik/raylib-zig.git
synced 2025-09-08 19:47:28 +00:00
Update to Zig 0.14.0 and raylib 5.6-dev
This commit is contained in:
parent
ae7cb3fa93
commit
1b6a05ca3b
@ -1,6 +1,7 @@
|
||||
.{
|
||||
.name = "raylib-zig",
|
||||
.name = .raylib_zig,
|
||||
.version = "5.6.0-dev",
|
||||
.fingerprint = 0xc4cfa8c610114f28,
|
||||
.dependencies = .{
|
||||
.raylib = .{
|
||||
.url = "git+https://github.com/raysan5/raylib#e70f9157bcae046804e754e98a2694adcfdbfa5d",
|
||||
@ -11,7 +12,7 @@
|
||||
.hash = "1220ce6e40b454766d901ac4a19b2408f84365fcad4e4840c788b59f34a0ed698883",
|
||||
},
|
||||
},
|
||||
.minimum_zig_version = "0.14.0-dev.2802+257054a14",
|
||||
.minimum_zig_version = "0.14.0",
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
|
@ -58,7 +58,7 @@ pub const GuiControl = enum(c_int) {
|
||||
dropdownbox,
|
||||
textbox,
|
||||
valuebox,
|
||||
spinner,
|
||||
control11,
|
||||
listview,
|
||||
colorpicker,
|
||||
scrollbar,
|
||||
@ -135,7 +135,7 @@ pub const GuiTextBoxProperty = enum(c_int) {
|
||||
text_readonly = 16,
|
||||
};
|
||||
|
||||
pub const GuiSpinnerProperty = enum(c_int) {
|
||||
pub const GuiValueBoxProperty = enum(c_int) {
|
||||
spin_button_width = 16,
|
||||
spin_button_spacing,
|
||||
};
|
||||
@ -145,6 +145,7 @@ pub const GuiListViewProperty = enum(c_int) {
|
||||
list_items_spacing,
|
||||
scrollbar_width,
|
||||
scrollbar_side,
|
||||
list_items_border_normal,
|
||||
list_items_border_width,
|
||||
};
|
||||
|
||||
|
@ -1843,6 +1843,7 @@ pub const ShaderLocationIndex = enum(c_int) {
|
||||
vertex_boneids = 26,
|
||||
vertex_boneweights = 27,
|
||||
bone_matrices = 28,
|
||||
shader_loc_vertex_instance_tx
|
||||
};
|
||||
|
||||
pub const ShaderUniformDataType = enum(c_int) {
|
||||
@ -1975,7 +1976,7 @@ 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);
|
||||
pub const RAYLIB_VERSION_PATCH = @as(i32, 0);
|
||||
pub const RAYLIB_VERSION = "5.5";
|
||||
pub const RAYLIB_VERSION = "5.6-devfn alloc(_: *anyopaque, len: usize, _: std.mem.Alignment, _: usize) ?[*]u8 {";
|
||||
|
||||
pub const MAX_TOUCH_POINTS = 10;
|
||||
pub const MAX_MATERIAL_MAPS = 12;
|
||||
@ -2518,8 +2519,8 @@ pub fn loadUTF8(codepoints: []const c_int) [*:0]u8 {
|
||||
}
|
||||
|
||||
/// Join text strings with delimiter
|
||||
pub fn textJoin(textList: [][*:0]const u8, delimiter: [*:0]const u8) [*:0]const u8 {
|
||||
return std.mem.span(cdef.TextJoin(@as([*c][*c]const u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter))));
|
||||
pub fn textJoin(textList: [][*:0]u8, delimiter: [*:0]const u8) [*:0]const u8 {
|
||||
return std.mem.span(cdef.TextJoin(@as([*c][*c]u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter))));
|
||||
}
|
||||
|
||||
/// Draw a triangle strip defined by points
|
||||
@ -2528,24 +2529,34 @@ pub fn drawTriangleStrip3D(points: []const Vector3, color: Color) void {
|
||||
}
|
||||
|
||||
/// Internal memory allocator
|
||||
fn alloc(_: *anyopaque, len: usize, _: u8, _: usize) ?[*]u8 {
|
||||
fn alloc(_: *anyopaque, len: usize, _: std.mem.Alignment, _: usize) ?[*]u8 {
|
||||
std.debug.assert(len > 0);
|
||||
return @ptrCast(cdef.MemAlloc(@intCast(len)));
|
||||
}
|
||||
|
||||
fn resize(_: *anyopaque, buf: []u8, _: u8, new_len: usize, _: usize) bool {
|
||||
fn resize(_: *anyopaque, buf: []u8, _: std.mem.Alignment, new_len: usize, _: usize) bool {
|
||||
return (new_len <= buf.len);
|
||||
}
|
||||
|
||||
/// Internal memory free
|
||||
fn free(_: *anyopaque, buf: []u8, _: u8, _: usize) void {
|
||||
fn free(_: *anyopaque, buf: []u8, _: std.mem.Alignment, _: usize) void {
|
||||
cdef.MemFree(buf.ptr);
|
||||
}
|
||||
|
||||
fn remap(_: *anyopaque, buf: []u8, _: std.mem.Alignment, new_len: usize, _: usize) ?[*]u8 {
|
||||
if (new_len <= buf.len) {
|
||||
return buf.ptr;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const mem_vtable = std.mem.Allocator.VTable{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
.free = free,
|
||||
.remap = remap,
|
||||
};
|
||||
|
||||
pub const mem = std.mem.Allocator{
|
||||
|
@ -266,3 +266,7 @@ pub const rl_default_shader_attrib_location_normal = @as(i32, 2);
|
||||
pub const rl_default_shader_attrib_location_color = @as(i32, 3);
|
||||
pub const rl_default_shader_attrib_location_tangent = @as(i32, 4);
|
||||
pub const rl_default_shader_attrib_location_texcoord2 = @as(i32, 5);
|
||||
pub const rl_default_shader_attrib_location_indices = @as(i32, 6);
|
||||
pub const rl_default_shader_attrib_location_boneids = @as(i32, 7);
|
||||
pub const rl_default_shader_attrib_location_boneweights = @as(i32, 5);
|
||||
pub const rl_default_shader_attrib_location_instance_tx = @as(i32, 9);
|
||||
|
467
lib/raygui.h
vendored
467
lib/raygui.h
vendored
@ -141,12 +141,16 @@
|
||||
* 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
|
||||
* 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
|
||||
@ -309,7 +313,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 +338,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"
|
||||
@ -527,7 +531,7 @@ typedef enum {
|
||||
DROPDOWNBOX,
|
||||
TEXTBOX, // Used also for: TEXTBOXMULTI
|
||||
VALUEBOX,
|
||||
SPINNER, // Uses: BUTTON, VALUEBOX
|
||||
CONTROL11,
|
||||
LISTVIEW,
|
||||
COLORPICKER,
|
||||
SCROLLBAR,
|
||||
@ -549,12 +553,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 +645,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 +660,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;
|
||||
|
||||
@ -1046,7 +1054,7 @@ typedef enum {
|
||||
#if defined(RAYGUI_IMPLEMENTATION)
|
||||
|
||||
#include <ctype.h> // required for: isspace() [GuiTextBox()]
|
||||
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()]
|
||||
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), snprintf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()]
|
||||
#include <stdlib.h> // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()]
|
||||
#include <string.h> // Required for: strlen() [GuiTextBox(), GuiValueBox()], memset(), memcpy()
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()]
|
||||
@ -1387,8 +1395,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)
|
||||
@ -1589,6 +1596,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 +1608,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 +1665,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)
|
||||
@ -2149,7 +2161,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
|
||||
@ -2474,10 +2488,10 @@ 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 30 // 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
|
||||
#define RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY 2 // Frames delay for autocursor movement
|
||||
#endif
|
||||
|
||||
int result = 0;
|
||||
@ -2511,15 +2525,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 +2542,15 @@ 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;
|
||||
@ -2560,9 +2574,40 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
int codepointSize = 0;
|
||||
const char *charEncoded = CodepointToUTF8(codepoint, &codepointSize);
|
||||
|
||||
// Handle 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';
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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))
|
||||
else 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];
|
||||
@ -2583,113 +2628,175 @@ 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++;
|
||||
|
||||
if (IsKeyPressed(KEY_DELETE) || (autoCursorDelayCounter%RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY) == 0) // Delay every movement some frames
|
||||
int offset = textBoxCursorIndex;
|
||||
int accCodepointSize = 0;
|
||||
int nextCodepointSize;
|
||||
int nextCodepoint;
|
||||
// Check characters of the same type to delete (either ASCII punctuation or anything non-whitespace)
|
||||
// Not using isalnum() since it only works on ASCII characters
|
||||
nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize);
|
||||
bool puctuation = ispunct(nextCodepoint & 0xFF);
|
||||
while (offset < textLength)
|
||||
{
|
||||
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;
|
||||
}
|
||||
// Delete single codepoint from text, after current cursor position
|
||||
else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
// Delete single codepoint from text, before current cursor position
|
||||
else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger)))
|
||||
{
|
||||
autoCursorDelayCounter++;
|
||||
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);
|
||||
|
||||
if (textBoxCursorIndex >= prevCodepointSize) textBoxCursorIndex -= prevCodepointSize;
|
||||
prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize);
|
||||
if (!isspace(prevCodepoint & 0xFF))
|
||||
break;
|
||||
offset -= prevCodepointSize;
|
||||
accCodepointSize += prevCodepointSize;
|
||||
}
|
||||
// Check characters of the same type to skip (either ASCII punctuation or anything non-whitespace)
|
||||
// Not using isalnum() since it only works on ASCII characters
|
||||
bool puctuation = ispunct(prevCodepoint & 0xFF);
|
||||
while (offset > 0)
|
||||
{
|
||||
prevCodepoint = GetCodepointPrevious(text + offset, &prevCodepointSize);
|
||||
if ((puctuation && !ispunct(prevCodepoint & 0xFF)) || (!puctuation && (isspace(prevCodepoint & 0xFF) || ispunct(prevCodepoint & 0xFF))))
|
||||
break;
|
||||
offset -= prevCodepointSize;
|
||||
accCodepointSize += prevCodepointSize;
|
||||
}
|
||||
|
||||
textBoxCursorIndex = offset;
|
||||
}
|
||||
else if (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 ((textBoxCursorIndex + nextCodepointSize) <= textLength) textBoxCursorIndex += nextCodepointSize;
|
||||
if ((puctuation && !ispunct(nextCodepoint & 0xFF)) || (!puctuation && (isspace(nextCodepoint & 0xFF) || ispunct(nextCodepoint & 0xFF))))
|
||||
break;
|
||||
offset += nextCodepointSize;
|
||||
accCodepointSize += nextCodepointSize;
|
||||
nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize);
|
||||
}
|
||||
// Check whitespace to skip (ASCII only)
|
||||
while (offset < textLength)
|
||||
{
|
||||
if (!isspace(nextCodepoint & 0xFF))
|
||||
break;
|
||||
offset += nextCodepointSize;
|
||||
accCodepointSize += nextCodepointSize;
|
||||
nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize);
|
||||
}
|
||||
|
||||
textBoxCursorIndex = offset;
|
||||
}
|
||||
else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_RIGHT) || (IsKeyDown(KEY_RIGHT) && autoCursorShouldTrigger)))
|
||||
{
|
||||
int nextCodepointSize = 0;
|
||||
GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
|
||||
|
||||
textBoxCursorIndex += nextCodepointSize;
|
||||
}
|
||||
|
||||
// Move cursor position with mouse
|
||||
@ -2701,7 +2808,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);
|
||||
@ -2745,6 +2852,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 +2865,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 +2934,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.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 +2983,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,7 +3015,7 @@ 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)
|
||||
@ -2992,11 +3104,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 + GetTextWidth(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,7 +3134,7 @@ 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};
|
||||
if (text != NULL)
|
||||
@ -3205,6 +3320,7 @@ 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)
|
||||
@ -3215,7 +3331,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight,
|
||||
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)
|
||||
@ -3226,7 +3342,7 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight,
|
||||
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))));
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@ -3255,16 +3371,16 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
||||
if (value == NULL) value = &temp;
|
||||
|
||||
// Progress bar
|
||||
Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH),
|
||||
Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING),
|
||||
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,18 +3398,18 @@ 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)
|
||||
progress.width -= 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING);
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
}
|
||||
|
||||
@ -3306,7 +3422,7 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
||||
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)
|
||||
@ -3317,7 +3433,7 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
||||
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 +3583,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 +3596,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)));
|
||||
}
|
||||
}
|
||||
@ -3570,7 +3686,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 +3736,6 @@ int GuiColorBarAlpha(Rectangle bounds, const char *text, float *alpha)
|
||||
|
||||
// Draw control
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// Draw alpha bar: checked background
|
||||
if (state != STATE_DISABLED)
|
||||
{
|
||||
@ -4283,8 +4401,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 +4415,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 +4426,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);
|
||||
@ -4352,7 +4469,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 +4481,7 @@ const char *GuiIconText(int iconId, const char *text)
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(iconBuffer, "#%03i#", iconId);
|
||||
snprintf(iconBuffer, 16, "#%03i#", iconId);
|
||||
|
||||
return iconBuffer;
|
||||
}
|
||||
@ -4449,6 +4566,56 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName)
|
||||
return guiIconsName;
|
||||
}
|
||||
|
||||
// Load icons from memory
|
||||
// WARNING: Binary files only
|
||||
char **GuiLoadIconsFromMemory(const unsigned char *fileData, size_t 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_MALLOC(iconCount*sizeof(char *));
|
||||
for (int i = 0; i < iconCount; i++)
|
||||
{
|
||||
guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH);
|
||||
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*(iconSize*iconSize/32)*sizeof(unsigned int);
|
||||
guiIconsPtr = (unsigned int *)RAYGUI_MALLOC(iconDataSize);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -4786,7 +4953,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:
|
||||
{
|
||||
@ -5204,7 +5371,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ pub const GuiControl = enum(c_int) {
|
||||
dropdownbox,
|
||||
textbox,
|
||||
valuebox,
|
||||
spinner,
|
||||
control11,
|
||||
listview,
|
||||
colorpicker,
|
||||
scrollbar,
|
||||
@ -135,7 +135,7 @@ pub const GuiTextBoxProperty = enum(c_int) {
|
||||
text_readonly = 16,
|
||||
};
|
||||
|
||||
pub const GuiSpinnerProperty = enum(c_int) {
|
||||
pub const GuiValueBoxProperty = enum(c_int) {
|
||||
spin_button_width = 16,
|
||||
spin_button_spacing,
|
||||
};
|
||||
@ -145,6 +145,7 @@ pub const GuiListViewProperty = enum(c_int) {
|
||||
list_items_spacing,
|
||||
scrollbar_width,
|
||||
scrollbar_side,
|
||||
list_items_border_normal,
|
||||
list_items_border_width,
|
||||
};
|
||||
|
||||
|
@ -168,6 +168,7 @@ pub extern "c" fn IsKeyReleased(key: rl.KeyboardKey) bool;
|
||||
pub extern "c" fn IsKeyUp(key: rl.KeyboardKey) bool;
|
||||
pub extern "c" fn GetKeyPressed() rl.KeyboardKey;
|
||||
pub extern "c" fn GetCharPressed() c_int;
|
||||
pub extern "c" fn GetKeyName(key: rl.KeyboardKey) [*c]const u8;
|
||||
pub extern "c" fn SetExitKey(key: rl.KeyboardKey) void;
|
||||
pub extern "c" fn IsGamepadAvailable(gamepad: c_int) bool;
|
||||
pub extern "c" fn GetGamepadName(gamepad: c_int) [*c]const u8;
|
||||
@ -429,15 +430,15 @@ pub extern "c" fn TextFormat(text: [*c]const u8, ...) [*c]const u8;
|
||||
pub extern "c" fn TextSubtext(text: [*c]const u8, position: c_int, length: c_int) [*c]const u8;
|
||||
pub extern "c" fn TextReplace(text: [*c]const u8, replace: [*c]const u8, by: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextInsert(text: [*c]const u8, insert: [*c]const u8, position: c_int) [*c]u8;
|
||||
pub extern "c" fn TextJoin(textList: [*c][*c]const u8, count: c_int, delimiter: [*c]const u8) [*c]const u8;
|
||||
pub extern "c" fn TextSplit(text: [*c]const u8, delimiter: u8, count: [*c]c_int) [*c][*c]const u8;
|
||||
pub extern "c" fn TextJoin(textList: [*c][*c]u8, count: c_int, delimiter: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextSplit(text: [*c]const u8, delimiter: u8, count: [*c]c_int) [*c][*c]u8;
|
||||
pub extern "c" fn TextAppend(text: [*c]u8, append: [*c]const u8, position: [*c]c_int) void;
|
||||
pub extern "c" fn TextFindIndex(text: [*c]const u8, find: [*c]const u8) c_int;
|
||||
pub extern "c" fn TextToUpper(text: [*c]const u8) [*c]const u8;
|
||||
pub extern "c" fn TextToLower(text: [*c]const u8) [*c]const u8;
|
||||
pub extern "c" fn TextToPascal(text: [*c]const u8) [*c]const u8;
|
||||
pub extern "c" fn TextToSnake(text: [*c]const u8) [*c]const u8;
|
||||
pub extern "c" fn TextToCamel(text: [*c]const u8) [*c]const u8;
|
||||
pub extern "c" fn TextToUpper(text: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextToLower(text: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextToPascal(text: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextToSnake(text: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextToCamel(text: [*c]const u8) [*c]u8;
|
||||
pub extern "c" fn TextToInteger(text: [*c]const u8) c_int;
|
||||
pub extern "c" fn TextToFloat(text: [*c]const u8) f32;
|
||||
pub extern "c" fn DrawLine3D(startPos: rl.Vector3, endPos: rl.Vector3, color: rl.Color) void;
|
||||
|
156
lib/raylib.h
vendored
156
lib/raylib.h
vendored
@ -1,6 +1,6 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib v5.5 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
* raylib v5.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
*
|
||||
* FEATURES:
|
||||
* - NO external dependencies, all required libraries included with raylib
|
||||
@ -63,7 +63,7 @@
|
||||
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software:
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2013-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.
|
||||
@ -88,9 +88,9 @@
|
||||
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
|
||||
|
||||
#define RAYLIB_VERSION_MAJOR 5
|
||||
#define RAYLIB_VERSION_MINOR 5
|
||||
#define RAYLIB_VERSION_MINOR 6
|
||||
#define RAYLIB_VERSION_PATCH 0
|
||||
#define RAYLIB_VERSION "5.5"
|
||||
#define RAYLIB_VERSION "5.6-dev"
|
||||
|
||||
// Function specifiers in case library is build/used as a shared library
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
@ -801,7 +801,8 @@ typedef enum {
|
||||
SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf
|
||||
SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds
|
||||
SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights
|
||||
SHADER_LOC_BONE_MATRICES // Shader location: array of matrices uniform: boneMatrices
|
||||
SHADER_LOC_BONE_MATRICES, // Shader location: array of matrices uniform: boneMatrices
|
||||
SHADER_LOC_VERTEX_INSTANCE_TX // Shader location: vertex attribute: instanceTransform
|
||||
} ShaderLocationIndex;
|
||||
|
||||
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
|
||||
@ -817,6 +818,10 @@ typedef enum {
|
||||
SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
|
||||
SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
|
||||
SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
|
||||
SHADER_UNIFORM_UINT, // Shader uniform type: unsigned int
|
||||
SHADER_UNIFORM_UIVEC2, // Shader uniform type: uivec2 (2 unsigned int)
|
||||
SHADER_UNIFORM_UIVEC3, // Shader uniform type: uivec3 (3 unsigned int)
|
||||
SHADER_UNIFORM_UIVEC4, // Shader uniform type: uivec4 (4 unsigned int)
|
||||
SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
|
||||
} ShaderUniformDataType;
|
||||
|
||||
@ -1056,7 +1061,7 @@ RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Ge
|
||||
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
|
||||
RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector
|
||||
RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4)
|
||||
RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture (sampler2d)
|
||||
RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value and bind the texture (sampler2d)
|
||||
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
|
||||
|
||||
// Screen-space-related functions
|
||||
@ -1150,20 +1155,19 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
|
||||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
|
||||
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
|
||||
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
|
||||
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
|
||||
// Automation events functionality
|
||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
|
||||
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
|
||||
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
|
||||
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
|
||||
RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set)
|
||||
RLAPI void StopAutomationEventRecording(void); // Stop recording automation events
|
||||
RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event
|
||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
|
||||
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
|
||||
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
|
||||
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
|
||||
RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set)
|
||||
RLAPI void StopAutomationEventRecording(void); // Stop recording automation events
|
||||
RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
@ -1177,19 +1181,20 @@ RLAPI bool IsKeyReleased(int key); // Check if a key
|
||||
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
|
||||
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
|
||||
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
|
||||
RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
|
||||
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||
|
||||
// Input-related functions: gamepads
|
||||
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
|
||||
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
|
||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
|
||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
|
||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
|
||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
|
||||
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
|
||||
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
|
||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
|
||||
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
|
||||
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
|
||||
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
|
||||
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
|
||||
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
|
||||
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
|
||||
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
|
||||
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
|
||||
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
|
||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
|
||||
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
|
||||
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
|
||||
|
||||
// Input-related functions: mouse
|
||||
@ -1218,19 +1223,19 @@ RLAPI int GetTouchPointCount(void); // Get number of t
|
||||
//------------------------------------------------------------------------------------
|
||||
// Gestures and Touch Handling Functions (Module: rgestures)
|
||||
//------------------------------------------------------------------------------------
|
||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||
RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
|
||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||
RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Camera System Functions (Module: rcamera)
|
||||
//------------------------------------------------------------------------------------
|
||||
RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode
|
||||
RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode
|
||||
RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -1239,9 +1244,9 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f
|
||||
// Set texture and rectangle to be used on shapes drawing
|
||||
// NOTE: It can be useful when using basic shapes and one single font,
|
||||
// defining a font char white rectangle would allow drawing everything in a single draw call
|
||||
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
|
||||
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
|
||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
|
||||
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
|
||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||
|
||||
// Basic shapes drawing functions
|
||||
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care]
|
||||
@ -1283,11 +1288,11 @@ RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation
|
||||
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
|
||||
|
||||
// Splines drawing functions
|
||||
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
|
||||
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
|
||||
RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
|
||||
RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
|
||||
RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
|
||||
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
|
||||
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
|
||||
RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
|
||||
RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
|
||||
RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
|
||||
RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points
|
||||
RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points
|
||||
RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points
|
||||
@ -1360,7 +1365,7 @@ RLAPI void ImageAlphaPremultiply(Image *image);
|
||||
RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation
|
||||
RLAPI void ImageKernelConvolution(Image *image, const float *kernel, int kernelSize); // Apply custom square convolution kernel to image
|
||||
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
|
||||
RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
|
||||
RLAPI void ImageResizeNN(Image *image, int newWidth, int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
|
||||
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
|
||||
RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image
|
||||
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
|
||||
@ -1486,18 +1491,19 @@ RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint);
|
||||
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
|
||||
|
||||
// Text codepoints management functions (unicode characters)
|
||||
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
|
||||
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
|
||||
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
|
||||
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
|
||||
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
|
||||
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
|
||||
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
|
||||
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
|
||||
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
|
||||
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
|
||||
|
||||
// Text strings management functions (no UTF-8 strings, only byte chars)
|
||||
// NOTE: Some strings allocate memory internally for returned strings, just be careful!
|
||||
// WARNING 1: Most of these functions use internal static buffers, it's recommended to store returned data on user-side for re-use
|
||||
// WARNING 2: Some strings allocate memory internally for the returned strings, those strings must be free by user using MemFree()
|
||||
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
|
||||
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
|
||||
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
|
||||
@ -1505,18 +1511,18 @@ RLAPI const char *TextFormat(const char *text, ...);
|
||||
RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string
|
||||
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 const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter
|
||||
RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
|
||||
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 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 const char *TextToUpper(const char *text); // Get upper case version of provided string
|
||||
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
|
||||
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
|
||||
RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string
|
||||
RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string
|
||||
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
|
||||
RLAPI char *TextToSnake(const char *text); // Get Snake case notation version of provided string
|
||||
RLAPI char *TextToCamel(const char *text); // Get Camel case notation version of provided string
|
||||
|
||||
RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported)
|
||||
RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported)
|
||||
RLAPI int TextToInteger(const char *text); // Get integer value from text
|
||||
RLAPI float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic 3d Shapes Drawing Functions (Module: models)
|
||||
@ -1609,14 +1615,14 @@ RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount);
|
||||
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
|
||||
|
||||
// Collision detection functions
|
||||
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
|
||||
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
|
||||
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
|
||||
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
|
||||
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
|
||||
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
|
||||
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
|
||||
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
|
||||
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
|
||||
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
|
||||
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
|
||||
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
|
||||
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
|
||||
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio Loading and Playing Functions (Module: audio)
|
||||
@ -1695,10 +1701,10 @@ RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan
|
||||
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
|
||||
RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data
|
||||
|
||||
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as 'float'
|
||||
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)
|
||||
RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream
|
||||
|
||||
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as 'float'
|
||||
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)
|
||||
RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -1843,6 +1843,7 @@ pub const ShaderLocationIndex = enum(c_int) {
|
||||
vertex_boneids = 26,
|
||||
vertex_boneweights = 27,
|
||||
bone_matrices = 28,
|
||||
shader_loc_vertex_instance_tx
|
||||
};
|
||||
|
||||
pub const ShaderUniformDataType = enum(c_int) {
|
||||
@ -1975,7 +1976,7 @@ 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);
|
||||
pub const RAYLIB_VERSION_PATCH = @as(i32, 0);
|
||||
pub const RAYLIB_VERSION = "5.5";
|
||||
pub const RAYLIB_VERSION = "5.6-devfn alloc(_: *anyopaque, len: usize, _: std.mem.Alignment, _: usize) ?[*]u8 {";
|
||||
|
||||
pub const MAX_TOUCH_POINTS = 10;
|
||||
pub const MAX_MATERIAL_MAPS = 12;
|
||||
@ -2518,8 +2519,8 @@ pub fn loadUTF8(codepoints: []const c_int) [*:0]u8 {
|
||||
}
|
||||
|
||||
/// Join text strings with delimiter
|
||||
pub fn textJoin(textList: [][*:0]const u8, delimiter: [*:0]const u8) [*:0]const u8 {
|
||||
return std.mem.span(cdef.TextJoin(@as([*c][*c]const u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter))));
|
||||
pub fn textJoin(textList: [][*:0]u8, delimiter: [*:0]const u8) [*:0]const u8 {
|
||||
return std.mem.span(cdef.TextJoin(@as([*c][*c]u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter))));
|
||||
}
|
||||
|
||||
/// Draw a triangle strip defined by points
|
||||
@ -2528,24 +2529,34 @@ pub fn drawTriangleStrip3D(points: []const Vector3, color: Color) void {
|
||||
}
|
||||
|
||||
/// Internal memory allocator
|
||||
fn alloc(_: *anyopaque, len: usize, _: u8, _: usize) ?[*]u8 {
|
||||
fn alloc(_: *anyopaque, len: usize, _: std.mem.Alignment, _: usize) ?[*]u8 {
|
||||
std.debug.assert(len > 0);
|
||||
return @ptrCast(cdef.MemAlloc(@intCast(len)));
|
||||
}
|
||||
|
||||
fn resize(_: *anyopaque, buf: []u8, _: u8, new_len: usize, _: usize) bool {
|
||||
fn resize(_: *anyopaque, buf: []u8, _: std.mem.Alignment, new_len: usize, _: usize) bool {
|
||||
return (new_len <= buf.len);
|
||||
}
|
||||
|
||||
/// Internal memory free
|
||||
fn free(_: *anyopaque, buf: []u8, _: u8, _: usize) void {
|
||||
fn free(_: *anyopaque, buf: []u8, _: std.mem.Alignment, _: usize) void {
|
||||
cdef.MemFree(buf.ptr);
|
||||
}
|
||||
|
||||
fn remap(_: *anyopaque, buf: []u8, _: std.mem.Alignment, new_len: usize, _: usize) ?[*]u8 {
|
||||
if (new_len <= buf.len) {
|
||||
return buf.ptr;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const mem_vtable = std.mem.Allocator.VTable{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
.free = free,
|
||||
.remap = remap,
|
||||
};
|
||||
|
||||
pub const mem = std.mem.Allocator{
|
||||
@ -2948,7 +2959,7 @@ pub fn setShaderValueMatrix(shader: Shader, locIndex: i32, mat: Matrix) void {
|
||||
cdef.SetShaderValueMatrix(shader, @as(c_int, locIndex), mat);
|
||||
}
|
||||
|
||||
/// Set shader uniform value for texture (sampler2d)
|
||||
/// Set shader uniform value and bind the texture (sampler2d)
|
||||
pub fn setShaderValueTexture(shader: Shader, locIndex: i32, texture: Texture2D) void {
|
||||
cdef.SetShaderValueTexture(shader, @as(c_int, locIndex), texture);
|
||||
}
|
||||
@ -3308,6 +3319,11 @@ pub fn getCharPressed() i32 {
|
||||
return @as(i32, cdef.GetCharPressed());
|
||||
}
|
||||
|
||||
/// Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
|
||||
pub fn getKeyName(key: KeyboardKey) [*:0]const u8 {
|
||||
return std.mem.span(cdef.GetKeyName(key));
|
||||
}
|
||||
|
||||
/// Set a custom key to exit program (default is ESC)
|
||||
pub fn setExitKey(key: KeyboardKey) void {
|
||||
cdef.SetExitKey(key);
|
||||
@ -4439,36 +4455,36 @@ pub fn textFindIndex(text: [*:0]const u8, find: [*:0]const u8) i32 {
|
||||
}
|
||||
|
||||
/// Get upper case version of provided string
|
||||
pub fn textToUpper(text: [*:0]const u8) [*:0]const u8 {
|
||||
pub fn textToUpper(text: [*:0]const u8) [*:0]u8 {
|
||||
return std.mem.span(cdef.TextToUpper(@as([*c]const u8, @ptrCast(text))));
|
||||
}
|
||||
|
||||
/// Get lower case version of provided string
|
||||
pub fn textToLower(text: [*:0]const u8) [*:0]const u8 {
|
||||
pub fn textToLower(text: [*:0]const u8) [*:0]u8 {
|
||||
return std.mem.span(cdef.TextToLower(@as([*c]const u8, @ptrCast(text))));
|
||||
}
|
||||
|
||||
/// Get Pascal case notation version of provided string
|
||||
pub fn textToPascal(text: [*:0]const u8) [*:0]const u8 {
|
||||
pub fn textToPascal(text: [*:0]const u8) [*:0]u8 {
|
||||
return std.mem.span(cdef.TextToPascal(@as([*c]const u8, @ptrCast(text))));
|
||||
}
|
||||
|
||||
/// Get Snake case notation version of provided string
|
||||
pub fn textToSnake(text: [*:0]const u8) [*:0]const u8 {
|
||||
pub fn textToSnake(text: [*:0]const u8) [*:0]u8 {
|
||||
return std.mem.span(cdef.TextToSnake(@as([*c]const u8, @ptrCast(text))));
|
||||
}
|
||||
|
||||
/// Get Camel case notation version of provided string
|
||||
pub fn textToCamel(text: [*:0]const u8) [*:0]const u8 {
|
||||
pub fn textToCamel(text: [*:0]const u8) [*:0]u8 {
|
||||
return std.mem.span(cdef.TextToCamel(@as([*c]const u8, @ptrCast(text))));
|
||||
}
|
||||
|
||||
/// Get integer value from text (negative values not supported)
|
||||
/// Get integer value from text
|
||||
pub fn textToInteger(text: [*:0]const u8) i32 {
|
||||
return @as(i32, cdef.TextToInteger(@as([*c]const u8, @ptrCast(text))));
|
||||
}
|
||||
|
||||
/// Get float value from text (negative values not supported)
|
||||
/// Get float value from text
|
||||
pub fn textToFloat(text: [*:0]const u8) f32 {
|
||||
return cdef.TextToFloat(@as([*c]const u8, @ptrCast(text)));
|
||||
}
|
||||
@ -5088,7 +5104,7 @@ pub fn setAudioStreamCallback(stream: AudioStream, callback: AudioCallback) void
|
||||
cdef.SetAudioStreamCallback(stream, callback);
|
||||
}
|
||||
|
||||
/// Attach audio stream processor to stream, receives the samples as 'float'
|
||||
/// Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)
|
||||
pub fn attachAudioStreamProcessor(stream: AudioStream, processor: AudioCallback) void {
|
||||
cdef.AttachAudioStreamProcessor(stream, processor);
|
||||
}
|
||||
@ -5098,7 +5114,7 @@ pub fn detachAudioStreamProcessor(stream: AudioStream, processor: AudioCallback)
|
||||
cdef.DetachAudioStreamProcessor(stream, processor);
|
||||
}
|
||||
|
||||
/// Attach audio stream processor to the entire audio pipeline, receives the samples as 'float'
|
||||
/// Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)
|
||||
pub fn attachAudioMixedProcessor(processor: AudioCallback) void {
|
||||
cdef.AttachAudioMixedProcessor(processor);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ pub extern "c" fn Vector2SubtractValue(v: rl.Vector2, sub: f32) rl.Vector2;
|
||||
pub extern "c" fn Vector2Length(v: rl.Vector2) f32;
|
||||
pub extern "c" fn Vector2LengthSqr(v: rl.Vector2) f32;
|
||||
pub extern "c" fn Vector2DotProduct(v1: rl.Vector2, v2: rl.Vector2) f32;
|
||||
pub extern "c" fn Vector2CrossProduct(v1: rl.Vector2, v2: rl.Vector2) f32;
|
||||
pub extern "c" fn Vector2Distance(v1: rl.Vector2, v2: rl.Vector2) f32;
|
||||
pub extern "c" fn Vector2DistanceSqr(v1: rl.Vector2, v2: rl.Vector2) f32;
|
||||
pub extern "c" fn Vector2Angle(v1: rl.Vector2, v2: rl.Vector2) f32;
|
||||
|
49
lib/raymath.h
vendored
49
lib/raymath.h
vendored
@ -32,7 +32,7 @@
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2015-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.
|
||||
@ -304,6 +304,14 @@ RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate two vectors cross product
|
||||
RMAPI float Vector2CrossProduct(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result = (v1.x*v2.y - v1.y*v2.x);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate distance between two vectors
|
||||
RMAPI float Vector2Distance(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
@ -320,8 +328,9 @@ RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate angle between two vectors
|
||||
// NOTE: Angle is calculated from origin point (0, 0)
|
||||
// Calculate the signed angle from v1 to v2, relative to the origin (0, 0)
|
||||
// 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)
|
||||
{
|
||||
float result = 0.0f;
|
||||
@ -1459,19 +1468,35 @@ RMAPI int Vector4Equals(Vector4 p, Vector4 q)
|
||||
RMAPI float MatrixDeterminant(Matrix mat)
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
/*
|
||||
// Cache the matrix values (speed optimization)
|
||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
||||
float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
|
||||
|
||||
// NOTE: It takes 72 multiplication to calculate 4x4 matrix determinant
|
||||
result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
|
||||
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
|
||||
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
|
||||
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
|
||||
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
|
||||
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
|
||||
*/
|
||||
// Using Laplace expansion (https://en.wikipedia.org/wiki/Laplace_expansion),
|
||||
// previous operation can be simplified to 40 multiplications, decreasing matrix
|
||||
// size from 4x4 to 2x2 using minors
|
||||
|
||||
// Cache the matrix values (speed optimization)
|
||||
float m0 = mat.m0, m1 = mat.m1, m2 = mat.m2, m3 = mat.m3;
|
||||
float m4 = mat.m4, m5 = mat.m5, m6 = mat.m6, m7 = mat.m7;
|
||||
float m8 = mat.m8, m9 = mat.m9, m10 = mat.m10, m11 = mat.m11;
|
||||
float m12 = mat.m12, m13 = mat.m13, m14 = mat.m14, m15 = mat.m15;
|
||||
|
||||
result = (m0*((m5*(m10*m15 - m11*m14) - m9*(m6*m15 - m7*m14) + m13*(m6*m11 - m7*m10))) -
|
||||
m4*((m1*(m10*m15 - m11*m14) - m9*(m2*m15 - m3*m14) + m13*(m2*m11 - m3*m10))) +
|
||||
m8*((m1*(m6*m15 - m7*m14) - m5*(m2*m15 - m3*m14) + m13*(m2*m7 - m3*m6))) -
|
||||
m12*((m1*(m6*m11 - m7*m10) - m5*(m2*m11 - m3*m10) + m9*(m2*m7 - m3*m6))));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -2648,7 +2673,7 @@ inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
|
||||
return Vector2Transform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator -= (Vector2& lhs, const Matrix& rhs)
|
||||
inline const Vector2& operator *= (Vector2& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = Vector2Transform(lhs, rhs);
|
||||
return lhs;
|
||||
@ -2656,12 +2681,12 @@ inline const Vector2& operator -= (Vector2& lhs, const Matrix& rhs)
|
||||
|
||||
inline Vector2 operator / (const Vector2& lhs, const float& rhs)
|
||||
{
|
||||
return Vector2Scale(lhs, 1.0f / rhs);
|
||||
return Vector2Scale(lhs, 1.0f/rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector2Scale(lhs, rhs);
|
||||
lhs = Vector2Scale(lhs, 1.0f/rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
@ -2742,7 +2767,7 @@ inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
|
||||
return Vector3Transform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator -= (Vector3& lhs, const Matrix& rhs)
|
||||
inline const Vector3& operator *= (Vector3& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = Vector3Transform(lhs, rhs);
|
||||
return lhs;
|
||||
@ -2750,12 +2775,12 @@ inline const Vector3& operator -= (Vector3& lhs, const Matrix& rhs)
|
||||
|
||||
inline Vector3 operator / (const Vector3& lhs, const float& rhs)
|
||||
{
|
||||
return Vector3Scale(lhs, 1.0f / rhs);
|
||||
return Vector3Scale(lhs, 1.0f/rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector3Scale(lhs, rhs);
|
||||
lhs = Vector3Scale(lhs, 1.0f/rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
@ -2834,12 +2859,12 @@ inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
|
||||
|
||||
inline Vector4 operator / (const Vector4& lhs, const float& rhs)
|
||||
{
|
||||
return Vector4Scale(lhs, 1.0f / rhs);
|
||||
return Vector4Scale(lhs, 1.0f/rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector4Scale(lhs, rhs);
|
||||
lhs = Vector4Scale(lhs, 1.0f/rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,10 @@ pub fn vector2DotProduct(v1: Vector2, v2: Vector2) f32 {
|
||||
return cdef.Vector2DotProduct(v1, v2);
|
||||
}
|
||||
|
||||
pub fn vector2CrossProduct(v1: Vector2, v2: Vector2) f32 {
|
||||
return cdef.Vector2CrossProduct(v1, v2);
|
||||
}
|
||||
|
||||
pub fn vector2Distance(v1: Vector2, v2: Vector2) f32 {
|
||||
return cdef.Vector2Distance(v1, v2);
|
||||
}
|
||||
|
@ -65,8 +65,9 @@ pub extern "c" fn rlSetCullFace(mode: c_int) void;
|
||||
pub extern "c" fn rlEnableScissorTest() void;
|
||||
pub extern "c" fn rlDisableScissorTest() void;
|
||||
pub extern "c" fn rlScissor(x: c_int, y: c_int, width: c_int, height: c_int) void;
|
||||
pub extern "c" fn rlEnableWireMode() void;
|
||||
pub extern "c" fn rlEnablePointMode() void;
|
||||
pub extern "c" fn rlDisablePointMode() void;
|
||||
pub extern "c" fn rlEnableWireMode() void;
|
||||
pub extern "c" fn rlDisableWireMode() void;
|
||||
pub extern "c" fn rlSetLineWidth(width: f32) void;
|
||||
pub extern "c" fn rlGetLineWidth() f32;
|
||||
|
101
lib/rlgl.h
vendored
101
lib/rlgl.h
vendored
@ -3,14 +3,14 @@
|
||||
* rlgl v5.0 - A multi-OpenGL abstraction layer with an immediate-mode style API
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0)
|
||||
* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0, ES 3.0)
|
||||
* that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...)
|
||||
*
|
||||
* ADDITIONAL NOTES:
|
||||
* When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are
|
||||
* initialized on rlglInit() to accumulate vertex data
|
||||
*
|
||||
* When an internal state change is required all the stored vertex data is renderer in batch,
|
||||
* When an internal state change is required all the stored vertex data is rendered in batch,
|
||||
* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch
|
||||
*
|
||||
* Some resources are also loaded for convenience, here the complete list:
|
||||
@ -88,7 +88,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.
|
||||
@ -355,6 +355,9 @@
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
|
||||
#endif
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX 9
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
@ -681,9 +684,10 @@ RLAPI void rlSetCullFace(int mode); // Set face culling mode
|
||||
RLAPI void rlEnableScissorTest(void); // Enable scissor test
|
||||
RLAPI void rlDisableScissorTest(void); // Disable scissor test
|
||||
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
|
||||
RLAPI void rlEnableWireMode(void); // Enable wire mode
|
||||
RLAPI void rlEnablePointMode(void); // Enable point mode
|
||||
RLAPI void rlDisableWireMode(void); // Disable wire (and point) mode
|
||||
RLAPI void rlDisablePointMode(void); // Disable point mode
|
||||
RLAPI void rlEnableWireMode(void); // Enable wire mode
|
||||
RLAPI void rlDisableWireMode(void); // Disable wire mode
|
||||
RLAPI void rlSetLineWidth(float width); // Set the line drawing width
|
||||
RLAPI float rlGetLineWidth(void); // Get the line drawing width
|
||||
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
|
||||
@ -998,6 +1002,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX
|
||||
#endif
|
||||
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
@ -1452,6 +1459,9 @@ void rlBegin(int mode)
|
||||
// NOTE: In all three cases, vertex are accumulated over default internal vertex buffer
|
||||
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode != mode)
|
||||
{
|
||||
// Get current binded texture to preserve it between draw modes change (QUADS <--> TRIANGLES)
|
||||
int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId;
|
||||
|
||||
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0)
|
||||
{
|
||||
// Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
|
||||
@ -1474,13 +1484,16 @@ void rlBegin(int mode)
|
||||
|
||||
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode;
|
||||
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0;
|
||||
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.defaultTextureId;
|
||||
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture; // Preserve active texture
|
||||
}
|
||||
}
|
||||
|
||||
// Finish vertex providing
|
||||
void rlEnd(void)
|
||||
{
|
||||
// Reset texture to default
|
||||
rlSetTexture(RLGL.State.defaultTextureId);
|
||||
|
||||
// NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values,
|
||||
// as well as depth buffer bit-depth (16bit or 24bit or 32bit)
|
||||
// Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits)
|
||||
@ -1884,16 +1897,6 @@ void rlActiveDrawBuffers(int count)
|
||||
else
|
||||
{
|
||||
unsigned int buffers[8] = {
|
||||
#if defined(GRAPHICS_API_OPENGL_ES3)
|
||||
GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_COLOR_ATTACHMENT1_EXT,
|
||||
GL_COLOR_ATTACHMENT2_EXT,
|
||||
GL_COLOR_ATTACHMENT3_EXT,
|
||||
GL_COLOR_ATTACHMENT4_EXT,
|
||||
GL_COLOR_ATTACHMENT5_EXT,
|
||||
GL_COLOR_ATTACHMENT6_EXT,
|
||||
GL_COLOR_ATTACHMENT7_EXT,
|
||||
#else
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
@ -1902,14 +1905,9 @@ void rlActiveDrawBuffers(int count)
|
||||
GL_COLOR_ATTACHMENT5,
|
||||
GL_COLOR_ATTACHMENT6,
|
||||
GL_COLOR_ATTACHMENT7,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES3)
|
||||
glDrawBuffersEXT(count, buffers);
|
||||
#else
|
||||
glDrawBuffers(count, buffers);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "GL: One color buffer active by default");
|
||||
@ -1976,6 +1974,15 @@ void rlEnableWireMode(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disable wire mode
|
||||
void rlDisableWireMode(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||
// NOTE: glPolygonMode() not available on OpenGL ES
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Enable point mode
|
||||
void rlEnablePointMode(void)
|
||||
{
|
||||
@ -1986,8 +1993,8 @@ void rlEnablePointMode(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disable wire mode
|
||||
void rlDisableWireMode(void)
|
||||
// Disable point mode
|
||||
void rlDisablePointMode(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||
// NOTE: glPolygonMode() not available on OpenGL ES
|
||||
@ -2525,11 +2532,11 @@ void rlLoadExtensions(void *loader)
|
||||
|
||||
// Check depth texture support
|
||||
if (strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) RLGL.ExtSupported.texDepth = true;
|
||||
if (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0) RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format
|
||||
if (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0) RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format
|
||||
if (RLGL.ExtSupported.texDepthWebGL) RLGL.ExtSupported.texDepth = true;
|
||||
|
||||
if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL
|
||||
if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL
|
||||
if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL
|
||||
if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL
|
||||
|
||||
// Check texture compression support: DXT
|
||||
if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) ||
|
||||
@ -3054,7 +3061,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
|
||||
|
||||
for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++)
|
||||
{
|
||||
// Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default
|
||||
// Bind current draw call texture, activated as GL_TEXTURE0 and bound to sampler2D texture0 by default
|
||||
glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId);
|
||||
|
||||
if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount);
|
||||
@ -3310,6 +3317,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
|
||||
// Activate Trilinear filtering if mipmaps are available
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount); // user defined mip count would break without this.
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3417,9 +3425,9 @@ unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mi
|
||||
{
|
||||
if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)
|
||||
{
|
||||
if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) ||
|
||||
if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) ||
|
||||
(format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) ||
|
||||
(format == RL_PIXELFORMAT_UNCOMPRESSED_R16) ||
|
||||
(format == RL_PIXELFORMAT_UNCOMPRESSED_R16) ||
|
||||
(format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
|
||||
else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, NULL);
|
||||
}
|
||||
@ -3674,29 +3682,37 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
|
||||
// Read screen pixel data (color buffer)
|
||||
unsigned char *rlReadScreenPixels(int width, int height)
|
||||
{
|
||||
unsigned char *screenData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char));
|
||||
unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char));
|
||||
|
||||
// NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
|
||||
// NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly!
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
|
||||
|
||||
// Flip image vertically!
|
||||
unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char));
|
||||
|
||||
for (int y = height - 1; y >= 0; y--)
|
||||
// NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it!
|
||||
for (int y = height - 1; y >= height / 2; y--)
|
||||
{
|
||||
for (int x = 0; x < (width*4); x++)
|
||||
for (int x = 0; x < (width*4); x += 4)
|
||||
{
|
||||
imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; // Flip line
|
||||
size_t s = ((height - 1) - y)*width*4 + x;
|
||||
size_t e = y*width*4 + x;
|
||||
|
||||
// Set alpha component value to 255 (no trasparent image retrieval)
|
||||
// NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it!
|
||||
if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255;
|
||||
unsigned char r = imgData[s];
|
||||
unsigned char g = imgData[s+1];
|
||||
unsigned char b = imgData[s+2];
|
||||
|
||||
imgData[s] = imgData[e];
|
||||
imgData[s+1] = imgData[e+1];
|
||||
imgData[s+2] = imgData[e+2];
|
||||
imgData[s+3] = 255; // Set alpha component value to 255 (no trasparent image retrieval)
|
||||
|
||||
imgData[e] = r;
|
||||
imgData[e+1] = g;
|
||||
imgData[e+2] = b;
|
||||
imgData[e+3] = 255; // Ditto
|
||||
}
|
||||
}
|
||||
|
||||
RL_FREE(screenData);
|
||||
|
||||
return imgData; // NOTE: image data should be freed
|
||||
}
|
||||
|
||||
@ -3959,7 +3975,7 @@ void rlDrawVertexArrayElements(int offset, int count, const void *buffer)
|
||||
void rlDrawVertexArrayInstanced(int offset, int count, int instances)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glDrawArraysInstanced(GL_TRIANGLES, 0, count, instances);
|
||||
glDrawArraysInstanced(GL_TRIANGLES, offset, count, instances);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -4216,6 +4232,7 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
|
||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
|
||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
|
||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX);
|
||||
|
||||
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
|
||||
|
21
lib/rlgl.zig
21
lib/rlgl.zig
@ -266,6 +266,10 @@ pub const rl_default_shader_attrib_location_normal = @as(i32, 2);
|
||||
pub const rl_default_shader_attrib_location_color = @as(i32, 3);
|
||||
pub const rl_default_shader_attrib_location_tangent = @as(i32, 4);
|
||||
pub const rl_default_shader_attrib_location_texcoord2 = @as(i32, 5);
|
||||
pub const rl_default_shader_attrib_location_indices = @as(i32, 6);
|
||||
pub const rl_default_shader_attrib_location_boneids = @as(i32, 7);
|
||||
pub const rl_default_shader_attrib_location_boneweights = @as(i32, 5);
|
||||
pub const rl_default_shader_attrib_location_instance_tx = @as(i32, 9);
|
||||
|
||||
/// Choose the current matrix to be transformed
|
||||
pub fn rlMatrixMode(mode: i32) void {
|
||||
@ -575,17 +579,22 @@ pub fn rlScissor(x: i32, y: i32, width: i32, height: i32) void {
|
||||
cdef.rlScissor(@as(c_int, x), @as(c_int, y), @as(c_int, width), @as(c_int, height));
|
||||
}
|
||||
|
||||
/// Enable wire mode
|
||||
pub fn rlEnableWireMode() void {
|
||||
cdef.rlEnableWireMode();
|
||||
}
|
||||
|
||||
/// Enable point mode
|
||||
pub fn rlEnablePointMode() void {
|
||||
cdef.rlEnablePointMode();
|
||||
}
|
||||
|
||||
/// Disable wire (and point) mode
|
||||
/// Disable point mode
|
||||
pub fn rlDisablePointMode() void {
|
||||
cdef.rlDisablePointMode();
|
||||
}
|
||||
|
||||
/// Enable wire mode
|
||||
pub fn rlEnableWireMode() void {
|
||||
cdef.rlEnableWireMode();
|
||||
}
|
||||
|
||||
/// Disable wire mode
|
||||
pub fn rlDisableWireMode() void {
|
||||
cdef.rlDisableWireMode();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user