4 Commits

Author SHA1 Message Date
bb78e98a71 Remove forced normalization of normal vectors in rlNormal3f, assume the user has set the correct input for the shader. (#5703) 2026-03-29 00:39:23 +01:00
5915584cd6 Fix zig build and minor improvements (#5702)
- Added zig-pkg directory to gitignore
- Brought min zig version to recent nightly release these improvements
  were completed on
- For linux build, only add rglfw.c if the platform is glfw
- Add a None option to the LinuxDisplayBackend
- Fixed xcode-frameworks dependency and update to using most recent
  commit hash
2026-03-29 00:38:45 +01:00
Ray
8c44ea5032 Code gardening
REVIEWED: Some early returns, avoid if possible
REVIEWED: Some return variable names, for consistency, rename `success` to `result`
2026-03-29 00:37:01 +01:00
Ray
5fad835ff1 Update rcore.c 2026-03-28 23:54:51 +01:00
10 changed files with 203 additions and 186 deletions

1
.gitignore vendored
View File

@ -118,6 +118,7 @@ GTAGS
# Zig programming language # Zig programming language
.zig-cache/ .zig-cache/
zig-cache/ zig-cache/
zig-pkg/
zig-out/ zig-out/
build/ build/
build-*/ build-*/

View File

@ -2,7 +2,7 @@ const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
/// Minimum supported version of Zig /// Minimum supported version of Zig
const min_ver = "0.16.0-dev.2349+204fa8959"; const min_ver = "0.16.0-dev.3013+abd131e33";
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str; const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
const emccOutputFile = "index.html"; const emccOutputFile = "index.html";
@ -264,7 +264,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
setDesktopPlatform(raylib, .android); setDesktopPlatform(raylib, .android);
} else { } else {
try c_source_files.append(b.allocator, "src/rglfw.c"); switch (options.platform) {
.glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
.rgfw, .sdl, .drm, .android => {},
}
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) { if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
raylib.root_module.addCMacro("_GLFW_X11", ""); raylib.root_module.addCMacro("_GLFW_X11", "");
@ -434,6 +437,7 @@ pub const OpenglVersion = enum {
}; };
pub const LinuxDisplayBackend = enum { pub const LinuxDisplayBackend = enum {
None,
X11, X11,
Wayland, Wayland,
Both, Both,

View File

@ -7,8 +7,8 @@
.dependencies = .{ .dependencies = .{
.xcode_frameworks = .{ .xcode_frameworks = .{
.url = "https://pkg.machengine.org/xcode-frameworks/9a45f3ac977fd25dff77e58c6de1870b6808c4a7.tar.gz", .url = "https://pkg.machengine.org/xcode-frameworks/8a1cfb373587ea4c9bb1468b7c986462d8d4e10e.tar.gz",
.hash = "122098b9174895f9708bc824b0f9e550c401892c40a900006459acf2cbf78acd99bb", .hash = "N-V-__8AALShqgXkvqYU6f__FrA22SMWmi2TXCJjNTO1m8XJ",
.lazy = true, .lazy = true,
}, },
.emsdk = .{ .emsdk = .{

View File

@ -963,12 +963,8 @@ Sound LoadSoundFromWave(Wave wave)
if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed to get frame count for format conversion"); if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed to get frame count for format conversion");
AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, frameCount, AUDIO_BUFFER_USAGE_STATIC); AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, frameCount, AUDIO_BUFFER_USAGE_STATIC);
if (audioBuffer == NULL) if (audioBuffer != NULL)
{ {
TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer");
return sound; // early return to avoid dereferencing the audioBuffer null pointer
}
frameCount = (ma_uint32)ma_convert_frames(audioBuffer->data, frameCount, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, wave.data, frameCountIn, formatIn, wave.channels, wave.sampleRate); frameCount = (ma_uint32)ma_convert_frames(audioBuffer->data, frameCount, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, wave.data, frameCountIn, formatIn, wave.channels, wave.sampleRate);
if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed format conversion"); if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed format conversion");
@ -978,6 +974,8 @@ Sound LoadSoundFromWave(Wave wave)
sound.stream.channels = AUDIO_DEVICE_CHANNELS; sound.stream.channels = AUDIO_DEVICE_CHANNELS;
sound.stream.buffer = audioBuffer; sound.stream.buffer = audioBuffer;
} }
else TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer");
}
return sound; return sound;
} }
@ -992,12 +990,8 @@ Sound LoadSoundAlias(Sound source)
{ {
AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC); AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
if (audioBuffer == NULL) if (audioBuffer != NULL)
{ {
TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer");
return sound; // Early return to avoid dereferencing the audioBuffer null pointer
}
audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames; audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames;
audioBuffer->data = source.stream.buffer->data; audioBuffer->data = source.stream.buffer->data;
@ -1012,6 +1006,8 @@ Sound LoadSoundAlias(Sound source)
sound.stream.channels = AUDIO_DEVICE_CHANNELS; sound.stream.channels = AUDIO_DEVICE_CHANNELS;
sound.stream.buffer = audioBuffer; sound.stream.buffer = audioBuffer;
} }
else TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer");
}
return sound; return sound;
} }
@ -1071,7 +1067,7 @@ void UpdateSound(Sound sound, const void *data, int frameCount)
// Export wave data to file // Export wave data to file
bool ExportWave(Wave wave, const char *fileName) bool ExportWave(Wave wave, const char *fileName)
{ {
bool success = false; bool result = false;
if (false) { } if (false) { }
#if SUPPORT_FILEFORMAT_WAV #if SUPPORT_FILEFORMAT_WAV
@ -1088,11 +1084,11 @@ bool ExportWave(Wave wave, const char *fileName)
void *fileData = NULL; void *fileData = NULL;
size_t fileDataSize = 0; size_t fileDataSize = 0;
success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL); result = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
if (success) success = (int)drwav_write_pcm_frames(&wav, wave.frameCount, wave.data); if (result) result = (int)drwav_write_pcm_frames(&wav, wave.frameCount, wave.data);
drwav_result result = drwav_uninit(&wav); drwav_result result = drwav_uninit(&wav);
if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, (unsigned char *)fileData, (unsigned int)fileDataSize); if (result == DRWAV_SUCCESS) result = SaveFileData(fileName, (unsigned char *)fileData, (unsigned int)fileDataSize);
drwav_free(fileData, NULL); drwav_free(fileData, NULL);
} }
@ -1108,7 +1104,7 @@ bool ExportWave(Wave wave, const char *fileName)
qoa.samples = wave.frameCount; qoa.samples = wave.frameCount;
int bytesWritten = qoa_write(fileName, (const short *)wave.data, &qoa); int bytesWritten = qoa_write(fileName, (const short *)wave.data, &qoa);
if (bytesWritten > 0) success = true; if (bytesWritten > 0) result = true;
} }
else TRACELOG(LOG_WARNING, "AUDIO: Wave data must be 16 bit per sample for QOA format export"); else TRACELOG(LOG_WARNING, "AUDIO: Wave data must be 16 bit per sample for QOA format export");
} }
@ -1117,19 +1113,19 @@ bool ExportWave(Wave wave, const char *fileName)
{ {
// Export raw sample data (without header) // Export raw sample data (without header)
// NOTE: It's up to the user to track wave parameters // NOTE: It's up to the user to track wave parameters
success = SaveFileData(fileName, wave.data, wave.frameCount*wave.channels*wave.sampleSize/8); result = SaveFileData(fileName, wave.data, wave.frameCount*wave.channels*wave.sampleSize/8);
} }
if (success) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave data exported successfully", fileName); if (result) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave data exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave data", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave data", fileName);
return success; return result;
} }
// Export wave sample data to code (.h) // Export wave sample data to code (.h)
bool ExportWaveAsCode(Wave wave, const char *fileName) bool ExportWaveAsCode(Wave wave, const char *fileName)
{ {
bool success = false; bool result = false;
#ifndef TEXT_BYTES_PER_LINE #ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20 #define TEXT_BYTES_PER_LINE 20
@ -1183,14 +1179,14 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
} }
// NOTE: Text data length exported is determined by '\0' (NULL) character // NOTE: Text data length exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave as code exported successfully", fileName); if (result != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave as code exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave as code", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave as code", fileName);
return success; return result;
} }
// Play a sound // Play a sound
@ -2187,12 +2183,15 @@ void UpdateAudioStream(AudioStream stream, const void *data, int frameCount)
// Check if any audio stream buffers requires refill // Check if any audio stream buffers requires refill
bool IsAudioStreamProcessed(AudioStream stream) bool IsAudioStreamProcessed(AudioStream stream)
{ {
if (stream.buffer == NULL) return false;
bool result = false; bool result = false;
if (stream.buffer != NULL)
{
ma_mutex_lock(&AUDIO.System.lock); ma_mutex_lock(&AUDIO.System.lock);
result = stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]; result = stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1];
ma_mutex_unlock(&AUDIO.System.lock); ma_mutex_unlock(&AUDIO.System.lock);
}
return result; return result;
} }
@ -2885,6 +2884,8 @@ static unsigned char *LoadFileData(const char *fileName, int *dataSize)
// Save data to file from buffer // Save data to file from buffer
static bool SaveFileData(const char *fileName, void *data, int dataSize) static bool SaveFileData(const char *fileName, void *data, int dataSize)
{ {
bool result = true;
if (fileName != NULL) if (fileName != NULL)
{ {
FILE *file = fopen(fileName, "wb"); FILE *file = fopen(fileName, "wb");
@ -2902,21 +2903,23 @@ static bool SaveFileData(const char *fileName, void *data, int dataSize)
else else
{ {
TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
return false; result = false;
} }
} }
else else
{ {
TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return false; result = false;
} }
return true; return result;
} }
// Save text data to file (write), string must be '\0' terminated // Save text data to file (write), string must be '\0' terminated
static bool SaveFileText(const char *fileName, char *text) static bool SaveFileText(const char *fileName, char *text)
{ {
bool result = true;
if (fileName != NULL) if (fileName != NULL)
{ {
FILE *file = fopen(fileName, "wt"); FILE *file = fopen(fileName, "wt");
@ -2934,16 +2937,16 @@ static bool SaveFileText(const char *fileName, char *text)
else else
{ {
TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
return false; result = false;
} }
} }
else else
{ {
TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return false; result = false;
} }
return true; return result;
} }
#endif #endif

