コード例 #1
0
ファイル: LibretroApi.cs プロジェクト: amsolg/AutoMario
        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) => { });
        }
コード例 #2
0
ファイル: LibRetro.cs プロジェクト: robsonfr/BizHawk
 public LibRetro(string modulename)
 {
     dll = new InstanceDll(modulename);
     if (!ConnectAllEntryPoints())
     {
         dll.Dispose();
         throw new Exception("ConnectAllEntryPoints() failed.  The console may contain more details.");
     }
 }
コード例 #3
0
ファイル: LibsnesApi.cs プロジェクト: lenalia/BizHawk
        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();
        }
コード例 #4
0
        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();
        }
コード例 #5
0
ファイル: LibretroApi.cs プロジェクト: gocha/BizHawk
        public LibretroApi(string dllPath, string corePath)
        {
            T GetTypedDelegate <T>(string proc) where T : Delegate => (T)Marshal.GetDelegateForFunctionPointer(instanceDll.GetProcAddrOrThrow(proc), typeof(T));

            InstanceName = "libretro_" + Guid.NewGuid();

            var pipeName = InstanceName;

            instanceDll     = new InstanceDll(dllPath);
            instanceDllCore = new InstanceDll(corePath);

            Message     = GetTypedDelegate <MessageApi>("Message");
            _copyBuffer = GetTypedDelegate <BufferApi>("CopyBuffer");
            _setBuffer  = GetTypedDelegate <BufferApi>("SetBuffer");
            SetVariable = GetTypedDelegate <SetVariableApi>("SetVariable");

            comm = (CommStruct *)(OSTailoredCode.IsUnixHost
                                ? GetTypedDelegate <DllInitUnix>("DllInit")(corePath)
                                : GetTypedDelegate <DllInit>("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)(
            //		(ProcessorFeatureImports.IsProcessorFeaturePresent(ProcessorFeatureImports.ProcessorFeature.InstructionsXMMIAvailable) ? LibRetro.RETRO_SIMD.SSE : 0) |
            //		(ProcessorFeatureImports.IsProcessorFeaturePresent(ProcessorFeatureImports.ProcessorFeature.InstructionsXMMI64Available) ? LibRetro.RETRO_SIMD.SSE2 : 0) |
            //		(ProcessorFeatureImports.IsProcessorFeaturePresent(ProcessorFeatureImports.ProcessorFeature.InstructionsSSE3Available) ? LibRetro.RETRO_SIMD.SSE3 : 0) |
            //		(ProcessorFeatureImports.IsProcessorFeaturePresent(ProcessorFeatureImports.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) => { });
        }
コード例 #6
0
ファイル: GPGX.cs プロジェクト: robsonfr/BizHawk
        public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings)
        {
            ServiceProvider = new BasicServiceProvider(this);
            // this can influence some things internally (autodetect romtype, etc)
            string romextension = "GEN";

            // three or six button?
            // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds

            //hack, don't use
            if (rom != null && rom.Length > 32 * 1024 * 1024)
            {
                throw new InvalidOperationException("ROM too big!  Did you try to load a CD as a ROM?");
            }

            try
            {
                Dll  = new InstanceDll(Path.Combine(comm.CoreFileProvider.DllPath(), LibGPGX.DllName));
                Core = BizInvoker.GetInvoker <LibGPGX>(Dll);

                _syncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings();
                _settings     = (GPGXSettings)Settings ?? new GPGXSettings();

                CoreComm = comm;

                LoadCallback = new LibGPGX.load_archive_cb(load_archive);

                this.romfile          = rom;
                this.CD               = CD;
                this.DiscSectorReader = new DiscSystem.DiscSectorReader(CD);

                LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;
                LibGPGX.INPUT_SYSTEM system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE;

                switch (_syncSettings.ControlType)
                {
                case ControlType.None:
                default:
                    break;

                case ControlType.Activator:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_ACTIVATOR;
                    break;

                case ControlType.Normal:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.OnePlayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    break;

                case ControlType.Xea1p:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_XE_A1P;
                    break;

                case ControlType.Teamplayer:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_TEAMPLAYER;
                    break;

                case ControlType.Wayplay:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_WAYPLAY;
                    break;

                case ControlType.Mouse:
                    system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_MD_GAMEPAD;
                    // seems like mouse in port 1 would be supported, but not both at the same time
                    system_b = LibGPGX.INPUT_SYSTEM.SYSTEM_MOUSE;
                    break;
                }


                if (!Core.gpgx_init(romextension, LoadCallback, _syncSettings.UseSixButton, system_a, system_b, _syncSettings.Region, _settings.GetNativeSettings()))
                {
                    throw new Exception("gpgx_init() failed");
                }

                {
                    int fpsnum = 60;
                    int fpsden = 1;
                    Core.gpgx_get_fps(ref fpsnum, ref fpsden);
                    CoreComm.VsyncNum = fpsnum;
                    CoreComm.VsyncDen = fpsden;
                    Region            = CoreComm.VsyncRate > 55 ? DisplayType.NTSC : DisplayType.PAL;
                }

                // compute state size
                {
                    byte[] tmp  = new byte[Core.gpgx_state_max_size()];
                    int    size = Core.gpgx_state_size(tmp, tmp.Length);
                    if (size <= 0)
                    {
                        throw new Exception("Couldn't Determine GPGX internal state size!");
                    }
                    _savebuff  = new byte[size];
                    _savebuff2 = new byte[_savebuff.Length + 13];
                    Console.WriteLine("GPGX Internal State Size: {0}", size);
                }

                SetControllerDefinition();

                // pull the default video size from the core
                UpdateVideoInitial();

                SetMemoryDomains();

                InputCallback = new LibGPGX.input_cb(input_callback);
                Core.gpgx_set_input_callback(InputCallback);

                if (CD != null)
                {
                    DriveLightEnabled = true;
                }

                // process the non-init settings now
                PutSettings(_settings);

                //TODO - this hits performance, we need to make it controllable
                CDCallback = new LibGPGX.CDCallback(CDCallbackProc);

                InitMemCallbacks();
                KillMemCallbacks();

                Tracer = new GPGXTraceBuffer(this, MemoryDomains, this);
                (ServiceProvider as BasicServiceProvider).Register <ITraceable>(Tracer);
            }
            catch
            {
                Dispose();
                throw;
            }
        }