SVC::ExitProcess: implement via callback

This commit is contained in:
mailwl 2017-01-31 19:20:57 +03:00
parent d0bf7df5ba
commit ea9250975e
7 changed files with 32 additions and 1 deletions

View File

@ -163,6 +163,8 @@ int main(int argc, char** argv) {
break; // Expected case break; // Expected case
} }
system.SetExitCallback([&]{ emu_window->CloseWindow(); });
while (emu_window->IsOpen()) { while (emu_window->IsOpen()) {
system.RunLoop(); system.RunLoop();
} }

View File

@ -31,6 +31,10 @@ public:
/// Whether the window is still open, and a close request hasn't yet been sent /// Whether the window is still open, and a close request hasn't yet been sent
bool IsOpen() const; bool IsOpen() const;
void CloseWindow() {
is_open = false;
}
/// Load keymap from configuration /// Load keymap from configuration
void ReloadSetKeymaps() override; void ReloadSetKeymaps() override;

View File

@ -342,6 +342,8 @@ void GMainWindow::BootGame(const std::string& filename) {
if (!LoadROM(filename)) if (!LoadROM(filename))
return; return;
Core::System::GetInstance().SetExitCallback([&]{ ShutdownGame(); });
// Create and start the emulation thread // Create and start the emulation thread
emu_thread = std::make_unique<EmuThread>(render_window); emu_thread = std::make_unique<EmuThread>(render_window);
emit EmulationStarting(emu_thread.get()); emit EmulationStarting(emu_thread.get());

View File

@ -113,6 +113,12 @@ void System::PrepareReschedule() {
reschedule_pending = true; reschedule_pending = true;
} }
void System::ExitCallback() {
if (exit_callback) {
exit_callback();
}
}
void System::Reschedule() { void System::Reschedule() {
if (!reschedule_pending) { if (!reschedule_pending) {
return; return;

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
@ -83,6 +84,12 @@ public:
/// Prepare the core emulation for a reschedule /// Prepare the core emulation for a reschedule
void PrepareReschedule(); void PrepareReschedule();
void SetExitCallback(std::function<void()> callback) {
exit_callback = callback;
}
void ExitCallback();
/** /**
* Gets a reference to the emulated CPU. * Gets a reference to the emulated CPU.
* @returns A reference to the emulated CPU. * @returns A reference to the emulated CPU.
@ -112,6 +119,8 @@ private:
/// When true, signals that a reschedule should happen /// When true, signals that a reschedule should happen
bool reschedule_pending{}; bool reschedule_pending{};
std::function<void()> exit_callback;
static System s_instance; static System s_instance;
}; };

View File

@ -770,6 +770,12 @@ static ResultCode CreateEvent(Kernel::Handle* out_handle, u32 reset_type) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
/// Exit current process
static void ExitProcess() {
LOG_WARNING(Kernel_SVC, "called");
Core::System::GetInstance().ExitCallback();
}
/// Duplicates a kernel handle /// Duplicates a kernel handle
static ResultCode DuplicateHandle(Kernel::Handle* out, Kernel::Handle handle) { static ResultCode DuplicateHandle(Kernel::Handle* out, Kernel::Handle handle) {
CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle)); CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle));
@ -1074,7 +1080,7 @@ static const FunctionDef SVC_Table[] = {
{0x00, nullptr, "Unknown"}, {0x00, nullptr, "Unknown"},
{0x01, HLE::Wrap<ControlMemory>, "ControlMemory"}, {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"},
{0x02, HLE::Wrap<QueryMemory>, "QueryMemory"}, {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"},
{0x03, nullptr, "ExitProcess"}, {0x03, ExitProcess, "ExitProcess"},
{0x04, nullptr, "GetProcessAffinityMask"}, {0x04, nullptr, "GetProcessAffinityMask"},
{0x05, nullptr, "SetProcessAffinityMask"}, {0x05, nullptr, "SetProcessAffinityMask"},
{0x06, nullptr, "GetProcessIdealProcessor"}, {0x06, nullptr, "GetProcessIdealProcessor"},

View File

@ -147,6 +147,8 @@ static u8* GetPointerFromVMA(VAddr vaddr) {
case Kernel::VMAType::BackingMemory: case Kernel::VMAType::BackingMemory:
direct_pointer = vma.backing_memory; direct_pointer = vma.backing_memory;
break; break;
case Kernel::VMAType::Free:
return nullptr;
default: default:
UNREACHABLE(); UNREACHABLE();
} }