View File

@ -821,7 +821,7 @@ int GetRenderWidth(void)
{ {
int width = 0; int width = 0;
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.width; if (CORE.Window.usingFbo) width = CORE.Window.currentFbo.width;
else width = CORE.Window.render.width; else width = CORE.Window.render.width;
return width; return width;
@ -832,7 +832,7 @@ int GetRenderHeight(void)
{ {
int height = 0; int height = 0;
if (CORE.Window.usingFbo) return CORE.Window.currentFbo.height; if (CORE.Window.usingFbo) height = CORE.Window.currentFbo.height;
else height = CORE.Window.render.height; else height = CORE.Window.render.height;
return height; return height;
@ -1621,8 +1621,8 @@ int GetFPS(void)
for (int i = 0; i < FPS_CAPTURE_FRAMES_COUNT; i++) history[i] = 0; for (int i = 0; i < FPS_CAPTURE_FRAMES_COUNT; i++) history[i] = 0;
} }
if (fpsFrame == 0) return 0; if (fpsFrame != 0)
{
if ((GetTime() - last) > FPS_STEP) if ((GetTime() - last) > FPS_STEP)
{ {
last = (float)GetTime(); last = (float)GetTime();
@ -1633,6 +1633,8 @@ int GetFPS(void)
} }
fps = (int)roundf(1.0f/average); fps = (int)roundf(1.0f/average);
}
else fps = 0;
#endif #endif
return fps; return fps;
@ -2025,7 +2027,7 @@ void UnloadFileData(unsigned char *data)
// Save data to file from buffer // Save data to file from buffer
bool SaveFileData(const char *fileName, void *data, int dataSize) bool SaveFileData(const char *fileName, void *data, int dataSize)
{ {
bool success = false; bool result = false;
if (fileName != NULL) if (fileName != NULL)
{ {
@ -2043,20 +2045,20 @@ bool SaveFileData(const char *fileName, void *data, int dataSize)
else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName);
else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName); else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName);
int result = fclose(file); int closed = fclose(file);
if (result == 0) success = true; if (closed == 0) result = true;
} }
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
} }
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return success; return result;
} }
// Export data to code (.h), returns true on success // Export data to code (.h), returns true on success
bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName) bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName)
{ {
bool success = false; bool result = false;
#ifndef TEXT_BYTES_PER_LINE #ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20 #define TEXT_BYTES_PER_LINE 20
@ -2096,14 +2098,14 @@ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileN
byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]); byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[dataSize - 1]);
// NOTE: Text data size exported is determined by '\0' (NULL) character // NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName); if (result != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName);
return success; return result;
} }
// Load text data from file, returns a '\0' terminated string // Load text data from file, returns a '\0' terminated string
@ -2166,7 +2168,7 @@ void UnloadFileText(char *text)
// Save text data to file (write), string must be '\0' terminated // Save text data to file (write), string must be '\0' terminated
bool SaveFileText(const char *fileName, const char *text) bool SaveFileText(const char *fileName, const char *text)
{ {
bool success = false; bool result = false;
if (fileName != NULL) if (fileName != NULL)
{ {
@ -2181,14 +2183,14 @@ bool SaveFileText(const char *fileName, const char *text)
if (count < 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName); if (count < 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName);
else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName); else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName);
int result = fclose(file); int closed = fclose(file);
if (result == 0) success = true; if (closed == 0) result = true;
} }
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
} }
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return success; return result;
} }
// File access custom callbacks // File access custom callbacks
@ -3628,7 +3630,7 @@ void UnloadAutomationEventList(AutomationEventList list)
// Export automation events list as text file // Export automation events list as text file
bool ExportAutomationEventList(AutomationEventList list, const char *fileName) bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
{ {
bool success = false; bool result = false;
#if SUPPORT_AUTOMATION_EVENTS #if SUPPORT_AUTOMATION_EVENTS
// Export events as binary file // Export events as binary file
@ -3646,7 +3648,7 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
memcpy(binBuffer + offset, list.events, sizeof(AutomationEvent)*list.count); memcpy(binBuffer + offset, list.events, sizeof(AutomationEvent)*list.count);
offset += sizeof(AutomationEvent)*list.count; offset += sizeof(AutomationEvent)*list.count;
success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize); result = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize);
RL_FREE(binBuffer); RL_FREE(binBuffer);
} }
*/ */
@ -3677,12 +3679,12 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName)
} }
// NOTE: Text data size exported is determined by '\0' (NULL) character // NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
#endif #endif
return success; return result;
} }
// Setup automation event list to record to // Setup automation event list to record to

