Merge branch 'master' into embedded-optimizations-pico

This commit is contained in:
Colin James Wood 2026-07-19 14:43:39 +01:00
commit 739b78c43d

View file

@ -108,7 +108,7 @@
#include <stdlib.h> // Required for: srand(), rand(), exit()
#include <stdio.h> // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()]
#include <string.h> // Required for: strlen(), strncpy(), strcmp(), strrchr(), memset(), strcat()
#include <string.h> // Required for: strlen(), strcmp(), strrchr(), memset(), memcpy(), strcat()
#include <stdarg.h> // Required for: va_list, va_start(), va_end() [Used in TraceLog()]
#ifndef PICO_RP2350
@ -1813,7 +1813,6 @@ void UnloadRandomSequence(int *sequence)
}
// Takes a screenshot of current screen
// NOTE: Provided fileName should not contain paths, saving to working directory
void TakeScreenshot(const char *fileName)
{
#if SUPPORT_MODULE_RTEXTURES
@ -1828,7 +1827,8 @@ void TakeScreenshot(const char *fileName)
Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
char path[MAX_FILEPATH_LENGTH] = { 0 };
strncpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName), MAX_FILEPATH_LENGTH - 1);
if (!IsPathAbsolute(fileName)) snprintf(path, MAX_FILEPATH_LENGTH, "%s", TextFormat("%s/%s", CORE.Storage.basePath, fileName));
else snprintf(path, MAX_FILEPATH_LENGTH, "%s", fileName);
ExportImage(image, path); // WARNING: Module required: rtextures
RL_FREE(imgData);
@ -1853,8 +1853,6 @@ void SetConfigFlags(unsigned int flags)
FLAG_SET(CORE.Window.flags, flags);
}
// void OpenURL(const char *url); // Defined per platform
//----------------------------------------------------------------------------------
// Module Functions Definition: Logging system
//----------------------------------------------------------------------------------
@ -1894,12 +1892,12 @@ void TraceLog(int logType, const char *text, ...)
switch (logType)
{
case LOG_TRACE: strncpy(buffer, "TRACE: ", 8); break;
case LOG_DEBUG: strncpy(buffer, "DEBUG: ", 8); break;
case LOG_INFO: strncpy(buffer, "INFO: ", 7); break;
case LOG_WARNING: strncpy(buffer, "WARNING: ", 10); break;
case LOG_ERROR: strncpy(buffer, "ERROR: ", 8); break;
case LOG_FATAL: strncpy(buffer, "FATAL: ", 8); break;
case LOG_TRACE: memcpy(buffer, "TRACE: ", 7); break;
case LOG_DEBUG: memcpy(buffer, "DEBUG: ", 7); break;
case LOG_INFO: memcpy(buffer, "INFO: ", 6); break;
case LOG_WARNING: memcpy(buffer, "WARNING: ", 9); break;
case LOG_ERROR: memcpy(buffer, "ERROR: ", 7); break;
case LOG_FATAL: memcpy(buffer, "FATAL: ", 7); break;
default: break;
}
@ -2072,7 +2070,7 @@ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileN
// Get file name from path
char varFileName[256] = { 0 };
strncpy(varFileName, GetFileNameWithoutExt(fileName), 256 - 1);
snprintf(varFileName, 256, "%s", GetFileNameWithoutExt(fileName));
for (int i = 0; varFileName[i] != '\0'; i++)
{
// Convert variable name to uppercase
@ -2516,7 +2514,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
if (filePath != NULL)
{
strncpy(fileName, GetFileName(filePath), MAX_FILENAME_LENGTH - 1); // Get filename.ext without path
snprintf(fileName, MAX_FILENAME_LENGTH, "%s", GetFileName(filePath)); // Get filename.ext without path
int fileNameLength = (int)strlen(fileName); // Get size in bytes
for (int i = fileNameLength; i > 0; i--) // Reverse search '.'
@ -2533,7 +2531,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
return fileName;
}
// Get directory for a given filePath
// Get directory for a provided filePath
const char *GetDirectoryPath(const char *filePath)
{
/*
@ -2570,7 +2568,6 @@ const char *GetDirectoryPath(const char *filePath)
}
else
{
// NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
char *dirPathPtr = dirPath;
if ((filePath[1] != ':') && (filePath[0] != '\\') && (filePath[0] != '/')) dirPathPtr += 2; // Skip drive letter, "C:"
memcpy(dirPathPtr, filePath, strlen(filePath) - (strlen(lastSlash) - 1));
@ -2581,14 +2578,14 @@ const char *GetDirectoryPath(const char *filePath)
return dirPath;
}
// Get previous directory path for a given path
// Get previous directory path for a provided path
const char *GetPrevDirectoryPath(const char *dirPath)
{
static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 };
memset(prevDirPath, 0, MAX_FILEPATH_LENGTH);
int dirPathLength = (int)strlen(dirPath);
if (dirPathLength <= 3) strncpy(prevDirPath, dirPath, MAX_FILEPATH_LENGTH - 1);
if (dirPathLength <= 3) snprintf(prevDirPath, MAX_FILEPATH_LENGTH, "%s", dirPath);
for (int i = (dirPathLength - 1); (i >= 0) && (dirPathLength > 3); i--)
{
@ -2597,7 +2594,7 @@ const char *GetPrevDirectoryPath(const char *dirPath)
// Check for root: "C:\" or "/"
if (((i == 2) && (dirPath[1] ==':')) || (i == 0)) i++;
strncpy(prevDirPath, dirPath, i);
memcpy(prevDirPath, dirPath, i);
break;
}
}
@ -2831,13 +2828,49 @@ int ChangeDirectory(const char *dirPath)
return result;
}
// Check if given path point to a file
// Check if provided path point to a file
bool IsPathFile(const char *path)
{
struct stat result = { 0 };
stat(path, &result);
bool result = false;
return S_ISREG(result.st_mode);
struct stat info = { 0 };
stat(path, &info);
if (S_ISREG(info.st_mode)) result = true;
return result;
}
// Check if provided path point to a directory
bool IsPathDirectory(const char *path)
{
bool result = false;
if (!IsPathFile(path)) result = true;
return result;
}
// Check if provided path is an absolute path
bool IsPathAbsolute(const char *path)
{
int result = false;
if ((path != NULL) && (path[0] != '\0'))
{
#if defined(_WIN32)
// UNC path (\\server\share)
if ((path[0] == '\\') && (path[1] == '\\')) result = true;
// Drive letter (e.g. C:\ or D:/)
else if (isalpha((unsigned char)path[0]) && (path[1] == ':') &&
((path[2] == '\\') || (path[2] == '/'))) result = true;
#else
// POSIX: must start with /
if (path[0] == '/') result = true;
#endif
}
return result;
}
// Check if fileName is valid for the platform/OS
@ -3271,7 +3304,7 @@ unsigned int *ComputeMD5(const unsigned char *data, int dataSize)
memcpy(msg + newDataSize, &bitsLen, 4); // Append the len in bits at the end of the buffer
// Process the message in successive 512-bit chunks for each 512-bit chunk of message
for (int offset = 0; offset < newDataSize; offset += (512/8))
for (int offset = 0; offset < newDataSize; offset += 64) // 512/8
{
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
unsigned int *w = (unsigned int *)(msg + offset);
@ -3368,16 +3401,16 @@ unsigned int *ComputeSHA1(const unsigned char *data, int dataSize)
msg[newDataSize - 8] = (unsigned char)(bitsLen >> 56);
// Process the message in successive 512-bit chunks
for (int offset = 0; offset < newDataSize; offset += (512/8))
for (int offset = 0; offset < newDataSize; offset += 64) // 512/8
{
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
unsigned int w[80] = { 0 };
for (int i = 0; i < 16; i++)
{
w[i] = (msg[offset + (i*4) + 0] << 24) |
(msg[offset + (i*4) + 1] << 16) |
(msg[offset + (i*4) + 2] << 8) |
(msg[offset + (i*4) + 3]);
w[i] = ((unsigned int)msg[offset + (i*4) + 0] << 24) |
((unsigned int)msg[offset + (i*4) + 1] << 16) |
((unsigned int)msg[offset + (i*4) + 2] << 8) |
((unsigned int)msg[offset + (i*4) + 3]);
}
// Message schedule: extend the sixteen 32-bit words into eighty 32-bit words:
@ -3599,10 +3632,14 @@ AutomationEventList LoadAutomationEventList(const char *fileName)
case 'c': sscanf(buffer, "c %i", &list.count); break;
case 'e':
{
sscanf(buffer, "e %d %d %d %d %d %d %[^\n]s", &list.events[counter].frame, &list.events[counter].type,
&list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
if (counter < list.capacity)
{
sscanf(buffer, "e %d %d %d %d %d %d %63[^\n]s", &list.events[counter].frame, &list.events[counter].type,
&list.events[counter].params[0], &list.events[counter].params[1], &list.events[counter].params[2], &list.events[counter].params[3], eventDesc);
counter++;
counter++;
}
else TRACELOG(LOG_WARNING, "AUTOMATION: Event goes beyond automated list capacity (MAX: %u): %s", list.capacity, buffer);
} break;
default: break;
}
@ -3935,7 +3972,7 @@ bool IsGamepadAvailable(int gamepad)
{
bool result = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
return result;
}
@ -3955,7 +3992,7 @@ bool IsGamepadButtonPressed(int gamepad, int button)
{
bool pressed = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true;
}
@ -3968,7 +4005,7 @@ bool IsGamepadButtonDown(int gamepad, int button)
{
bool down = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1) down = true;
}
@ -3981,7 +4018,7 @@ bool IsGamepadButtonReleased(int gamepad, int button)
{
bool released = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true;
}
@ -3994,7 +4031,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
{
bool up = false;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS))
{
if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0) up = true;
}
@ -4024,7 +4061,7 @@ float GetGamepadAxisMovement(int gamepad, int axis)
{
float value = ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))? -1.0f : 0.0f;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXES))
if ((gamepad >= 0) && (gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXES))
{
float movement = (value < 0.0f)? CORE.Input.Gamepad.axisState[gamepad][axis] : fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]);
@ -4208,7 +4245,7 @@ Vector2 GetTouchPosition(int index)
return position;
}
// Get touch point identifier for given index
// Get touch point identifier for provided index
int GetTouchPointId(int index)
{
int id = -1;