diff --git a/Program.cs b/Program.cs index 3d4481aa..88a8a117 100644 --- a/Program.cs +++ b/Program.cs @@ -50,6 +50,10 @@ namespace Ryujinx using (GLScreen Screen = new GLScreen(Ns, Renderer)) { + Ns.Finish += (Sender, Args) => { + Screen.Exit(); + }; + Screen.Run(60.0); } diff --git a/Ryujinx/OsHle/Horizon.cs b/Ryujinx/OsHle/Horizon.cs index dd578730..f3108873 100644 --- a/Ryujinx/OsHle/Horizon.cs +++ b/Ryujinx/OsHle/Horizon.cs @@ -4,6 +4,7 @@ using Ryujinx.OsHle.Handles; using Ryujinx.OsHle.Utilities; using System.Collections.Concurrent; using System.IO; +using System; namespace Ryujinx.OsHle { @@ -136,6 +137,18 @@ namespace Ryujinx.OsHle } } + internal bool ExitProcess(int ProcessId) { + Process process; + var Success = Processes.TryRemove(ProcessId, out process); + if (Success) { + process.StopAllThreads(); + } + + if (Processes.Count == 0) { + Ns.OnFinish(EventArgs.Empty); + } + return Success; + } internal bool TryGetProcess(int ProcessId, out Process Process) { if (!Processes.TryGetValue(ProcessId, out Process)) diff --git a/Ryujinx/OsHle/Process.cs b/Ryujinx/OsHle/Process.cs index 653d9dfd..05f12c1a 100644 --- a/Ryujinx/OsHle/Process.cs +++ b/Ryujinx/OsHle/Process.cs @@ -116,7 +116,7 @@ namespace Ryujinx.OsHle { if (MainThread != null) { - while (MainThread.Thread.IsAlive) + if (MainThread.Thread.IsAlive) { MainThread.Thread.StopExecution(); } @@ -124,7 +124,7 @@ namespace Ryujinx.OsHle foreach (AThread Thread in TlsSlots.Values) { - while (Thread.IsAlive) + if (Thread.IsAlive) { Thread.StopExecution(); } diff --git a/Ryujinx/OsHle/Svc/SvcHandler.cs b/Ryujinx/OsHle/Svc/SvcHandler.cs index ad228c45..2191793a 100644 --- a/Ryujinx/OsHle/Svc/SvcHandler.cs +++ b/Ryujinx/OsHle/Svc/SvcHandler.cs @@ -8,7 +8,6 @@ namespace Ryujinx.OsHle.Svc partial class SvcHandler { private delegate void SvcFunc(ARegisters Registers); - private Dictionary SvcFuncs; private Switch Ns; @@ -25,6 +24,7 @@ namespace Ryujinx.OsHle.Svc { 0x03, SvcSetMemoryAttribute }, { 0x04, SvcMapMemory }, { 0x06, SvcQueryMemory }, + { 0x07, SvcExitProcess }, { 0x08, SvcCreateThread }, { 0x09, SvcStartThread }, { 0x0b, SvcSleepThread }, diff --git a/Ryujinx/OsHle/Svc/SvcSystem.cs b/Ryujinx/OsHle/Svc/SvcSystem.cs index 098ddb2f..09f7e74c 100644 --- a/Ryujinx/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx/OsHle/Svc/SvcSystem.cs @@ -9,6 +9,8 @@ namespace Ryujinx.OsHle.Svc { partial class SvcHandler { + private void SvcExitProcess(ARegisters Registers) => Ns.Os.ExitProcess(Registers.ProcessId); + private void SvcCloseHandle(ARegisters Registers) { int Handle = (int)Registers.X0; diff --git a/Ryujinx/Switch.cs b/Ryujinx/Switch.cs index 9e5ea7d0..e912da86 100644 --- a/Ryujinx/Switch.cs +++ b/Ryujinx/Switch.cs @@ -24,6 +24,15 @@ namespace Ryujinx VFs = new VirtualFs(); } + public event EventHandler Finish; + internal virtual void OnFinish(EventArgs e) + { + EventHandler Handler = Finish; + if (Handler != null) + { + Handler(this, e); + } + } public void Dispose() { Dispose(true);