View File

@ -1613,6 +1613,8 @@ void rlNormal3f(float x, float y, float z)
normaly = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z; normaly = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z;
normalz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z; normalz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z;
} }
/* Normalize the vector if required. Default behavior assumes the normal vector is in the correct space for what the shader expects.
float length = sqrtf(normalx * normalx + normaly * normaly + normalz * normalz); float length = sqrtf(normalx * normalx + normaly * normaly + normalz * normalz);
if (length != 0.0f) if (length != 0.0f)
{ {
@ -1621,6 +1623,7 @@ void rlNormal3f(float x, float y, float z)
normaly *= ilength; normaly *= ilength;
normalz *= ilength; normalz *= ilength;
} }
*/
RLGL.State.normalx = normalx; RLGL.State.normalx = normalx;
RLGL.State.normaly = normaly; RLGL.State.normaly = normaly;
RLGL.State.normalz = normalz; RLGL.State.normalz = normalz;
@ -4647,14 +4650,14 @@ void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSi
// Get SSBO buffer size // Get SSBO buffer size
unsigned int rlGetShaderBufferSize(unsigned int id) unsigned int rlGetShaderBufferSize(unsigned int id)
{ {
unsigned int result = 0;
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
GLint64 size = 0; GLint64 size = 0;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size); glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
return (size > 0)? (unsigned int)size : 0; if (size > 0) result = (unsigned int)size;
#else
return 0;
#endif #endif
return result;
} }
// Read SSBO buffer data (GPU->CPU) // Read SSBO buffer data (GPU->CPU)

