8 Commits

Author SHA1 Message Date
Ray
11e3e6e0b9 REVIEWED: Formating, tested sound examples 2026-02-21 09:09:43 +01:00
0c91f230fd Audio: Fix a glitch at the end of a sound. (#5578)
This is happening because the processing function keeps reading audio
data from the AudioBuffer even after it has been marked as stopped.

There is also an error in ReadAudioBufferFramesInInternalFormat() where
if it is called on a stopped sound, it'll still return audio frames.
This has also been addressed with this commit.
2026-02-21 08:04:32 +01:00
005ff74eb0 Audio: Improvements to device configuration (#5577)
* Audio: Stop setting capture config options.

Since the device is being configured as a playback device, all capture
config options are unused and therefore need to not be set.

* Audio: Stop pre-silencing the miniaudio output buffer.

raylib already manually silences the output buffer prior to mixing so
there is no reason to have miniaudio also do it. It can therefore be
disabled via the device config to make data processing slightly more
efficient.

* Audio: Stop forcing fixed sized processing callbacks.

There is no requirement for raylib to have guaranteed fixed sized
audio processing. By disabling it, audio processing can be made more
efficient by not having to run the data through an internal intermediary
buffer.

* Audio: Make the period size (latency) configurable.

The default period size is 10ms, but this is inappropriate for certain
platforms so it is useful to be able to allow those platforms to
configure the period size as required.

* Audio: Fix documentation for pan.

The pan if -1..1, not 0..1.
2026-02-21 08:02:40 +01:00
Ray
c519e9f566 REVIEWED: Simplified char ** approach 2026-02-20 23:56:11 +01:00
Ray
09f22f3c86 REVIEWED: Avoid const char ** usage (aligned with raylib) 2026-02-20 23:02:43 +01:00
29b9c050c7 fix example (#5575) 2026-02-20 20:18:28 +01:00
Ray
0343cb6a37 Update rcore_desktop_sdl.c 2026-02-20 18:47:53 +01:00
d148d9515b Fix text input on SDL3 (#5574) 2026-02-20 18:44:34 +01:00
7 changed files with 121 additions and 114 deletions

View File

@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
// Basic controls set // Basic controls set
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
// Advance controls set // Advance controls set
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
static int ColorToInt(Color color); // Returns hexadecimal value for a Color static int ColorToInt(Color color); // Returns hexadecimal value for a Color
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
static int TextToInteger(const char *text); // Get integer value from text static int TextToInteger(const char *text); // Get integer value from text
static float TextToFloat(const char *text); // Get float value from text static float TextToFloat(const char *text); // Get float value from text
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
// Tab Bar control // Tab Bar control
// NOTE: Using GuiToggle() for the TABS // NOTE: Using GuiToggle() for the TABS
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
{ {
#define RAYGUI_TABBAR_ITEM_WIDTH 148 #define RAYGUI_TABBAR_ITEM_WIDTH 148
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, rows); char **items = GuiTextSplit(text, ';', &itemCount, rows);
int prevRow = rows[0]; int prevRow = rows[0];
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
if (*active < 0) *active = 0; if (*active < 0) *active = 0;
else if (*active > (itemCount - 1)) *active = itemCount - 1; else if (*active > (itemCount - 1)) *active = itemCount - 1;
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
Rectangle boundsOpen = bounds; Rectangle boundsOpen = bounds;
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
{ {
int result = 0; int result = 0;
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
} }
// List View control with extended parameters // List View control with extended parameters
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
{ {
int result = 0; int result = 0;
GuiState state = guiState; GuiState state = guiState;
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
int result = -1; int result = -1;
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
// Get text divided into lines (by line-breaks '\n') // Get text divided into lines (by line-breaks '\n')
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
static const char **GetTextLines(const char *text, int *count) static char **GetTextLines(const char *text, int *count)
{ {
#define RAYGUI_MAX_TEXT_LINES 128 #define RAYGUI_MAX_TEXT_LINES 128
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
int textLength = (int)strlen(text); int textLength = (int)strlen(text);
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
lines[0] = text; lines[0] = text;
*count = 1; *count = 1;
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
{ {
if (text[i] == '\n') if ((text[i] == '\n') && ((i + 1) < textLength))
{ {
k++; lines[*count] = &text[i + 1];
lines[k] = &text[i + 1]; // WARNING: next value is valid?
*count += 1; *count += 1;
} }
} }
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
// WARNING: GuiTextSplit() function can't be used now because it can have already been used // WARNING: GuiTextSplit() function can't be used now because it can have already been used
// before the GuiDrawText() call and its buffer is static, it would be overriden :( // before the GuiDrawText() call and its buffer is static, it would be overriden :(
int lineCount = 0; int lineCount = 0;
const char **lines = GetTextLines(text, &lineCount); char **lines = GetTextLines(text, &lineCount);
// Text style variables // Text style variables
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
// Split controls text into multiple strings // Split controls text into multiple strings
// Also check for multiple columns (required by GuiToggleGroup()) // Also check for multiple columns (required by GuiToggleGroup())
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
#endif #endif
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
result[0] = buffer; result[0] = buffer;
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
} }
// Split string into multiple strings // Split string into multiple strings
const char **TextSplit(const char *text, char delimiter, int *count) char **TextSplit(const char *text, char delimiter, int *count)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,

View File

@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
// Basic controls set // Basic controls set
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
// Advance controls set // Advance controls set
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
static int ColorToInt(Color color); // Returns hexadecimal value for a Color static int ColorToInt(Color color); // Returns hexadecimal value for a Color
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
static int TextToInteger(const char *text); // Get integer value from text static int TextToInteger(const char *text); // Get integer value from text
static float TextToFloat(const char *text); // Get float value from text static float TextToFloat(const char *text); // Get float value from text
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
// Tab Bar control // Tab Bar control
// NOTE: Using GuiToggle() for the TABS // NOTE: Using GuiToggle() for the TABS
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
{ {
#define RAYGUI_TABBAR_ITEM_WIDTH 148 #define RAYGUI_TABBAR_ITEM_WIDTH 148
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, rows); char **items = GuiTextSplit(text, ';', &itemCount, rows);
int prevRow = rows[0]; int prevRow = rows[0];
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
if (*active < 0) *active = 0; if (*active < 0) *active = 0;
else if (*active > (itemCount - 1)) *active = itemCount - 1; else if (*active > (itemCount - 1)) *active = itemCount - 1;
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
Rectangle boundsOpen = bounds; Rectangle boundsOpen = bounds;
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
{ {
int result = 0; int result = 0;
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
} }
// List View control with extended parameters // List View control with extended parameters
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
{ {
int result = 0; int result = 0;
GuiState state = guiState; GuiState state = guiState;
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
int result = -1; int result = -1;
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
// Get text divided into lines (by line-breaks '\n') // Get text divided into lines (by line-breaks '\n')
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
static const char **GetTextLines(const char *text, int *count) static char **GetTextLines(const char *text, int *count)
{ {
#define RAYGUI_MAX_TEXT_LINES 128 #define RAYGUI_MAX_TEXT_LINES 128
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
int textLength = (int)strlen(text); int textLength = (int)strlen(text);
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
lines[0] = text; lines[0] = text;
*count = 1; *count = 1;
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
{ {
if (text[i] == '\n') if ((text[i] == '\n') && ((i + 1) < textLength))
{ {
k++; lines[*count] = &text[i + 1];
lines[k] = &text[i + 1]; // WARNING: next value is valid?
*count += 1; *count += 1;
} }
} }
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
// WARNING: GuiTextSplit() function can't be used now because it can have already been used // WARNING: GuiTextSplit() function can't be used now because it can have already been used
// before the GuiDrawText() call and its buffer is static, it would be overriden :( // before the GuiDrawText() call and its buffer is static, it would be overriden :(
int lineCount = 0; int lineCount = 0;
const char **lines = GetTextLines(text, &lineCount); char **lines = GetTextLines(text, &lineCount);
// Text style variables // Text style variables
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
// Split controls text into multiple strings // Split controls text into multiple strings
// Also check for multiple columns (required by GuiToggleGroup()) // Also check for multiple columns (required by GuiToggleGroup())
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
#endif #endif
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
result[0] = buffer; result[0] = buffer;
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
} }
// Split string into multiple strings // Split string into multiple strings
const char **TextSplit(const char *text, char delimiter, int *count) char **TextSplit(const char *text, char delimiter, int *count)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,

View File

@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
// Basic controls set // Basic controls set
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
// Advance controls set // Advance controls set
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
static int ColorToInt(Color color); // Returns hexadecimal value for a Color static int ColorToInt(Color color); // Returns hexadecimal value for a Color
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
static int TextToInteger(const char *text); // Get integer value from text static int TextToInteger(const char *text); // Get integer value from text
static float TextToFloat(const char *text); // Get float value from text static float TextToFloat(const char *text); // Get float value from text
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
// Tab Bar control // Tab Bar control
// NOTE: Using GuiToggle() for the TABS // NOTE: Using GuiToggle() for the TABS
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
{ {
#define RAYGUI_TABBAR_ITEM_WIDTH 148 #define RAYGUI_TABBAR_ITEM_WIDTH 148
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, rows); char **items = GuiTextSplit(text, ';', &itemCount, rows);
int prevRow = rows[0]; int prevRow = rows[0];
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
if (*active < 0) *active = 0; if (*active < 0) *active = 0;
else if (*active > (itemCount - 1)) *active = itemCount - 1; else if (*active > (itemCount - 1)) *active = itemCount - 1;
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
Rectangle boundsOpen = bounds; Rectangle boundsOpen = bounds;
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
{ {
int result = 0; int result = 0;
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
} }
// List View control with extended parameters // List View control with extended parameters
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
{ {
int result = 0; int result = 0;
GuiState state = guiState; GuiState state = guiState;
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
int result = -1; int result = -1;
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
// Get text divided into lines (by line-breaks '\n') // Get text divided into lines (by line-breaks '\n')
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
static const char **GetTextLines(const char *text, int *count) static char **GetTextLines(const char *text, int *count)
{ {
#define RAYGUI_MAX_TEXT_LINES 128 #define RAYGUI_MAX_TEXT_LINES 128
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
int textLength = (int)strlen(text); int textLength = (int)strlen(text);
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
lines[0] = text; lines[0] = text;
*count = 1; *count = 1;
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
{ {
if (text[i] == '\n') if ((text[i] == '\n') && ((i + 1) < textLength))
{ {
k++; lines[*count] = &text[i + 1];
lines[k] = &text[i + 1]; // WARNING: next value is valid?
*count += 1; *count += 1;
} }
} }
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
// WARNING: GuiTextSplit() function can't be used now because it can have already been used // WARNING: GuiTextSplit() function can't be used now because it can have already been used
// before the GuiDrawText() call and its buffer is static, it would be overriden :( // before the GuiDrawText() call and its buffer is static, it would be overriden :(
int lineCount = 0; int lineCount = 0;
const char **lines = GetTextLines(text, &lineCount); char **lines = GetTextLines(text, &lineCount);
// Text style variables // Text style variables
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
// Split controls text into multiple strings // Split controls text into multiple strings
// Also check for multiple columns (required by GuiToggleGroup()) // Also check for multiple columns (required by GuiToggleGroup())
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
#endif #endif
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
result[0] = buffer; result[0] = buffer;
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
} }
// Split string into multiple strings // Split string into multiple strings
const char **TextSplit(const char *text, char delimiter, int *count) char **TextSplit(const char *text, char delimiter, int *count)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,

View File

@ -772,7 +772,7 @@ RAYGUIAPI int GuiWindowBox(Rectangle bounds, const char *title);
RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name RAYGUIAPI int GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text RAYGUIAPI int GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls RAYGUIAPI int GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
RAYGUIAPI int GuiTabBar(Rectangle bounds, const char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1 RAYGUIAPI int GuiTabBar(Rectangle bounds, char **text, int count, int *active); // Tab Bar control, returns TAB to be closed or -1
RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control RAYGUIAPI int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll, Rectangle *view); // Scroll Panel control
// Basic controls set // Basic controls set
@ -800,7 +800,7 @@ RAYGUIAPI int GuiGrid(Rectangle bounds, const char *text, float spacing, int sub
// Advance controls set // Advance controls set
RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *active); // List View control
RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters RAYGUIAPI int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus); // List View with extended parameters
RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, bool *secretViewActive); // Text Input Box control, ask for text, supports secret
RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls) RAYGUIAPI int GuiColorPicker(Rectangle bounds, const char *text, Color *color); // Color Picker control (multiple color controls)
@ -1526,7 +1526,7 @@ static Color GetColor(int hexValue); // Returns a Color struct fr
static int ColorToInt(Color color); // Returns hexadecimal value for a Color static int ColorToInt(Color color); // Returns hexadecimal value for a Color
static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed' static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings static char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
static int TextToInteger(const char *text); // Get integer value from text static int TextToInteger(const char *text); // Get integer value from text
static float TextToFloat(const char *text); // Get float value from text static float TextToFloat(const char *text); // Get float value from text
@ -1549,7 +1549,7 @@ static const char *GetTextIcon(const char *text, int *iconId); // Get text icon
static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, Color tint); // Gui draw text using default font
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow); // Split controls text into multiple strings
static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
@ -1783,7 +1783,7 @@ int GuiPanel(Rectangle bounds, const char *text)
// Tab Bar control // Tab Bar control
// NOTE: Using GuiToggle() for the TABS // NOTE: Using GuiToggle() for the TABS
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active) int GuiTabBar(Rectangle bounds, char **text, int count, int *active)
{ {
#define RAYGUI_TABBAR_ITEM_WIDTH 148 #define RAYGUI_TABBAR_ITEM_WIDTH 148
@ -2168,7 +2168,7 @@ int GuiToggleGroup(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 }; int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, rows); char **items = GuiTextSplit(text, ';', &itemCount, rows);
int prevRow = rows[0]; int prevRow = rows[0];
@ -2212,7 +2212,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers) // Get substrings items from text (items pointers)
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -2356,7 +2356,7 @@ int GuiComboBox(Rectangle bounds, const char *text, int *active)
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
if (*active < 0) *active = 0; if (*active < 0) *active = 0;
else if (*active > (itemCount - 1)) *active = itemCount - 1; else if (*active > (itemCount - 1)) *active = itemCount - 1;
@ -2422,7 +2422,7 @@ int GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMod
// Get substrings items from text (items pointers, lengths and count) // Get substrings items from text (items pointers, lengths and count)
int itemCount = 0; int itemCount = 0;
const char **items = GuiTextSplit(text, ';', &itemCount, NULL); char **items = GuiTextSplit(text, ';', &itemCount, NULL);
Rectangle boundsOpen = bounds; Rectangle boundsOpen = bounds;
boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING)); boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
@ -3602,7 +3602,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
{ {
int result = 0; int result = 0;
int itemCount = 0; int itemCount = 0;
const char **items = NULL; char **items = NULL;
if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL); if (text != NULL) items = GuiTextSplit(text, ';', &itemCount, NULL);
@ -3612,7 +3612,7 @@ int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int *activ
} }
// List View control with extended parameters // List View control with extended parameters
int GuiListViewEx(Rectangle bounds, const char **text, int count, int *scrollIndex, int *active, int *focus) int GuiListViewEx(Rectangle bounds, char **text, int count, int *scrollIndex, int *active, int *focus)
{ {
int result = 0; int result = 0;
GuiState state = guiState; GuiState state = guiState;
@ -4140,7 +4140,7 @@ int GuiMessageBox(Rectangle bounds, const char *title, const char *message, cons
int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button int result = -1; // Returns clicked button from buttons list, 0 refers to closed window button
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
@ -4199,7 +4199,7 @@ int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, co
int result = -1; int result = -1;
int buttonCount = 0; int buttonCount = 0;
const char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL); char **buttonsText = GuiTextSplit(buttons, ';', &buttonCount, NULL);
Rectangle buttonBounds = { 0 }; Rectangle buttonBounds = { 0 };
buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING; buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
@ -5119,11 +5119,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
// Get text divided into lines (by line-breaks '\n') // Get text divided into lines (by line-breaks '\n')
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator! // WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
static const char **GetTextLines(const char *text, int *count) static char **GetTextLines(const char *text, int *count)
{ {
#define RAYGUI_MAX_TEXT_LINES 128 #define RAYGUI_MAX_TEXT_LINES 128
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 }; static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
int textLength = (int)strlen(text); int textLength = (int)strlen(text);
@ -5131,12 +5131,11 @@ static const char **GetTextLines(const char *text, int *count)
lines[0] = text; lines[0] = text;
*count = 1; *count = 1;
for (int i = 0, k = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++) for (int i = 0; (i < textLength) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
{ {
if (text[i] == '\n') if ((text[i] == '\n') && ((i + 1) < textLength))
{ {
k++; lines[*count] = &text[i + 1];
lines[k] = &text[i + 1]; // WARNING: next value is valid?
*count += 1; *count += 1;
} }
} }
@ -5194,7 +5193,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
// WARNING: GuiTextSplit() function can't be used now because it can have already been used // WARNING: GuiTextSplit() function can't be used now because it can have already been used
// before the GuiDrawText() call and its buffer is static, it would be overriden :( // before the GuiDrawText() call and its buffer is static, it would be overriden :(
int lineCount = 0; int lineCount = 0;
const char **lines = GetTextLines(text, &lineCount); char **lines = GetTextLines(text, &lineCount);
// Text style variables // Text style variables
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT); //int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
@ -5444,7 +5443,7 @@ static void GuiTooltip(Rectangle controlRec)
// Split controls text into multiple strings // Split controls text into multiple strings
// Also check for multiple columns (required by GuiToggleGroup()) // Also check for multiple columns (required by GuiToggleGroup())
static const char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow) static char **GuiTextSplit(const char *text, char delimiter, int *count, int *textRow)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
@ -5463,8 +5462,8 @@ static const char **GuiTextSplit(const char *text, char delimiter, int *count, i
#define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024 #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
#endif #endif
static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data) static char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL }; // String pointers array (points to buffer data)
static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added) static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 }; // Buffer data (text input copy with '\0' added)
memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE); memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
result[0] = buffer; result[0] = buffer;
@ -5863,7 +5862,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
} }
// Split string into multiple strings // Split string into multiple strings
const char **TextSplit(const char *text, char delimiter, int *count) char **TextSplit(const char *text, char delimiter, int *count)
{ {
// NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter) // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
// inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated, // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,

View File

@ -303,6 +303,7 @@
#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit) #define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit)
#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo #define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
#define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default) #define AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default)
#define AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES 0 // Device period size (controls latency, 0 defaults to 10ms)
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels

View File

@ -2016,6 +2016,15 @@ int InitPlatform(void)
// Init window // Init window
#if defined(USING_VERSION_SDL3) #if defined(USING_VERSION_SDL3)
platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags); platform.window = SDL_CreateWindow(CORE.Window.title, CORE.Window.screen.width, CORE.Window.screen.height, flags);
// NOTE: SDL3 no longer enables text input by default,
// it is needed to be enabled manually to keep GetCharPressed() working
// REF: https://github.com/libsdl-org/SDL/commit/72fc6f86e5d605a3787222bc7dc18c5379047f4a
const char *enableOSK = SDL_GetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD);
if (enableOSK == NULL) SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0");
if (!SDL_StartTextInput(platform.window)) TRACELOG(LOG_WARNING, "SDL: Failed to start text input: %s", SDL_GetError());
if (enableOSK == NULL) SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, NULL);
#else #else
platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags); platform.window = SDL_CreateWindow(CORE.Window.title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, CORE.Window.screen.width, CORE.Window.screen.height, flags);
#endif #endif

