diff --git a/Raylib-cs/interop/Raylib.cs b/Raylib-cs/interop/Raylib.cs
index 1ad4343..6268319 100644
--- a/Raylib-cs/interop/Raylib.cs
+++ b/Raylib-cs/interop/Raylib.cs
@@ -987,7 +987,7 @@ public static unsafe partial class Raylib
/// Decode Base64 string data, memory must be MemFree()
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
- public static partial byte* DecodeDataBase64(byte* data, int* outputSize);
+ public static partial byte* DecodeDataBase64(sbyte* data, int* outputSize);
/// Compute CRC32 hash code
[LibraryImport(NativeLibName)]
@@ -1886,7 +1886,7 @@ public static unsafe partial class Raylib
/// Load image sequence from memory buffer
[LibraryImport(NativeLibName)]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
- public static partial Image LoadImageAnimFromMemory(sbyte* fileName, sbyte* fileData, int dataSize, int* frames);
+ public static partial Image LoadImageAnimFromMemory(sbyte* fileType, byte* fileData, int dataSize, int* frames);
/// Load image from memory buffer, fileType refers to extension: i.e. ".png"
[LibraryImport(NativeLibName)]
diff --git a/Raylib-cs/types/Model.cs b/Raylib-cs/types/Model.cs
index 16bac95..e6548b4 100644
--- a/Raylib-cs/types/Model.cs
+++ b/Raylib-cs/types/Model.cs
@@ -57,6 +57,12 @@ public unsafe struct ModelSkeleton
public Span BonesAsSpan()
{
+
+ if (Bones == null || BoneCount <= 0)
+ {
+ return Span.Empty;
+ }
+
return new Span(Bones, BoneCount);
}
}
@@ -104,7 +110,7 @@ public unsafe struct Model
///
/// Skeleton for animation
///
- ModelSkeleton Skeleton;
+ public ModelSkeleton Skeleton;
///
/// Current animation pose (Transform[])
@@ -128,11 +134,21 @@ public unsafe struct Model
public Span MeshMaterialAsSpan()
{
+ if (MeshMaterial == null || MeshCount <= 0)
+ {
+ return Span.Empty;
+ }
+
return new Span(MeshMaterial, MeshCount);
}
public Span MeshesAsSpan()
{
+ if (Meshes == null || MeshCount <= 0)
+ {
+ return Span.Empty;
+ }
+
return new Span(Meshes, MeshCount);
}
}
@@ -161,11 +177,23 @@ public unsafe struct ModelAnimation
///
/// Animation sequence keyframe poses [keyframe][pose]
///
- public Transform* KeyframePoses;
+ public Transform** KeyframePoses;
- public Span KeyFramePosesAsSpan()
+ public Span GetKeyFramePoseAsSpan(int frame)
{
- return new Span(KeyframePoses, KeyFrameCount);
+ if (KeyframePoses == null || frame < 0 || frame >= KeyFrameCount)
+ {
+ return Span.Empty;
+ }
+
+ var pose = KeyframePoses[frame];
+
+ if (pose == null || BoneCount <= 0)
+ {
+ return Span.Empty;
+ }
+
+ return new Span(KeyframePoses[frame], KeyFrameCount);
}
public string NameToString()
diff --git a/Raylib-cs/types/Raylib.Utils.cs b/Raylib-cs/types/Raylib.Utils.cs
index 37f7bbe..0dbf173 100644
--- a/Raylib-cs/types/Raylib.Utils.cs
+++ b/Raylib-cs/types/Raylib.Utils.cs
@@ -20,6 +20,20 @@ public static unsafe partial class Raylib
SetWindowTitle(str1.AsPointer());
}
+ /// Set icon for window (multiple images, RGBA 32bit)
+ public static void SetWindowIcons(Image[] images)
+ {
+ if (images == null || images.Length == 0)
+ {
+ return;
+ }
+
+ fixed (Image* imagesPtr = images)
+ {
+ SetWindowIcons(imagesPtr, images.Length);
+ }
+ }
+
/// Get the human-readable, UTF-8 encoded name of the specified monitor
public static string GetMonitorName_(int monitor)
{
@@ -112,6 +126,19 @@ public static unsafe partial class Raylib
return LoadImage(str1.AsPointer());
}
+ /// Load image sequence from memory buffer
+ public static Image LoadImageAnimFromMemory(string fileType, byte[] fileData, out int frames)
+ {
+ using AnsiBuffer type = fileType.ToAnsiBuffer();
+ fixed (byte* data = fileData)
+ {
+ int frameCount;
+ var result = LoadImageAnimFromMemory(type.AsPointer(), data, fileData.Length, &frameCount);
+ frames = frameCount;
+ return result;
+ }
+ }
+
/// Load image from RAW file data
public static Image LoadImageRaw(string fileName, int width, int height, PixelFormat format, int headerSize)
{
@@ -192,7 +219,7 @@ public static unsafe partial class Raylib
/// Set shader uniform value
public static void SetShaderValue(Shader shader, int locIndex, T value, ShaderUniformDataType uniformType)
- where T : unmanaged
+ where T : unmanaged
{
SetShaderValue(shader, locIndex, &value, uniformType);
}
@@ -244,6 +271,7 @@ public static unsafe partial class Raylib
{
return false;
}
+
fixed (T* ptr = data)
{
using AnsiBuffer ansiBuffer = fileName.ToAnsiBuffer();
@@ -251,6 +279,16 @@ public static unsafe partial class Raylib
}
}
+ /// Export data to code (.h), returns true on success
+ public static CBool ExportDataAsCode(byte[] data, string fileName)
+ {
+ fixed (byte* ptr = data)
+ {
+ using AnsiBuffer name = fileName.ToAnsiBuffer();
+ return ExportDataAsCode(ptr, data.Length, name.AsPointer());
+ }
+ }
+
/// Load file data as byte array (read)
public static byte* LoadFileData(string fileName, ref int bytesRead)
{
@@ -265,6 +303,13 @@ public static unsafe partial class Raylib
{
int length = 0;
byte* data = LoadFileData(fileName, ref length);
+
+ if (data == null)
+ {
+ return Array.Empty();
+ }
+
+
byte[] arr = new byte[length];
Marshal.Copy((IntPtr)data, arr, 0, length);
UnloadFileData(data);
@@ -294,6 +339,7 @@ public static unsafe partial class Raylib
{
files[i] = filePathList[i];
}
+
UnloadDroppedFiles(filePathList);
return files;
@@ -409,7 +455,7 @@ public static unsafe partial class Raylib
CBool lockView,
CBool rotateAroundTarget,
CBool rotateUp
- )
+ )
{
fixed (Camera3D* c = &camera)
{
@@ -866,7 +912,8 @@ public static unsafe partial class Raylib
}
/// Draw triangle with interpolated colors within an image
- public static void ImageDrawTriangleEx(ref Image dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3)
+ public static void ImageDrawTriangleEx(ref Image dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2,
+ Color c3)
{
fixed (Image* p = &dst)
{
@@ -1112,6 +1159,33 @@ public static unsafe partial class Raylib
}
}
+ /// Update sound buffer with new data
+ public static void UpdateSound(Sound sound, ReadOnlySpan data, int sampleCount) where T : unmanaged
+ {
+ fixed (T* dataPtr = data)
+ {
+ UpdateSound(sound, dataPtr, sampleCount);
+ }
+ }
+
+ /// Update sound buffer with new data
+ public static void UpdateSound(Sound sound, ReadOnlySpan data) where T : unmanaged
+ {
+ fixed (T* dataPtr = data)
+ {
+ UpdateSound(sound, dataPtr, data.Length);
+ }
+ }
+
+ /// Update audio stream buffers with data
+ public static void UpdateAudioStream(AudioStream sound, ReadOnlySpan data, int frameCount) where T : unmanaged
+ {
+ fixed (T* dataPtr = data)
+ {
+ UpdateAudioStream(sound, dataPtr, frameCount);
+ }
+ }
+
/// Convert wave data to desired format
public static void WaveFormat(ref Wave wave, int sampleRate, int sampleSize, int channels)
{
@@ -1232,6 +1306,33 @@ public static unsafe partial class Raylib
DrawTextPro(font, str1.AsPointer(), position, origin, rotation, fontSize, spacing, tint);
}
+ /// Draw multiple characters (codepoint)
+ public static void DrawTextCodepoints(
+ Font font,
+ int[] codepoints,
+ Vector2 position,
+ float fontSize,
+ float spacing,
+ Color tint
+ )
+ {
+ fixed (int* codepointsPtr = codepoints)
+ {
+ DrawTextCodepoints(font, codepointsPtr, codepoints.Length, position, fontSize, spacing, tint);
+ }
+ }
+
+ /// Measure string size for Font
+ public static Vector2 MeasureTextCodepoints(
+ Font font, int[] codepoints, float fontSize, float spacing
+ )
+ {
+ fixed (int* codepointsPtr = codepoints)
+ {
+ return MeasureTextCodepoints(font, codepointsPtr, codepoints.Length, fontSize, spacing);
+ }
+ }
+
/// Measure string width for default font
public static int MeasureText(string text, int fontSize)
{
@@ -1502,12 +1603,12 @@ public static unsafe partial class Raylib
public static string GetApplicationDirectoryString()
{
- return new string(GetApplicationDirectory());
+ return Utf8StringUtils.GetUTF8String(GetApplicationDirectory());
}
public static string GetWorkingDirectoryString()
{
- return new string(GetWorkingDirectory());
+ return Utf8StringUtils.GetUTF8String(GetWorkingDirectory());
}
///
@@ -1529,6 +1630,7 @@ public static unsafe partial class Raylib
{
output[i] = sequence[i];
}
+
UnloadRandomSequence(sequence);
return output;
}
@@ -1554,6 +1656,7 @@ public static unsafe partial class Raylib
float norm = (float)val / (float)maxi;
output[i] = Raymath.Lerp(min, max, norm);
}
+
return output;
}
@@ -1641,47 +1744,47 @@ public static unsafe partial class Raylib
public static string GetFileExtension(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
- return new string(GetFileExtension(fileBuffer.AsPointer()));
+ return Utf8StringUtils.GetUTF8String(GetFileExtension(fileBuffer.AsPointer()));
}
/// Get string to filename for a path string
public static string GetFileName(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
- return new string(GetFileName(fileBuffer.AsPointer()));
+ return Utf8StringUtils.GetUTF8String(GetFileName(fileBuffer.AsPointer()));
}
/// Get filename string without extension
public static string GetFileNameWithoutExt(string fileName)
{
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
- return new string(GetFileNameWithoutExt(fileBuffer.AsPointer()));
+ return Utf8StringUtils.GetUTF8String(GetFileNameWithoutExt(fileBuffer.AsPointer()));
}
/// Get full path for a given fileName with path
public static string GetDirectoryPath(string filePath)
{
using AnsiBuffer fileBuffer = filePath.ToAnsiBuffer();
- return new string(GetDirectoryPath(fileBuffer.AsPointer()));
+ return Utf8StringUtils.GetUTF8String(GetDirectoryPath(fileBuffer.AsPointer()));
}
/// Get previous directory path for a given path
public static string GetPrevDirectoryPath(string dirPath)
{
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
- return new string(GetPrevDirectoryPath(dirBuffer.AsPointer()));
+ return Utf8StringUtils.GetUTF8String(GetPrevDirectoryPath(dirBuffer.AsPointer()));
}
/// Get current working directory
public static string GetWorkingDirectoryAsString()
{
- return new string(GetWorkingDirectory());
+ return Utf8StringUtils.GetUTF8String(GetWorkingDirectory());
}
/// Get the directory of the running application
public static string GetApplicationDirectoryAsString()
{
- return new string(GetApplicationDirectory());
+ return Utf8StringUtils.GetUTF8String(GetApplicationDirectory());
}
/// Change working directory, return true on success
@@ -1705,6 +1808,21 @@ public static unsafe partial class Raylib
return LoadDirectoryFiles(dirBuffer.AsPointer());
}
+ /// Get the file count in a directory
+ public static int GetDirectoryFileCount(string dirPath)
+ {
+ using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
+ return GetDirectoryFileCount(dirBuffer.AsPointer());
+ }
+
+ /// Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"
+ public static int GetDirectoryFileCountEx(string dirPath, string filter, CBool scanSubdirs)
+ {
+ using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
+ using AnsiBuffer filterBuffer = filter.ToAnsiBuffer();
+ return GetDirectoryFileCountEx(dirBuffer.AsPointer(), filterBuffer.AsPointer(), scanSubdirs);
+ }
+
/// Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"
public static FilePathList LoadDirectoryFilesEx(string basePath, string filter, CBool scanSubDirs)
{
@@ -1713,6 +1831,212 @@ public static unsafe partial class Raylib
return LoadDirectoryFilesEx(baseBuffer.AsPointer(), filterBuffer.AsPointer(), scanSubDirs);
}
+
+ /// Compress data (DEFLATE algorithm)
+ public static byte[] CompressData(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ int compressedSize;
+ var compressedPtr = CompressData(dataPtr, data.Length, &compressedSize);
+
+ if (compressedPtr == null || compressedSize <= 0)
+ {
+ return Array.Empty();
+ }
+
+ try
+ {
+ var result = new byte[compressedSize];
+
+ fixed (byte* resultPtr = result)
+ {
+ Buffer.MemoryCopy(
+ compressedPtr,
+ resultPtr,
+ compressedSize,
+ compressedSize
+ );
+ }
+
+ return result;
+ }
+ finally
+ {
+ MemFree(compressedPtr);
+ }
+ }
+ }
+
+ /// Decompress data (DEFLATE algorithm)
+ public static byte[] DecompressData(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ int dataSize;
+ var compressedPtr = DecompressData(dataPtr, data.Length, &dataSize);
+
+ if (compressedPtr == null || dataSize <= 0)
+ {
+ return Array.Empty();
+ }
+
+ try
+ {
+ var result = new byte[dataSize];
+
+ fixed (byte* resultPtr = result)
+ {
+ Buffer.MemoryCopy(
+ compressedPtr,
+ resultPtr,
+ dataSize,
+ dataSize
+ );
+ }
+
+ return result;
+ }
+ finally
+ {
+ MemFree(compressedPtr);
+ }
+ }
+ }
+
+ /// Encode data to Base64 string
+ public static byte[] EncodeDataBase64(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ int outputSize;
+ var compressedPtr = EncodeDataBase64(dataPtr, data.Length, &outputSize);
+
+ if (compressedPtr == null || outputSize <= 0)
+ {
+ return Array.Empty();
+ }
+
+ try
+ {
+ var result = new byte[outputSize];
+
+ fixed (byte* resultPtr = result)
+ {
+ Buffer.MemoryCopy(
+ compressedPtr,
+ resultPtr,
+ outputSize,
+ outputSize
+ );
+ }
+
+ return result;
+ }
+ finally
+ {
+ MemFree(compressedPtr);
+ }
+ }
+ }
+
+ /// Decode data to Base64 string
+ public static byte[] DecodeDataBase64(string data)
+ {
+ using Utf8Buffer ptr = data.ToUtf8Buffer();
+
+ int outputSize;
+ var compressedPtr = DecodeDataBase64(ptr.AsPointer(), &outputSize);
+
+ if (compressedPtr == null || outputSize <= 0)
+ {
+ return Array.Empty();
+ }
+
+ try
+ {
+ var result = new byte[outputSize];
+
+ fixed (byte* resultPtr = result)
+ {
+ Buffer.MemoryCopy(
+ compressedPtr,
+ resultPtr,
+ outputSize,
+ outputSize
+ );
+ }
+
+ return result;
+ }
+ finally
+ {
+ MemFree(compressedPtr);
+ }
+ }
+
+ /// Compute CRC32 hash code
+ public static uint ComputeCRC32(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ return ComputeCRC32(dataPtr, data.Length);
+ }
+ }
+
+ /// Compute MD5 hash code, returns uint[4] array
+ public static uint[] ComputeMD5(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ var result = ComputeMD5(dataPtr, data.Length);
+ return
+ [
+ result[0],
+ result[1],
+ result[2],
+ result[3],
+ ];
+ }
+ }
+
+ /// Compute SHA1 hash code, returns uint[5] array
+ public static uint[] ComputeSHA1(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ var result = ComputeSHA1(dataPtr, data.Length);
+ return
+ [
+ result[0],
+ result[1],
+ result[2],
+ result[3],
+ result[4],
+ ];
+ }
+ }
+
+ /// Compute SHA256 hash code, returns int[8] (32 bytes)
+ public static uint[] ComputeSHA256(byte[] data)
+ {
+ fixed (byte* dataPtr = data)
+ {
+ var result = ComputeSHA256(dataPtr, data.Length);
+ return
+ [
+ result[0],
+ result[1],
+ result[2],
+ result[3],
+ result[4],
+ result[5],
+ result[6],
+ result[7],
+ ];
+ }
+ }
+
///
/// Loads text from a file, reads it, saves it, unloads the file, and returns the loaded text.
///