View File

@ -1949,7 +1949,7 @@ void UnloadMesh(Mesh mesh)
// Export mesh data to file // Export mesh data to file
bool ExportMesh(Mesh mesh, const char *fileName) bool ExportMesh(Mesh mesh, const char *fileName)
{ {
bool success = false; bool result = false;
if (IsFileExtension(fileName, ".obj")) if (IsFileExtension(fileName, ".obj"))
{ {
@ -2013,7 +2013,7 @@ bool ExportMesh(Mesh mesh, const char *fileName)
} }
// NOTE: Text data length exported is determined by '\0' (NULL) character // NOTE: Text data length exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
} }
@ -2022,13 +2022,13 @@ bool ExportMesh(Mesh mesh, const char *fileName)
// TODO: Support additional file formats to export mesh vertex data // TODO: Support additional file formats to export mesh vertex data
} }
return success; return result;
} }
// Export mesh as code file (.h) defining multiple arrays of vertex attributes // Export mesh as code file (.h) defining multiple arrays of vertex attributes
bool ExportMeshAsCode(Mesh mesh, const char *fileName) bool ExportMeshAsCode(Mesh mesh, const char *fileName)
{ {
bool success = false; bool result = false;
#ifndef TEXT_BYTES_PER_LINE #ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20 #define TEXT_BYTES_PER_LINE 20
@ -2112,14 +2112,14 @@ bool ExportMeshAsCode(Mesh mesh, const char *fileName)
//----------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------
// NOTE: Text data size exported is determined by '\0' (NULL) character // NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
//if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName); //if (result != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName);
//else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName); //else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName);
return success; return result;
} }
#if SUPPORT_FILEFORMAT_OBJ || SUPPORT_FILEFORMAT_MTL #if SUPPORT_FILEFORMAT_OBJ || SUPPORT_FILEFORMAT_MTL

