summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar TheKoopaKingdom2017-03-08 16:28:30 -0500
committerGravatar TheKoopaKingdom2017-06-02 18:27:56 -0400
commit1ecb322daa0e2521fe0e179e87889db9aaaf63b0 (patch)
tree6f8cc571b41a76c7ab93843472809bfc9121abb7 /src
parentFixed encrypted ROM error messages. (diff)
downloadyuzu-1ecb322daa0e2521fe0e179e87889db9aaaf63b0.tar.gz
yuzu-1ecb322daa0e2521fe0e179e87889db9aaaf63b0.tar.xz
yuzu-1ecb322daa0e2521fe0e179e87889db9aaaf63b0.zip
Added system for handling core errors in citra-qt.
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/bootmanager.cpp6
-rw-r--r--src/citra_qt/bootmanager.h3
-rw-r--r--src/citra_qt/main.cpp86
-rw-r--r--src/citra_qt/main.h1
-rw-r--r--src/core/core.cpp24
-rw-r--r--src/core/core.h13
-rw-r--r--src/core/hle/service/apt/apt.cpp7
-rw-r--r--src/core/hle/service/err_f.cpp2
-rw-r--r--src/core/hle/service/fs/fs_user.cpp5
9 files changed, 121 insertions, 26 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 06b62f44c..16661767f 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -37,7 +37,11 @@ void EmuThread::run() {
37 if (!was_active) 37 if (!was_active)
38 emit DebugModeLeft(); 38 emit DebugModeLeft();
39 39
40 Core::System::GetInstance().RunLoop(); 40 Core::System::ResultStatus result = Core::System::GetInstance().RunLoop();
41 if (result != Core::System::ResultStatus::Success) {
42 emit ErrorThrown(result);
43 break;
44 }
41 45
42 was_active = running || exec_step; 46 was_active = running || exec_step;
43 if (!was_active && !stop_run) 47 if (!was_active && !stop_run)
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index 9d39f1af8..c5430a3fa 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -10,6 +10,7 @@
10#include <QGLWidget> 10#include <QGLWidget>
11#include <QThread> 11#include <QThread>
12#include "common/thread.h" 12#include "common/thread.h"
13#include "core/core.h"
13#include "core/frontend/emu_window.h" 14#include "core/frontend/emu_window.h"
14#include "core/frontend/motion_emu.h" 15#include "core/frontend/motion_emu.h"
15 16
@@ -97,6 +98,8 @@ signals:
97 * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) 98 * Qt::BlockingQueuedConnection (additionally block source thread until slot returns)
98 */ 99 */
99 void DebugModeLeft(); 100 void DebugModeLeft();
101
102 void ErrorThrown(Core::System::ResultStatus);
100}; 103};
101 104
102class GRenderWindow : public QWidget, public EmuWindow { 105class GRenderWindow : public QWidget, public EmuWindow {
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index eb2c7d613..e24c48e90 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -301,8 +301,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
301 301
302 if (!gladLoadGL()) { 302 if (!gladLoadGL()) {
303 QMessageBox::critical(this, tr("Error while starting Citra!"), 303 QMessageBox::critical(this, tr("Error while starting Citra!"),
304 tr("Failed to initialize the video core!\n\n" 304 tr("Your GPU may not support OpenGL 3.3, or you do not"
305 "Please ensure that your GPU supports OpenGL 3.3 and that you "
306 "have the latest graphics driver.")); 305 "have the latest graphics driver."));
307 return false; 306 return false;
308 } 307 }
@@ -327,18 +326,17 @@ bool GMainWindow::LoadROM(const QString& filename) {
327 break; 326 break;
328 327
329 case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: { 328 case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: {
330 // Build the MessageBox ourselves to have clickable link 329 QMessageBox::critical(
331 QMessageBox popup_error; 330 this, tr("Error while loading ROM!"),
332 popup_error.setTextFormat(Qt::RichText);
333 popup_error.setWindowTitle(tr("Error while loading ROM!"));
334 popup_error.setText(
335 tr("The game that you are trying to load must be decrypted before being used with " 331 tr("The game that you are trying to load must be decrypted before being used with "
336 "Citra.<br/><br/>" 332 "Citra.<br/><br/>"
337 "For more information on dumping and decrypting games, please see: <a " 333 "For more information on dumping and decrypting games, please see the following "
338 "href='https://citra-emu.org/wiki/Dumping-Game-Cartridges'>https://" 334 "wiki pages: <ul>"
339 "citra-emu.org/wiki/Dumping-Game-Cartridges</a>")); 335 "<li><a href='https://citra-emu.org/wiki/Dumping-Game-Cartridges/'>Dumping Game "
340 popup_error.setIcon(QMessageBox::Critical); 336 "Cartridges</a></li>"
341 popup_error.exec(); 337 "<li><a href='https://citra-emu.org/wiki/Dumping-Installed-Titles/'>Dumping "
338 "Installed Titles</a></li>"
339 "</ul>"));
342 break; 340 break;
343 } 341 }
344 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: 342 case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat:
@@ -346,8 +344,16 @@ bool GMainWindow::LoadROM(const QString& filename) {
346 tr("The ROM format is not supported.")); 344 tr("The ROM format is not supported."));
347 break; 345 break;
348 346
347 case Core::System::ResultStatus::ErrorOpenGL:
348 QMessageBox::critical(this, tr("Error while loading OpenGL!"),
349 tr("Your GPU may not support OpenGL 3.3, or you do not "
350 "have the latest graphics driver."));
351 break;
352
349 default: 353 default:
350 QMessageBox::critical(this, tr("Error while loading ROM!"), tr("Unknown error!")); 354 QMessageBox::critical(
355 this, tr("Error while loading ROM!"),
356 tr("An unknown error occured. Please see the log for more details."));
351 break; 357 break;
352 } 358 }
353 return false; 359 return false;
@@ -530,6 +536,9 @@ void GMainWindow::OnMenuRecentFile() {
530 536
531void GMainWindow::OnStartGame() { 537void GMainWindow::OnStartGame() {
532 emu_thread->SetRunning(true); 538 emu_thread->SetRunning(true);
539 qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
540 connect(emu_thread.get(), SIGNAL(ErrorThrown(Core::System::ResultStatus)), this,
541 SLOT(OnCoreError(Core::System::ResultStatus)));
533 542
534 ui.action_Start->setEnabled(false); 543 ui.action_Start->setEnabled(false);
535 ui.action_Start->setText(tr("Continue")); 544 ui.action_Start->setText(tr("Continue"));
@@ -622,14 +631,57 @@ void GMainWindow::UpdateStatusBar() {
622 emu_frametime_label->setVisible(true); 631 emu_frametime_label->setVisible(true);
623} 632}
624 633
634void GMainWindow::OnCoreError(Core::System::ResultStatus result) {
635 // Waiting for the dialog to be closed before shutting down causes a segfault, maybe because of
636 // the profiler
637 ShutdownGame();
638 switch (result) {
639 case Core::System::ResultStatus::ErrorSystemFiles:
640 QMessageBox::critical(
641 this, "System Archive Not Found",
642 "Citra was unable to locate the 3DS system archive.<br/><br/>"
643 "The game you are trying to load requires additional files from your 3DS to be dumped "
644 "before playing.<br/><br/>"
645 "For more information on dumping these files, please see the following wiki page: "
646 "<a "
647 "href='https://citra-emu.org/wiki/"
648 "Dumping-System-Archives-and-the-Shared-Fonts-from-a-3DS-Console/'>Dumping System "
649 "Archives and the Shared Fonts from a 3DS Console</a>"
650 ".");
651 break;
652
653 case Core::System::ResultStatus::ErrorSharedFont:
654 QMessageBox::critical(
655 this, "Shared Fonts Not Found",
656 "Citra was unable to locate the 3DS shared fonts.<br/><br/>"
657 "The game you are trying to load requires additional files from your 3DS to be dumped "
658 "before playing.<br/><br/>"
659 "For more information on dumping these files, please see the following wiki page: "
660 "<a "
661 "href='https://citra-emu.org/wiki/"
662 "Dumping-System-Archives-and-the-Shared-Fonts-from-a-3DS-Console/'>Dumping System "
663 "Archives and the Shared Fonts from a 3DS Console</a>"
664 ".");
665 break;
666
667 case Core::System::ResultStatus::ErrorUnknown:
668 QMessageBox::critical(
669 this, "Fatal Error",
670 "Citra has encountered a fatal error, please see the log for more details.");
671 break;
672
673 default:
674 break;
675 }
676}
677
625bool GMainWindow::ConfirmClose() { 678bool GMainWindow::ConfirmClose() {
626 if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) 679 if (emu_thread == nullptr || !UISettings::values.confirm_before_closing)
627 return true; 680 return true;
628 681
629 auto answer = 682 return QMessageBox::question(this, tr("Citra"), tr("Are you sure you want to close Citra?"),
630 QMessageBox::question(this, tr("Citra"), tr("Are you sure you want to close Citra?"), 683 QMessageBox::Yes | QMessageBox::No,
631 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); 684 QMessageBox::No) != QMessageBox::No;
632 return answer != QMessageBox::No;
633} 685}
634 686
635void GMainWindow::closeEvent(QCloseEvent* event) { 687void GMainWindow::closeEvent(QCloseEvent* event) {
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index cb2e87cbd..1ce0607e2 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -125,6 +125,7 @@ private slots:
125 void OnDisplayTitleBars(bool); 125 void OnDisplayTitleBars(bool);
126 void ToggleWindowMode(); 126 void ToggleWindowMode();
127 void OnCreateGraphicsSurfaceViewer(); 127 void OnCreateGraphicsSurfaceViewer();
128 void OnCoreError(Core::System::ResultStatus);
128 129
129private: 130private:
130 void UpdateStatusBar(); 131 void UpdateStatusBar();
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 450e7566d..1861bfa9b 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -59,7 +59,7 @@ System::ResultStatus System::RunLoop(int tight_loop) {
59 HW::Update(); 59 HW::Update();
60 Reschedule(); 60 Reschedule();
61 61
62 return ResultStatus::Success; 62 return GetStatus();
63} 63}
64 64
65System::ResultStatus System::SingleStep() { 65System::ResultStatus System::SingleStep() {
@@ -73,11 +73,21 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
73 LOG_CRITICAL(Core, "Failed to obtain loader for %s!", filepath.c_str()); 73 LOG_CRITICAL(Core, "Failed to obtain loader for %s!", filepath.c_str());
74 return ResultStatus::ErrorGetLoader; 74 return ResultStatus::ErrorGetLoader;
75 } 75 }
76 boost::optional<u32> system_mode = boost::none;
76 77
77 boost::optional<u32> system_mode{app_loader->LoadKernelSystemMode()}; 78 Loader::ResultStatus load_result{app_loader->LoadKernelSystemMode(system_mode)};
78 if (!system_mode) { 79 if (!system_mode) {
79 LOG_CRITICAL(Core, "Failed to determine system mode!"); 80 LOG_CRITICAL(Core, "Failed to determine system mode (Error %i)!", load_result);
80 return ResultStatus::ErrorSystemMode; 81 System::Shutdown();
82
83 switch (load_result) {
84 case Loader::ResultStatus::ErrorEncrypted:
85 return ResultStatus::ErrorLoader_ErrorEncrypted;
86 case Loader::ResultStatus::ErrorInvalidFormat:
87 return ResultStatus::ErrorLoader_ErrorInvalidFormat;
88 default:
89 return ResultStatus::ErrorSystemMode;
90 }
81 } 91 }
82 92
83 ResultStatus init_result{Init(emu_window, system_mode.get())}; 93 ResultStatus init_result{Init(emu_window, system_mode.get())};
@@ -87,7 +97,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
87 return init_result; 97 return init_result;
88 } 98 }
89 99
90 const Loader::ResultStatus load_result{app_loader->Load()}; 100 load_result = app_loader->Load();
91 if (Loader::ResultStatus::Success != load_result) { 101 if (Loader::ResultStatus::Success != load_result) {
92 LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result); 102 LOG_CRITICAL(Core, "Failed to load ROM (Error %i)!", load_result);
93 System::Shutdown(); 103 System::Shutdown();
@@ -101,6 +111,8 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
101 return ResultStatus::ErrorLoader; 111 return ResultStatus::ErrorLoader;
102 } 112 }
103 } 113 }
114 // this->status will be used for errors while actually running the game
115 status = ResultStatus::Success;
104 return ResultStatus::Success; 116 return ResultStatus::Success;
105} 117}
106 118
@@ -142,7 +154,7 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
142 GDBStub::Init(); 154 GDBStub::Init();
143 155
144 if (!VideoCore::Init(emu_window)) { 156 if (!VideoCore::Init(emu_window)) {
145 return ResultStatus::ErrorVideoCore; 157 return ResultStatus::ErrorOpenGL;
146 } 158 }
147 159
148 LOG_DEBUG(Core, "Initialized OK"); 160 LOG_DEBUG(Core, "Initialized OK");
diff --git a/src/core/core.h b/src/core/core.h
index 6af772831..0963f273e 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -40,7 +40,11 @@ public:
40 ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption 40 ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
41 ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an 41 ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
42 /// invalid format 42 /// invalid format
43 ErrorSystemFiles, ///< Error in finding system files
44 ErrorSharedFont, ///< Error in finding shared font
43 ErrorVideoCore, ///< Error in the video core 45 ErrorVideoCore, ///< Error in the video core
46 ErrorOpenGL, ///< Error when initializing OpenGL
47 ErrorUnknown ///< Any other error
44 }; 48 };
45 49
46 /** 50 /**
@@ -105,6 +109,14 @@ public:
105 PerfStats perf_stats; 109 PerfStats perf_stats;
106 FrameLimiter frame_limiter; 110 FrameLimiter frame_limiter;
107 111
112 ResultStatus GetStatus() {
113 return status;
114 }
115
116 void SetStatus(ResultStatus newStatus) {
117 status = newStatus;
118 }
119
108private: 120private:
109 /** 121 /**
110 * Initialize the emulated system. 122 * Initialize the emulated system.
@@ -130,6 +142,7 @@ private:
130 std::unique_ptr<Core::TelemetrySession> telemetry_session; 142 std::unique_ptr<Core::TelemetrySession> telemetry_session;
131 143
132 static System s_instance; 144 static System s_instance;
145 ResultStatus status;
133}; 146};
134 147
135inline ARM_Interface& CPU() { 148inline ARM_Interface& CPU() {
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 366d1eacf..a92abb58f 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -5,6 +5,7 @@
5#include "common/common_paths.h" 5#include "common/common_paths.h"
6#include "common/file_util.h" 6#include "common/file_util.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/core.h"
8#include "core/hle/applets/applet.h" 9#include "core/hle/applets/applet.h"
9#include "core/hle/kernel/event.h" 10#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/mutex.h" 11#include "core/hle/kernel/mutex.h"
@@ -74,6 +75,7 @@ void GetSharedFont(Service::Interface* self) {
74 LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds"); 75 LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds");
75 rb.Push<u32>(-1); // TODO: Find the right error code 76 rb.Push<u32>(-1); // TODO: Find the right error code
76 rb.Skip(1 + 2, true); 77 rb.Skip(1 + 2, true);
78 Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorSharedFont);
77 return; 79 return;
78 } 80 }
79 81
@@ -279,8 +281,9 @@ void CancelParameter(Service::Interface* self) {
279 rb.Push(RESULT_SUCCESS); // No error 281 rb.Push(RESULT_SUCCESS); // No error
280 rb.Push(true); // Set to Success 282 rb.Push(true); // Set to Success
281 283
282 LOG_WARNING(Service_APT, "(STUBBED) called check_sender=0x%08X, sender_appid=0x%08X, " 284 LOG_WARNING(Service_APT,
283 "check_receiver=0x%08X, receiver_appid=0x%08X", 285 "(STUBBED) called check_sender=0x%08X, sender_appid=0x%08X, "
286 "check_receiver=0x%08X, receiver_appid=0x%08X",
284 check_sender, sender_appid, check_receiver, receiver_appid); 287 check_sender, sender_appid, check_receiver, receiver_appid);
285} 288}
286 289
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index 9da55f328..4f4dc6dc7 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -10,6 +10,7 @@
10#include "common/bit_field.h" 10#include "common/bit_field.h"
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "core/core.h"
13#include "core/hle/result.h" 14#include "core/hle/result.h"
14#include "core/hle/service/err_f.h" 15#include "core/hle/service/err_f.h"
15 16
@@ -172,6 +173,7 @@ static void ThrowFatalError(Interface* self) {
172 const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]); 173 const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
173 LOG_CRITICAL(Service_ERR, "Fatal error type: %s", 174 LOG_CRITICAL(Service_ERR, "Fatal error type: %s",
174 GetErrType(errinfo->errinfo_common.specifier).c_str()); 175 GetErrType(errinfo->errinfo_common.specifier).c_str());
176 Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorUnknown);
175 177
176 // Generic Info 178 // Generic Info
177 LogGenericInfo(errinfo->errinfo_common); 179 LogGenericInfo(errinfo->errinfo_common);
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index e53a970d3..5a4437123 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -8,6 +8,7 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/scope_exit.h" 9#include "common/scope_exit.h"
10#include "common/string_util.h" 10#include "common/string_util.h"
11#include "core/core.h"
11#include "core/file_sys/errors.h" 12#include "core/file_sys/errors.h"
12#include "core/hle/kernel/client_session.h" 13#include "core/hle/kernel/client_session.h"
13#include "core/hle/result.h" 14#include "core/hle/result.h"
@@ -132,6 +133,10 @@ static void OpenFileDirectly(Service::Interface* self) {
132 LOG_ERROR(Service_FS, 133 LOG_ERROR(Service_FS,
133 "failed to get a handle for archive archive_id=0x%08X archive_path=%s", 134 "failed to get a handle for archive archive_id=0x%08X archive_path=%s",
134 static_cast<u32>(archive_id), archive_path.DebugStr().c_str()); 135 static_cast<u32>(archive_id), archive_path.DebugStr().c_str());
136 if (static_cast<u32>(archive_id) == 0x2345678A) {
137 Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorSystemFiles);
138 return;
139 }
135 cmd_buff[1] = archive_handle.Code().raw; 140 cmd_buff[1] = archive_handle.Code().raw;
136 cmd_buff[3] = 0; 141 cmd_buff[3] = 0;
137 return; 142 return;