Example #1
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();
		}
Example #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();
        }