View File

@ -2348,16 +2348,18 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
float dx = fabsf(center.x - recCenterX); float dx = fabsf(center.x - recCenterX);
float dy = fabsf(center.y - recCenterY); float dy = fabsf(center.y - recCenterY);
if (dx > (rec.width/2.0f + radius)) { return false; } if ((dx <= (rec.width/2.0f + radius)) && (dy <= (rec.height/2.0f + radius)))
if (dy > (rec.height/2.0f + radius)) { return false; } {
if (dx <= (rec.width/2.0f)) collision = true;
if (dx <= (rec.width/2.0f)) { return true; } else if (dy <= (rec.height/2.0f)) collision = true;
if (dy <= (rec.height/2.0f)) { return true; } else
{
float cornerDistanceSq = (dx - rec.width/2.0f)*(dx - rec.width/2.0f) + float cornerDistanceSq = (dx - rec.width/2.0f)*(dx - rec.width/2.0f) +
(dy - rec.height/2.0f)*(dy - rec.height/2.0f); (dy - rec.height/2.0f)*(dy - rec.height/2.0f);
collision = (cornerDistanceSq <= (radius*radius)); collision = (cornerDistanceSq <= (radius*radius));
}
}
return collision; return collision;
} }
@ -2418,14 +2420,17 @@ bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshol
// Check if circle collides with a line created between two points [p1] and [p2] // Check if circle collides with a line created between two points [p1] and [p2]
bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2) bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2)
{ {
bool collision = false;
float dx = p1.x - p2.x; float dx = p1.x - p2.x;
float dy = p1.y - p2.y; float dy = p1.y - p2.y;
if ((fabsf(dx) + fabsf(dy)) <= FLT_EPSILON) if ((fabsf(dx) + fabsf(dy)) <= FLT_EPSILON)
{ {
return CheckCollisionCircles(p1, 0, center, radius); collision = CheckCollisionCircles(p1, 0, center, radius);
} }
else
{
float lengthSQ = ((dx*dx) + (dy*dy)); float lengthSQ = ((dx*dx) + (dy*dy));
float dotProduct = (((center.x - p1.x)*(p2.x - p1.x)) + ((center.y - p1.y)*(p2.y - p1.y)))/(lengthSQ); float dotProduct = (((center.x - p1.x)*(p2.x - p1.x)) + ((center.y - p1.y)*(p2.y - p1.y)))/(lengthSQ);
@ -2436,7 +2441,10 @@ bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2
float dy2 = (p1.y - (dotProduct*(dy))) - center.y; float dy2 = (p1.y - (dotProduct*(dy))) - center.y;
float distanceSQ = ((dx2*dx2) + (dy2*dy2)); float distanceSQ = ((dx2*dx2) + (dy2*dy2));
return (distanceSQ <= radius*radius); if (distanceSQ <= radius*radius) collision = true;
}
return collision;
} }
// Get collision rectangle for two rectangles collision // Get collision rectangle for two rectangles collision

View File

