Update to Zig 0.14.0 and raylib 5.6-dev

This commit is contained in:
Nikolas 2025-03-05 18:09:59 +01:00
parent ae7cb3fa93
commit 1b6a05ca3b
No known key found for this signature in database
GPG Key ID: E95F679E3CDD9784
15 changed files with 586 additions and 321 deletions

View File

@ -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",

View File

@ -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,
};

View File

@ -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{

View File

@ -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
View File

@ -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;
}
}

View File

@ -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,
};

View File

@ -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
View File

@ -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)

View File

@ -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);
}

View File

@ -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
View File

@ -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;
}

View File

@ -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);
}

View File

@ -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
View File

@ -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);

View File

@ -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();
}