public LibretroApi(string dllPath, string corePath) { InstanceName = "libretro_" + Guid.NewGuid().ToString(); var pipeName = InstanceName; instanceDll = new InstanceDll(dllPath); instanceDllCore = new InstanceDll(corePath); var dllinit = (DllInit)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("DllInit"), typeof(DllInit)); Message = (MessageApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("Message"), typeof(MessageApi)); _copyBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("CopyBuffer"), typeof(BufferApi)); _setBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("SetBuffer"), typeof(BufferApi)); SetVariable = (SetVariableApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("SetVariable"), typeof(SetVariableApi)); comm = (CommStruct *)dllinit(instanceDllCore.HModule).ToPointer(); //TODO: (stash function pointers locally and thunk to IntPtr) //ALSO: this should be done by the core, I think, not the API. No smarts should be in here comm->env.retro_perf_callback.get_cpu_features = IntPtr.Zero; //retro_perf_callback.get_cpu_features = new LibRetro.retro_get_cpu_features_t(() => (ulong)( // (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsXMMIAvailable) ? LibRetro.RETRO_SIMD.SSE : 0) | // (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsXMMI64Available) ? LibRetro.RETRO_SIMD.SSE2 : 0) | // (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsSSE3Available) ? LibRetro.RETRO_SIMD.SSE3 : 0) | // (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsMMXAvailable) ? LibRetro.RETRO_SIMD.MMX : 0) // )); //retro_perf_callback.get_perf_counter = new LibRetro.retro_perf_get_counter_t(() => System.Diagnostics.Stopwatch.GetTimestamp()); //retro_perf_callback.get_time_usec = new LibRetro.retro_perf_get_time_usec_t(() => DateTime.Now.Ticks / 10); //retro_perf_callback.perf_log = new LibRetro.retro_perf_log_t(() => { }); //retro_perf_callback.perf_register = new LibRetro.retro_perf_register_t((ref LibRetro.retro_perf_counter counter) => { }); //retro_perf_callback.perf_start = new LibRetro.retro_perf_start_t((ref LibRetro.retro_perf_counter counter) => { }); //retro_perf_callback.perf_stop = new LibRetro.retro_perf_stop_t((ref LibRetro.retro_perf_counter counter) => { }); }
BufferApi _setBuffer; //TODO: consider making private and wrapping public LibsnesApi(string dllPath) { InstanceName = "libsneshawk_" + Guid.NewGuid().ToString(); instanceDll = new InstanceDll(dllPath); var dllinit = (DllInit)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("DllInit"), typeof(DllInit)); Message = (MessageApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("Message"), typeof(MessageApi)); _copyBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("CopyBuffer"), typeof(BufferApi)); _setBuffer = (BufferApi)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("SetBuffer"), typeof(BufferApi)); comm = (CommStruct *)dllinit().ToPointer(); }
public LibsnesApi(string dllPath) { InstanceName = "libsneshawk_" + Guid.NewGuid().ToString(); var pipeName = InstanceName; mmf = MemoryMappedFile.CreateNew(pipeName, 1024 * 1024); mmva = mmf.CreateViewAccessor(); mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref mmvaPtr); pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024 * 1024, 1024); instanceDll = new InstanceDll(dllPath); var dllinit = (DllInit)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddress("DllInit"), typeof(DllInit)); dllinit(pipeName); //TODO - start a thread to wait for process to exit and gracefully handle errors? how about the pipe? pipe.WaitForConnection(); rbuf = new IPCRingBuffer(); wbuf = new IPCRingBuffer(); rbuf.Allocate(1024); wbuf.Allocate(1024); rbufstr = new IPCRingBufferStream(rbuf); wbufstr = new IPCRingBufferStream(wbuf); rstream = new SwitcherStream(); wstream = new SwitcherStream(); rstream.SetCurrStream(pipe); wstream.SetCurrStream(pipe); brPipe = new BinaryReader(rstream); bwPipe = new BinaryWriter(wstream); WritePipeMessage(eMessage.eMessage_SetBuffer); bwPipe.Write(1); WritePipeString(rbuf.Id); WritePipeMessage(eMessage.eMessage_SetBuffer); bwPipe.Write(0); WritePipeString(wbuf.Id); bwPipe.Flush(); }
private bool ConnectAllEntryPoints() { bool succeed = true; foreach (var field in GetAllEntryPoints()) { string fieldname = field.Name; IntPtr entry = dll.GetProcAddress(fieldname); if (entry != IntPtr.Zero) { field.SetValue(this, Marshal.GetDelegateForFunctionPointer(entry, field.FieldType)); } else { Console.WriteLine("Couldn't bind libretro entry point {0}", fieldname); succeed = false; } } return(succeed); }