@ -1017,7 +1017,7 @@ void UnloadFont(Font font)
// Export font as code file, returns true on success // Export font as code file, returns true on success
bool ExportFontAsCode(Font font, const char *fileName) bool ExportFontAsCode(Font font, const char *fileName)
{ {
bool success = false; bool result = false;
#ifndef TEXT_BYTES_PER_LINE #ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20 #define TEXT_BYTES_PER_LINE 20
@ -1159,14 +1159,14 @@ bool ExportFontAsCode(Font font, const char *fileName)
UnloadImage(image); UnloadImage(image);
// NOTE: Text data size exported is determined by '\0' (NULL) character // NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Font as code exported successfully", fileName); if (result != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Font as code exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export font as code", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export font as code", fileName);
return success; return result;
} }
// Draw current FPS // Draw current FPS
@ -1395,8 +1395,7 @@ Vector2 MeasureTextCodepoints(Font font, const int *codepoints, int length, floa
{ {
Vector2 textSize = { 0 }; Vector2 textSize = { 0 };
// Security check if ((font.texture.id == 0) || (codepoints == NULL) || (length == 0)) return textSize; // Security check
if ((font.texture.id == 0) || (codepoints == NULL) || (length == 0)) return textSize;
float textWidth = 0.0f; float textWidth = 0.0f;
// Used to count longer text line width // Used to count longer text line width
@ -1699,8 +1698,8 @@ const char *TextSubtext(const char *text, int position, int length)
{ {
int textLength = TextLength(text); int textLength = TextLength(text);
if (position >= textLength) return buffer; // First char is already '\0' by memset if (position < textLength)
{
int maxLength = textLength - position; int maxLength = textLength - position;
if (length > maxLength) length = maxLength; if (length > maxLength) length = maxLength;
if (length >= MAX_TEXT_BUFFER_LENGTH) length = MAX_TEXT_BUFFER_LENGTH - 1; if (length >= MAX_TEXT_BUFFER_LENGTH) length = MAX_TEXT_BUFFER_LENGTH - 1;
@ -1711,6 +1710,7 @@ const char *TextSubtext(const char *text, int position, int length)
buffer[length] = '\0'; buffer[length] = '\0';
} }
}
return buffer; return buffer;
} }
@ -1763,8 +1763,8 @@ char *GetTextBetween(const char *text, const char *begin, const char *end)
// NOTE: Limited text replace functionality, using static string // NOTE: Limited text replace functionality, using static string
char *TextReplace(const char *text, const char *search, const char *replacement) char *TextReplace(const char *text, const char *search, const char *replacement)
{ {
static char result[MAX_TEXT_BUFFER_LENGTH] = { 0 }; static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(result, 0, MAX_TEXT_BUFFER_LENGTH); memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
if ((text != NULL) && (search != NULL) && (search[0] != '\0')) if ((text != NULL) && (search != NULL) && (search[0] != '\0'))
{ {
@ -1790,7 +1790,7 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
{ {
// TODO: Allow copying data replaced up to maximum buffer size and stop // TODO: Allow copying data replaced up to maximum buffer size and stop
tempPtr = result; // Point to result start tempPtr = buffer; // Point to result start
// First time through the loop, all the variable are set correctly from here on, // First time through the loop, all the variable are set correctly from here on,
// - 'temp' points to the end of the result string // - 'temp' points to the end of the result string
@ -1821,7 +1821,7 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
else TRACELOG(LOG_WARNING, "Text with replacement is longer than internal buffer, use TextReplaceAlloc()"); else TRACELOG(LOG_WARNING, "Text with replacement is longer than internal buffer, use TextReplaceAlloc()");
} }
return result; return buffer;
} }
// Replace text string // Replace text string
@ -1894,8 +1894,8 @@ char *TextReplaceAlloc(const char *text, const char *search, const char *replace
// NOTE: If (replacement == NULL) removes "begin"[ ]"end" text // NOTE: If (replacement == NULL) removes "begin"[ ]"end" text
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement) char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement)
{ {
static char result[MAX_TEXT_BUFFER_LENGTH] = { 0 }; static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(result, 0, MAX_TEXT_BUFFER_LENGTH); memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
if ((text != NULL) && (begin != NULL) && (end != NULL)) if ((text != NULL) && (begin != NULL) && (end != NULL))
{ {
@ -1912,16 +1912,16 @@ char *TextReplaceBetween(const char *text, const char *begin, const char *end, c
int textLen = TextLength(text); int textLen = TextLength(text);
int replaceLen = (replacement == NULL)? 0 : TextLength(replacement); int replaceLen = (replacement == NULL)? 0 : TextLength(replacement);
int toreplaceLen = endIndex - beginIndex - beginLen; //int toreplaceLen = endIndex - beginIndex - beginLen;
strncpy(result, text, beginIndex + beginLen); // Copy first text part strncpy(buffer, text, beginIndex + beginLen); // Copy first text part
if (replacement != NULL) strncpy(result + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided) if (replacement != NULL) strncpy(buffer + beginIndex + beginLen, replacement, replaceLen); // Copy replacement (if provided)
strncpy(result + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part strncpy(buffer + beginIndex + beginLen + replaceLen, text + endIndex, textLen - endIndex); // Copy end text part
} }
} }
} }
return result; return buffer;
} }
// Replace text between two specific strings // Replace text between two specific strings
@ -1964,8 +1964,8 @@ char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *e
// WARNING: Allocated memory must be manually freed // WARNING: Allocated memory must be manually freed
char *TextInsert(const char *text, const char *insert, int position) char *TextInsert(const char *text, const char *insert, int position)
{ {
static char result[MAX_TEXT_BUFFER_LENGTH] = { 0 }; static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
memset(result, 0, MAX_TEXT_BUFFER_LENGTH); memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
if ((text != NULL) && (insert != NULL)) if ((text != NULL) && (insert != NULL))
{ {
@ -1976,16 +1976,16 @@ char *TextInsert(const char *text, const char *insert, int position)
{ {
// TODO: Allow copying data inserted up to maximum buffer size and stop // TODO: Allow copying data inserted up to maximum buffer size and stop
for (int i = 0; i < position; i++) result[i] = text[i]; for (int i = 0; i < position; i++) buffer[i] = text[i];
for (int i = position; i < insertLen + position; i++) result[i] = insert[i - position]; for (int i = position; i < insertLen + position; i++) buffer[i] = insert[i - position];
for (int i = (insertLen + position); i < (textLen + insertLen); i++) result[i] = text[i]; for (int i = (insertLen + position); i < (textLen + insertLen); i++) buffer[i] = text[i];
result[textLen + insertLen] = '\0'; // Add EOL buffer[textLen + insertLen] = '\0'; // Add EOL
} }
else TRACELOG(LOG_WARNING, "Text with inserted string is longer than internal buffer, use TextInserExt()"); else TRACELOG(LOG_WARNING, "Text with inserted string is longer than internal buffer, use TextInserExt()");
} }
return result; return buffer;
} }
// Insert text in a specific position, moves all text forward // Insert text in a specific position, moves all text forward

