summaryrefslogtreecommitdiffstats
path: root/src/yuzu/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r--src/yuzu/main.cpp152
1 files changed, 61 insertions, 91 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index fe140dce0..6121711e0 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1498,7 +1498,7 @@ void GMainWindow::SetupSigInterrupts() {
void GMainWindow::HandleSigInterrupt(int sig) {
if (sig == SIGINT) {
- exit(1);
+ _exit(1);
}
// Calling into Qt directly from a signal handler is not safe,
@@ -1550,8 +1550,9 @@ void GMainWindow::AllowOSSleep() {
bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) {
// Shutdown previous session if the emu thread is still active...
- if (emu_thread != nullptr)
+ if (emu_thread != nullptr) {
ShutdownGame();
+ }
if (!render_window->InitRenderTarget()) {
return false;
@@ -1710,6 +1711,11 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
system->RegisterExecuteProgramCallback(
[this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); });
+ system->RegisterExitCallback([this] {
+ emu_thread->ForceStop();
+ render_window->Exit();
+ });
+
connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
@@ -1779,7 +1785,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
OnStartGame();
}
-void GMainWindow::ShutdownGame() {
+void GMainWindow::OnShutdownBegin() {
if (!emulation_running) {
return;
}
@@ -1794,20 +1800,48 @@ void GMainWindow::ShutdownGame() {
Settings::values.use_speed_limit.SetValue(true);
system->SetShuttingDown(true);
- system->DetachDebugger();
discord_rpc->Pause();
RequestGameExit();
+ emu_thread->disconnect();
+ emu_thread->SetRunning(true);
emit EmulationStopping();
- // Wait for emulation thread to complete and delete it
- if (!emu_thread->wait(5000)) {
+ shutdown_timer.setSingleShot(true);
+ shutdown_timer.start(system->DebuggerEnabled() ? 0 : 5000);
+ connect(&shutdown_timer, &QTimer::timeout, this, &GMainWindow::OnEmulationStopTimeExpired);
+ connect(emu_thread.get(), &QThread::finished, this, &GMainWindow::OnEmulationStopped);
+
+ // Disable everything to prevent anything from being triggered here
+ ui->action_Pause->setEnabled(false);
+ ui->action_Restart->setEnabled(false);
+ ui->action_Stop->setEnabled(false);
+}
+
+void GMainWindow::OnShutdownBeginDialog() {
+ shutdown_dialog = new OverlayDialog(this, *system, QString{}, tr("Closing software..."),
+ QString{}, QString{}, Qt::AlignHCenter | Qt::AlignVCenter);
+ shutdown_dialog->open();
+}
+
+void GMainWindow::OnEmulationStopTimeExpired() {
+ if (emu_thread) {
emu_thread->ForceStop();
- emu_thread->wait();
}
+}
+
+void GMainWindow::OnEmulationStopped() {
+ shutdown_timer.stop();
+ emu_thread->disconnect();
+ emu_thread->wait();
emu_thread = nullptr;
+ if (shutdown_dialog) {
+ shutdown_dialog->deleteLater();
+ shutdown_dialog = nullptr;
+ }
+
emulation_running = false;
discord_rpc->Update();
@@ -1853,6 +1887,20 @@ void GMainWindow::ShutdownGame() {
// When closing the game, destroy the GLWindow to clear the context after the game is closed
render_window->ReleaseRenderTarget();
+
+ Settings::RestoreGlobalState(system->IsPoweredOn());
+ system->HIDCore().ReloadInputDevices();
+ UpdateStatusButtons();
+}
+
+void GMainWindow::ShutdownGame() {
+ if (!emulation_running) {
+ return;
+ }
+
+ OnShutdownBegin();
+ OnEmulationStopTimeExpired();
+ OnEmulationStopped();
}
void GMainWindow::StoreRecentFile(const QString& filename) {
@@ -2919,8 +2967,6 @@ void GMainWindow::OnStartGame() {
emu_thread->SetRunning(true);
- connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
-
UpdateMenuState();
OnTasStateChanged();
@@ -2957,11 +3003,8 @@ void GMainWindow::OnStopGame() {
return;
}
- ShutdownGame();
-
- Settings::RestoreGlobalState(system->IsPoweredOn());
- system->HIDCore().ReloadInputDevices();
- UpdateStatusButtons();
+ OnShutdownBegin();
+ OnShutdownBeginDialog();
}
void GMainWindow::OnLoadComplete() {
@@ -3904,79 +3947,6 @@ void GMainWindow::OnMouseActivity() {
mouse_center_timer.stop();
}
-void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string details) {
- QMessageBox::StandardButton answer;
- QString status_message;
- const QString common_message =
- tr("The game you are trying to load requires additional files from your Switch to be "
- "dumped "
- "before playing.<br/><br/>For more information on dumping these files, please see the "
- "following wiki page: <a "
- "href='https://yuzu-emu.org/wiki/"
- "dumping-system-archives-and-the-shared-fonts-from-a-switch-console/'>Dumping System "
- "Archives and the Shared Fonts from a Switch Console</a>.<br/><br/>Would you like to "
- "quit "
- "back to the game list? Continuing emulation may result in crashes, corrupted save "
- "data, or other bugs.");
- switch (result) {
- case Core::SystemResultStatus::ErrorSystemFiles: {
- QString message;
- if (details.empty()) {
- message =
- tr("yuzu was unable to locate a Switch system archive. %1").arg(common_message);
- } else {
- message = tr("yuzu was unable to locate a Switch system archive: %1. %2")
- .arg(QString::fromStdString(details), common_message);
- }
-
- answer = QMessageBox::question(this, tr("System Archive Not Found"), message,
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = tr("System Archive Missing");
- break;
- }
-
- case Core::SystemResultStatus::ErrorSharedFont: {
- const QString message =
- tr("yuzu was unable to locate the Switch shared fonts. %1").arg(common_message);
- answer = QMessageBox::question(this, tr("Shared Fonts Not Found"), message,
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = tr("Shared Font Missing");
- break;
- }
-
- default:
- answer = QMessageBox::question(
- this, tr("Fatal Error"),
- tr("yuzu has encountered a fatal error, please see the log for more details. "
- "For more information on accessing the log, please see the following page: "
- "<a href='https://community.citra-emu.org/t/how-to-upload-the-log-file/296'>How "
- "to "
- "Upload the Log File</a>.<br/><br/>Would you like to quit back to the game "
- "list? "
- "Continuing emulation may result in crashes, corrupted save data, or other "
- "bugs."),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = tr("Fatal Error encountered");
- break;
- }
-
- if (answer == QMessageBox::Yes) {
- if (emu_thread) {
- ShutdownGame();
-
- Settings::RestoreGlobalState(system->IsPoweredOn());
- system->HIDCore().ReloadInputDevices();
- UpdateStatusButtons();
- }
- } else {
- // Only show the message if the game is still running.
- if (emu_thread) {
- emu_thread->SetRunning(true);
- message_label->setText(status_message);
- }
- }
-}
-
void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
if (behavior == ReinitializeKeyBehavior::Warning) {
const auto res = QMessageBox::information(
@@ -4121,10 +4091,6 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
// Shutdown session if the emu thread is active...
if (emu_thread != nullptr) {
ShutdownGame();
-
- Settings::RestoreGlobalState(system->IsPoweredOn());
- system->HIDCore().ReloadInputDevices();
- UpdateStatusButtons();
}
render_window->close();
@@ -4217,6 +4183,10 @@ bool GMainWindow::ConfirmForceLockedExit() {
}
void GMainWindow::RequestGameExit() {
+ if (!system->IsPoweredOn()) {
+ return;
+ }
+
auto& sm{system->ServiceManager()};
auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE");
auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE");