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();
        }
Beispiel #2
0
        public LibsnesApi(string exePath)
        {
            //make sure we've checked this exe for OKness.. the dry run should keep us from freezing up or crashing weirdly if the external process isnt correct
            if (!okExes.Contains(exePath))
            {
                bool ok = DryRun(exePath);
                if (!ok)
                {
                    throw new InvalidOperationException(string.Format("Couldn't launch {0} to run SNES core. Not sure why this would have happened. Try redownloading BizHawk first.", Path.GetFileName(exePath)));
                }
                okExes.Add(exePath);
            }

            InstanceName = "libsneshawk_" + Guid.NewGuid().ToString();

#if DEBUG
            //use this to get a debug console with libsnes output
            InstanceName = "console-" + InstanceName;
#endif

            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);

            //slim chance this might be useful sometimes:
            //http://stackoverflow.com/questions/2590334/creating-a-cross-process-eventwaithandle
            //create an event for the child process to monitor with a watchdog, to make sure it terminates when the emuhawk process terminates.
            //NOTE: this is alarming! for some reason .net releases this event when it gets finalized, instead of when i (dont) dispose it.
            bool createdNew;
            watchdogEvent = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset, InstanceName + "-event", out createdNew);

            process = new Process();
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
            process.StartInfo.FileName         = exePath;
            process.StartInfo.Arguments        = pipeName;
            process.StartInfo.ErrorDialog      = true;
            process.Start();

            //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();
        }