View File

@ -376,8 +376,7 @@ Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileDat
Image image = { 0 }; Image image = { 0 };
int frameCount = 0; int frameCount = 0;
// Security check for input data if ((fileType == NULL) || (fileData == NULL) || (dataSize == 0)) return image; // Security check
if ((fileType == NULL) || (fileData == NULL) || (dataSize == 0)) return image;
#if SUPPORT_FILEFORMAT_GIF #if SUPPORT_FILEFORMAT_GIF
if ((strcmp(fileType, ".gif") == 0) || (strcmp(fileType, ".GIF") == 0)) if ((strcmp(fileType, ".gif") == 0) || (strcmp(fileType, ".GIF") == 0))
@ -621,8 +620,7 @@ bool ExportImage(Image image, const char *fileName)
{ {
int result = 0; int result = 0;
// Security check for input data if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return result; // Security check
if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return result;
#if SUPPORT_IMAGE_EXPORT #if SUPPORT_IMAGE_EXPORT
int channels = 4; int channels = 4;
@ -709,8 +707,7 @@ unsigned char *ExportImageToMemory(Image image, const char *fileType, int *dataS
unsigned char *fileData = NULL; unsigned char *fileData = NULL;
*dataSize = 0; *dataSize = 0;
// Security check for input data if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return fileData; // Security check
if ((image.width == 0) || (image.height == 0) || (image.data == NULL)) return NULL;
int channels = 4; int channels = 4;
@ -734,7 +731,7 @@ unsigned char *ExportImageToMemory(Image image, const char *fileType, int *dataS
// Export image as code file (.h) defining an array of bytes // Export image as code file (.h) defining an array of bytes
bool ExportImageAsCode(Image image, const char *fileName) bool ExportImageAsCode(Image image, const char *fileName)
{ {
bool success = false; bool result = false;
#ifndef TEXT_BYTES_PER_LINE #ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20 #define TEXT_BYTES_PER_LINE 20
@ -774,14 +771,14 @@ bool ExportImageAsCode(Image image, const char *fileName)
byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)image.data)[dataSize - 1]); byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)image.data)[dataSize - 1]);
// NOTE: Text data size exported is determined by '\0' (NULL) character // NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData); result = SaveFileText(fileName, txtData);
RL_FREE(txtData); RL_FREE(txtData);
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName); if (result != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName); else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName);
return success; return result;
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -1536,8 +1533,7 @@ Image ImageFromChannel(Image image, int selectedChannel)
{ {
Image result = { 0 }; Image result = { 0 };
// Security check to avoid program crash if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result; // Security check
if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result;
// Check selected channel is valid // Check selected channel is valid
if (selectedChannel < 0) if (selectedChannel < 0)
@ -2937,7 +2933,7 @@ void ImageColorReplace(Image *image, Color color, Color replace)
// NOTE: Memory allocated should be freed using UnloadImageColors(); // NOTE: Memory allocated should be freed using UnloadImageColors();
Color *LoadImageColors(Image image) Color *LoadImageColors(Image image)
{ {
if ((image.width == 0) || (image.height == 0)) return NULL; if ((image.width == 0) || (image.height == 0)) return NULL; // Security check
Color *pixels = (Color *)RL_MALLOC(image.width*image.height*sizeof(Color)); Color *pixels = (Color *)RL_MALLOC(image.width*image.height*sizeof(Color));
@ -4903,11 +4899,11 @@ Vector3 ColorToHSV(Color color)
float max = 0.0f; float max = 0.0f;
float delta = 0.0f; float delta = 0.0f;
min = rgb.x < rgb.y? rgb.x : rgb.y; min = (rgb.x < rgb.y)? rgb.x : rgb.y;
min = min < rgb.z? min : rgb.z; min = (min < rgb.z)? min : rgb.z;
max = rgb.x > rgb.y? rgb.x : rgb.y; max = (rgb.x > rgb.y)? rgb.x : rgb.y;
max = max > rgb.z? max : rgb.z; max = (max > rgb.z)? max : rgb.z;
hsv.z = max; // Value hsv.z = max; // Value
delta = max - min; delta = max - min;
@ -5093,7 +5089,7 @@ Color ColorAlpha(Color color, float alpha)
// Get src alpha-blended into dst color with tint // Get src alpha-blended into dst color with tint
Color ColorAlphaBlend(Color dst, Color src, Color tint) Color ColorAlphaBlend(Color dst, Color src, Color tint)
{ {
Color out = WHITE; Color result = WHITE;
// Apply color tint to source color // Apply color tint to source color
src.r = (unsigned char)(((unsigned int)src.r*((unsigned int)tint.r+1)) >> 8); src.r = (unsigned char)(((unsigned int)src.r*((unsigned int)tint.r+1)) >> 8);
@ -5104,24 +5100,24 @@ Color ColorAlphaBlend(Color dst, Color src, Color tint)
//#define COLORALPHABLEND_FLOAT //#define COLORALPHABLEND_FLOAT
#define COLORALPHABLEND_INTEGERS #define COLORALPHABLEND_INTEGERS
#if defined(COLORALPHABLEND_INTEGERS) #if defined(COLORALPHABLEND_INTEGERS)
if (src.a == 0) out = dst; if (src.a == 0) result = dst;
else if (src.a == 255) out = src; else if (src.a == 255) result = src;
else else
{ {
unsigned int alpha = (unsigned int)src.a + 1; // Shifting by 8 (dividing by 256), so need to take that excess into account unsigned int alpha = (unsigned int)src.a + 1; // Shifting by 8 (dividing by 256), so need to take that excess into account
out.a = (unsigned char)(((unsigned int)alpha*256 + (unsigned int)dst.a*(256 - alpha)) >> 8); result.a = (unsigned char)(((unsigned int)alpha*256 + (unsigned int)dst.a*(256 - alpha)) >> 8);
if (out.a > 0) if (result.a > 0)
{ {
out.r = (unsigned char)((((unsigned int)src.r*alpha*256 + (unsigned int)dst.r*(unsigned int)dst.a*(256 - alpha))/out.a) >> 8); result.r = (unsigned char)((((unsigned int)src.r*alpha*256 + (unsigned int)dst.r*(unsigned int)dst.a*(256 - alpha))/result.a) >> 8);
out.g = (unsigned char)((((unsigned int)src.g*alpha*256 + (unsigned int)dst.g*(unsigned int)dst.a*(256 - alpha))/out.a) >> 8); result.g = (unsigned char)((((unsigned int)src.g*alpha*256 + (unsigned int)dst.g*(unsigned int)dst.a*(256 - alpha))/result.a) >> 8);
out.b = (unsigned char)((((unsigned int)src.b*alpha*256 + (unsigned int)dst.b*(unsigned int)dst.a*(256 - alpha))/out.a) >> 8); result.b = (unsigned char)((((unsigned int)src.b*alpha*256 + (unsigned int)dst.b*(unsigned int)dst.a*(256 - alpha))/result.a) >> 8);
} }
} }
#endif #endif
#if defined(COLORALPHABLEND_FLOAT) #if defined(COLORALPHABLEND_FLOAT)
if (src.a == 0) out = dst; if (src.a == 0) result = dst;
else if (src.a == 255) out = src; else if (src.a == 255) result = src;
else else
{ {
Vector4 fdst = ColorNormalize(dst); Vector4 fdst = ColorNormalize(dst);
@ -5138,11 +5134,11 @@ Color ColorAlphaBlend(Color dst, Color src, Color tint)
fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w; fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w;
} }
out = (Color){ (unsigned char)(fout.x*255.0f), (unsigned char)(fout.y*255.0f), (unsigned char)(fout.z*255.0f), (unsigned char)(fout.w*255.0f) }; result = (Color){ (unsigned char)(fout.x*255.0f), (unsigned char)(fout.y*255.0f), (unsigned char)(fout.z*255.0f), (unsigned char)(fout.w*255.0f) };
} }
#endif #endif
return out; return result;
} }
// Get color lerp interpolation between two colors, factor [0.0f..1.0f] // Get color lerp interpolation between two colors, factor [0.0f..1.0f]