diff --git a/DirectMusic/Native.cs b/DirectMusic/Native.cs index af534a4..8bbe2ec 100644 --- a/DirectMusic/Native.cs +++ b/DirectMusic/Native.cs @@ -40,6 +40,9 @@ internal static class Native [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void DmLogHandler(IntPtr ctx, LogLevel lvl, string message); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate uint DmRng(IntPtr ctx); + private const string DllName = "dmusic"; [DllImport(DllName)] @@ -100,6 +103,9 @@ public static extern DmResult DmPerformance_playTransition(IntPtr slf, IntPtr sg [DllImport(DllName)] public static extern DmResult DmPerformance_renderPcm(IntPtr slf, float[] buf, ulong len, DmRenderOptions opts); + [DllImport(DllName)] + public static extern void Dm_setRandomNumberGenerator(DmRng rng, IntPtr ctx); + public class Structs { } diff --git a/DirectMusic/RandomNumberGenerator.cs b/DirectMusic/RandomNumberGenerator.cs new file mode 100644 index 0000000..200c313 --- /dev/null +++ b/DirectMusic/RandomNumberGenerator.cs @@ -0,0 +1,37 @@ +using System; +using System.Runtime.InteropServices; +using DirectMusic.Util; + +namespace DirectMusic +{ + public class RandomNumberGenerator + { + private static GCHandle? _handler; + private static readonly Native.DmRng NativeHandler = _nativeCallbackHandler; + + /// + /// + /// + public delegate int Callback(); + + /// + /// + /// + public static void Set(Callback cb) + { + var handler = GCHandle.Alloc(cb); + Native.Dm_setRandomNumberGenerator(NativeHandler, GCHandle.ToIntPtr(handler)); + + _handler?.Free(); + _handler = handler; + } + + [MonoPInvokeCallback] + private static uint _nativeCallbackHandler(IntPtr ctx) + { + var gcHandle = GCHandle.FromIntPtr(ctx); + var cb = (Callback)gcHandle.Target; + return (uint) (cb() % uint.MaxValue); + } + } +} \ No newline at end of file