diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index e52b8a7c..10d65c77 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -448,6 +448,8 @@ namespace CafeSystem bool sSystemRunning = false; TitleId sForegroundTitleId = 0; + bool sTitlePaused = false; + GameInfo2 sGameInfo_ForegroundTitle; @@ -931,6 +933,30 @@ namespace CafeSystem return sSystemRunning; } + void PauseTitle() + { + if (!sSystemRunning || sTitlePaused) + { + return; + } + + sTitlePaused = true; + + coreinit::SuspendActiveThreads(); + } + + void ResumeTitle() + { + if (!sSystemRunning || !sTitlePaused) + { + return; + } + + sTitlePaused = false; + + coreinit::ResumeActiveThreads(); + } + TitleId GetForegroundTitleId() { cemu_assert_debug(sForegroundTitleId != 0); diff --git a/src/Cafe/CafeSystem.h b/src/Cafe/CafeSystem.h index ddf7621c..6eb049b7 100644 --- a/src/Cafe/CafeSystem.h +++ b/src/Cafe/CafeSystem.h @@ -31,6 +31,9 @@ namespace CafeSystem void LaunchForegroundTitle(); bool IsTitleRunning(); + void PauseTitle(); + void ResumeTitle(); + bool GetOverrideArgStr(std::vector& args); void SetOverrideArgs(std::span args); void UnsetOverrideArgs(); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index 52dc0318..f3ecb8fc 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -94,6 +94,42 @@ namespace coreinit uint32 selectedCore; }; + void SuspendActiveThreads() + { + if (activeThreadCount == 0) + { + return; + } + + __OSLockScheduler(); + + for (sint32 i = 0; i < activeThreadCount; i++) + { + auto thread = reinterpret_cast(memory_getPointerFromVirtualOffset(activeThread[i])); + __OSSuspendThreadNolock(thread); + } + + __OSUnlockScheduler(); + } + + void ResumeActiveThreads() + { + if (activeThreadCount == 0) + { + return; + } + + __OSLockScheduler(); + + for (sint32 i = 0; i < activeThreadCount; i++) + { + auto thread = reinterpret_cast(memory_getPointerFromVirtualOffset(activeThread[i])); + __OSResumeThreadInternal(thread, 1); + } + + __OSUnlockScheduler(); + } + std::unordered_map s_threadToFiber; bool __CemuIsMulticoreMode() diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index c199e59f..4499ae6d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -508,6 +508,9 @@ namespace coreinit void InitializeConcurrency(); + void SuspendActiveThreads(); + void ResumeActiveThreads(); + bool __CemuIsMulticoreMode(); OSThread_t* OSGetDefaultThread(sint32 coreIndex);