View File

@ -290,6 +290,9 @@ typedef struct tagBITMAPINFOHEADER {
#ifndef AUDIO_DEVICE_SAMPLE_RATE #ifndef AUDIO_DEVICE_SAMPLE_RATE
#define AUDIO_DEVICE_SAMPLE_RATE 0 // Device output sample rate #define AUDIO_DEVICE_SAMPLE_RATE 0 // Device output sample rate
#endif #endif
#ifndef AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES
#define AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES 0 // Device latency. 0 defaults to 10ms
#endif
#ifndef MAX_AUDIO_BUFFER_POOL_CHANNELS #ifndef MAX_AUDIO_BUFFER_POOL_CHANNELS
#define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels #define MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Audio pool channels
@ -349,7 +352,7 @@ struct rAudioBuffer {
float volume; // Audio buffer volume float volume; // Audio buffer volume
float pitch; // Audio buffer pitch float pitch; // Audio buffer pitch
float pan; // Audio buffer pan (0.0f to 1.0f) float pan; // Audio buffer pan (-1.0f to 1.0f)
bool playing; // Audio buffer state: AUDIO_PLAYING bool playing; // Audio buffer state: AUDIO_PLAYING
bool paused; // Audio buffer state: AUDIO_PAUSED bool paused; // Audio buffer state: AUDIO_PAUSED
@ -477,12 +480,12 @@ void InitAudioDevice(void)
config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device config.playback.pDeviceID = NULL; // NULL for the default playback AUDIO.System.device
config.playback.format = AUDIO_DEVICE_FORMAT; config.playback.format = AUDIO_DEVICE_FORMAT;
config.playback.channels = AUDIO_DEVICE_CHANNELS; config.playback.channels = AUDIO_DEVICE_CHANNELS;
config.capture.pDeviceID = NULL; // NULL for the default capture AUDIO.System.device
config.capture.format = ma_format_s16;
config.capture.channels = 1;
config.sampleRate = AUDIO_DEVICE_SAMPLE_RATE; config.sampleRate = AUDIO_DEVICE_SAMPLE_RATE;
config.periodSizeInFrames = AUDIO_DEVICE_PERIOD_SIZE_IN_FRAMES;
config.dataCallback = OnSendAudioDataToDevice; config.dataCallback = OnSendAudioDataToDevice;
config.pUserData = NULL; config.pUserData = NULL;
config.noPreSilencedOutputBuffer = true; // raylib pre-silences the output buffer manually
config.noFixedSizedCallback = true; // raylib does not require fixed sized callback guarantees. This bypasses an internal intermediary buffer
result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device); result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device);
if (result != MA_SUCCESS) if (result != MA_SUCCESS)
@ -2374,6 +2377,9 @@ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage)
// Reads audio data from an AudioBuffer object in internal format // Reads audio data from an AudioBuffer object in internal format
static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount) static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
{ {
// Don't read anything if the sound is not playing
if (!audioBuffer->playing) return 0;
// Using audio buffer callback // Using audio buffer callback
if (audioBuffer->callback) if (audioBuffer->callback)
{ {
@ -2510,27 +2516,22 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
// When the guess is overestimated, that's when it gets more complicated. In this case, any overflow // When the guess is overestimated, that's when it gets more complicated. In this case, any overflow
// needs to be stored in a buffer for later processing by the next read. // needs to be stored in a buffer for later processing by the next read.
ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut) * outputFramesToProcessThisIteration); ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut) * outputFramesToProcessThisIteration);
if (estimatedInputFrameCount == 0) if (estimatedInputFrameCount == 0) estimatedInputFrameCount = 1; // Make sure at least one input frame is read.
{ if (estimatedInputFrameCount > inputBufferFrameCap) estimatedInputFrameCount = inputBufferFrameCap;
estimatedInputFrameCount = 1; // Make sure at least one input frame is read.
}
if (estimatedInputFrameCount > inputBufferFrameCap) ma_uint32 inputFramesInInternalFormatCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount);
{
estimatedInputFrameCount = inputBufferFrameCap;
}
estimatedInputFrameCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount); ma_uint64 inputFramesProcessedThisIteration = inputFramesInInternalFormatCount;
ma_uint64 inputFramesProcessedThisIteration = estimatedInputFrameCount;
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
if (estimatedInputFrameCount > inputFramesProcessedThisIteration) totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration;
if (inputFramesInInternalFormatCount > inputFramesProcessedThisIteration)
{ {
// Getting here means the estimated input frame count was overestimated. The residual needs // Getting here means the estimated input frame count was overestimated. The residual needs
// be stored for later use. // be stored for later use.
ma_uint64 residualFrameCount = estimatedInputFrameCount - inputFramesProcessedThisIteration; ma_uint64 residualFrameCount = inputFramesInInternalFormatCount - inputFramesProcessedThisIteration;
// A safety check to make sure the capacity of the residual cache is not exceeded. // A safety check to make sure the capacity of the residual cache is not exceeded.
if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY) if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY)
@ -2542,7 +2543,7 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
audioBuffer->converterResidualCount = residualFrameCount; audioBuffer->converterResidualCount = residualFrameCount;
} }
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; if (inputFramesInInternalFormatCount < estimatedInputFrameCount) break; // Reached the end of the sound
} }
} }