summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/CMakeLists.txt8
-rw-r--r--src/yuzu/applets/error.cpp59
-rw-r--r--src/yuzu/applets/error.h33
-rw-r--r--src/yuzu/bootmanager.cpp13
-rw-r--r--src/yuzu/bootmanager.h1
-rw-r--r--src/yuzu/configuration/config.cpp3
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp2
-rw-r--r--src/yuzu/configuration/configure_graphics.ui7
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp19
-rw-r--r--src/yuzu/configuration/configure_hotkeys.h3
-rw-r--r--src/yuzu/debugger/wait_tree.cpp11
-rw-r--r--src/yuzu/game_list_p.h2
-rw-r--r--src/yuzu/main.cpp17
-rw-r--r--src/yuzu/main.h3
15 files changed, 154 insertions, 29 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 2eb86d6e5..5138bd9a3 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -7,6 +7,8 @@ add_executable(yuzu
Info.plist
about_dialog.cpp
about_dialog.h
+ applets/error.cpp
+ applets/error.h
applets/profile_select.cpp
applets/profile_select.h
applets/software_keyboard.cpp
@@ -151,6 +153,12 @@ target_link_libraries(yuzu PRIVATE common core input_common video_core)
target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::OpenGL Qt5::Widgets)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
+target_compile_definitions(yuzu PRIVATE
+ # Use QStringBuilder for string concatenation to reduce
+ # the overall number of temporary strings created.
+ -DQT_USE_QSTRINGBUILDER
+)
+
if (YUZU_ENABLE_COMPATIBILITY_REPORTING)
target_compile_definitions(yuzu PRIVATE -DYUZU_ENABLE_COMPATIBILITY_REPORTING)
endif()
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/error.cpp
new file mode 100644
index 000000000..1fb2fe277
--- /dev/null
+++ b/src/yuzu/applets/error.cpp
@@ -0,0 +1,59 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QDateTime>
+#include "core/hle/lock.h"
+#include "yuzu/applets/error.h"
+#include "yuzu/main.h"
+
+QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) {
+ connect(this, &QtErrorDisplay::MainWindowDisplayError, &parent,
+ &GMainWindow::ErrorDisplayDisplayError, Qt::QueuedConnection);
+ connect(&parent, &GMainWindow::ErrorDisplayFinished, this,
+ &QtErrorDisplay::MainWindowFinishedError, Qt::DirectConnection);
+}
+
+QtErrorDisplay::~QtErrorDisplay() = default;
+
+void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished) const {
+ this->callback = std::move(finished);
+ emit MainWindowDisplayError(
+ tr("An error has occured.\nPlease try again or contact the developer of the "
+ "software.\n\nError Code: %1-%2 (0x%3)")
+ .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
+ .arg(error.description, 4, 10, QChar::fromLatin1('0'))
+ .arg(error.raw, 8, 16, QChar::fromLatin1('0')));
+}
+
+void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
+ std::function<void()> finished) const {
+ this->callback = std::move(finished);
+ emit MainWindowDisplayError(
+ tr("An error occured on %1 at %2.\nPlease try again or contact the "
+ "developer of the software.\n\nError Code: %3-%4 (0x%5)")
+ .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("dddd, MMMM d, yyyy"))
+ .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("h:mm:ss A"))
+ .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
+ .arg(error.description, 4, 10, QChar::fromLatin1('0'))
+ .arg(error.raw, 8, 16, QChar::fromLatin1('0')));
+}
+
+void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_text,
+ std::string fullscreen_text,
+ std::function<void()> finished) const {
+ this->callback = std::move(finished);
+ emit MainWindowDisplayError(
+ tr("An error has occured.\nError Code: %1-%2 (0x%3)\n\n%4\n\n%5")
+ .arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
+ .arg(error.description, 4, 10, QChar::fromLatin1('0'))
+ .arg(error.raw, 8, 16, QChar::fromLatin1('0'))
+ .arg(QString::fromStdString(dialog_text))
+ .arg(QString::fromStdString(fullscreen_text)));
+}
+
+void QtErrorDisplay::MainWindowFinishedError() {
+ // Acquire the HLE mutex
+ std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
+ callback();
+}
diff --git a/src/yuzu/applets/error.h b/src/yuzu/applets/error.h
new file mode 100644
index 000000000..b0932d895
--- /dev/null
+++ b/src/yuzu/applets/error.h
@@ -0,0 +1,33 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QObject>
+
+#include "core/frontend/applets/error.h"
+
+class GMainWindow;
+
+class QtErrorDisplay final : public QObject, public Core::Frontend::ErrorApplet {
+ Q_OBJECT
+
+public:
+ explicit QtErrorDisplay(GMainWindow& parent);
+ ~QtErrorDisplay() override;
+
+ void ShowError(ResultCode error, std::function<void()> finished) const override;
+ void ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
+ std::function<void()> finished) const override;
+ void ShowCustomErrorText(ResultCode error, std::string dialog_text, std::string fullscreen_text,
+ std::function<void()> finished) const override;
+
+signals:
+ void MainWindowDisplayError(QString error) const;
+
+private:
+ void MainWindowFinishedError();
+
+ mutable std::function<void()> callback;
+};
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index c29f2d2dc..5c98636c5 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -91,8 +91,8 @@ void EmuThread::run() {
class GGLContext : public Core::Frontend::GraphicsContext {
public:
- explicit GGLContext(QOpenGLContext* shared_context) : surface() {
- context = std::make_unique<QOpenGLContext>(shared_context);
+ explicit GGLContext(QOpenGLContext* shared_context)
+ : context{std::make_unique<QOpenGLContext>(shared_context)} {
surface.setFormat(shared_context->format());
surface.create();
}
@@ -186,8 +186,7 @@ private:
};
GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
- : QWidget(parent), child(nullptr), context(nullptr), emu_thread(emu_thread) {
-
+ : QWidget(parent), emu_thread(emu_thread) {
setWindowTitle(QStringLiteral("yuzu %1 | %2-%3")
.arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
setAttribute(Qt::WA_AcceptTouchEvents);
@@ -378,7 +377,11 @@ void GRenderWindow::InitRenderTarget() {
// WA_DontShowOnScreen, WA_DeleteOnClose
QSurfaceFormat fmt;
fmt.setVersion(4, 3);
- fmt.setProfile(QSurfaceFormat::CoreProfile);
+ if (Settings::values.use_compatibility_profile) {
+ fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
+ } else {
+ fmt.setProfile(QSurfaceFormat::CoreProfile);
+ }
// TODO: expose a setting for buffer value (ie default/single/double/triple)
fmt.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior);
shared_context = std::make_unique<QOpenGLContext>();
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 9608b959f..3df33aca1 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -10,7 +10,6 @@
#include <QImage>
#include <QThread>
#include <QWidget>
-#include "common/thread.h"
#include "core/core.h"
#include "core/frontend/emu_window.h"
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 8725a78dc..6c6f047d8 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -389,6 +389,8 @@ void Config::ReadValues() {
Settings::values.resolution_factor = ReadSetting("resolution_factor", 1.0).toFloat();
Settings::values.use_frame_limit = ReadSetting("use_frame_limit", true).toBool();
Settings::values.frame_limit = ReadSetting("frame_limit", 100).toInt();
+ Settings::values.use_compatibility_profile =
+ ReadSetting("use_compatibility_profile", true).toBool();
Settings::values.use_disk_shader_cache = ReadSetting("use_disk_shader_cache", true).toBool();
Settings::values.use_accurate_gpu_emulation =
ReadSetting("use_accurate_gpu_emulation", false).toBool();
@@ -661,6 +663,7 @@ void Config::SaveValues() {
WriteSetting("resolution_factor", (double)Settings::values.resolution_factor, 1.0);
WriteSetting("use_frame_limit", Settings::values.use_frame_limit, true);
WriteSetting("frame_limit", Settings::values.frame_limit, 100);
+ WriteSetting("use_compatibility_profile", Settings::values.use_compatibility_profile, true);
WriteSetting("use_disk_shader_cache", Settings::values.use_disk_shader_cache, true);
WriteSetting("use_accurate_gpu_emulation", Settings::values.use_accurate_gpu_emulation, false);
WriteSetting("use_asynchronous_gpu_emulation", Settings::values.use_asynchronous_gpu_emulation,
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 51bd1f121..a5218b051 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -12,7 +12,7 @@
#include "yuzu/hotkeys.h"
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
- : QDialog(parent), registry(registry), ui(new Ui::ConfigureDialog) {
+ : QDialog(parent), ui(new Ui::ConfigureDialog), registry(registry) {
ui->setupUi(this);
ui->hotkeysTab->Populate(registry);
this->setConfiguration();
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 0a9883d37..c299c0b5b 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -73,6 +73,7 @@ void ConfigureGraphics::setConfiguration() {
static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor)));
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
ui->frame_limit->setValue(Settings::values.frame_limit);
+ ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile);
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation);
ui->use_asynchronous_gpu_emulation->setEnabled(!Core::System::GetInstance().IsPoweredOn());
@@ -88,6 +89,7 @@ void ConfigureGraphics::applyConfiguration() {
ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex()));
Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked();
Settings::values.frame_limit = ui->frame_limit->value();
+ Settings::values.use_compatibility_profile = ui->use_compatibility_profile->isChecked();
Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked();
Settings::values.use_accurate_gpu_emulation = ui->use_accurate_gpu_emulation->isChecked();
Settings::values.use_asynchronous_gpu_emulation =
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 15ab18ecd..0f6f6c003 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -50,6 +50,13 @@
</layout>
</item>
<item>
+ <widget class="QCheckBox" name="use_compatibility_profile">
+ <property name="text">
+ <string>Use OpenGL compatibility profile</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QCheckBox" name="use_disk_shader_cache">
<property name="text">
<string>Use disk shader cache</string>
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index bfb562535..a7a8752e5 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -66,20 +66,21 @@ void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
}
void ConfigureHotkeys::Configure(QModelIndex index) {
- if (index.parent() == QModelIndex())
+ if (!index.parent().isValid()) {
return;
+ }
index = index.sibling(index.row(), 1);
- auto* model = ui->hotkey_list->model();
- auto previous_key = model->data(index);
-
- auto* hotkey_dialog = new SequenceDialog;
- int return_code = hotkey_dialog->exec();
+ auto* const model = ui->hotkey_list->model();
+ const auto previous_key = model->data(index);
- auto key_sequence = hotkey_dialog->GetSequence();
+ SequenceDialog hotkey_dialog{this};
- if (return_code == QDialog::Rejected || key_sequence.isEmpty())
+ const int return_code = hotkey_dialog.exec();
+ const auto key_sequence = hotkey_dialog.GetSequence();
+ if (return_code == QDialog::Rejected || key_sequence.isEmpty()) {
return;
+ }
if (IsUsedKey(key_sequence) && key_sequence != QKeySequence(previous_key.toString())) {
QMessageBox::critical(this, tr("Error in inputted key"),
@@ -90,7 +91,7 @@ void ConfigureHotkeys::Configure(QModelIndex index) {
}
}
-bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) {
+bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const {
return GetUsedKeyList().contains(key_sequence);
}
diff --git a/src/yuzu/configuration/configure_hotkeys.h b/src/yuzu/configuration/configure_hotkeys.h
index cd203aad6..73fb8a175 100644
--- a/src/yuzu/configuration/configure_hotkeys.h
+++ b/src/yuzu/configuration/configure_hotkeys.h
@@ -6,7 +6,6 @@
#include <memory>
#include <QWidget>
-#include "core/settings.h"
namespace Ui {
class ConfigureHotkeys;
@@ -39,7 +38,7 @@ signals:
private:
void Configure(QModelIndex index);
- bool IsUsedKey(QKeySequence key_sequence);
+ bool IsUsedKey(QKeySequence key_sequence) const;
QList<QKeySequence> GetUsedKeyList() const;
std::unique_ptr<Ui::ConfigureHotkeys> ui;
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 593bb681f..85b095688 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -227,8 +227,7 @@ QString WaitTreeThread::GetText() const {
case Kernel::ThreadStatus::WaitIPC:
status = tr("waiting for IPC reply");
break;
- case Kernel::ThreadStatus::WaitSynchAll:
- case Kernel::ThreadStatus::WaitSynchAny:
+ case Kernel::ThreadStatus::WaitSynch:
status = tr("waiting for objects");
break;
case Kernel::ThreadStatus::WaitMutex:
@@ -269,8 +268,7 @@ QColor WaitTreeThread::GetColor() const {
return QColor(Qt::GlobalColor::darkRed);
case Kernel::ThreadStatus::WaitSleep:
return QColor(Qt::GlobalColor::darkYellow);
- case Kernel::ThreadStatus::WaitSynchAll:
- case Kernel::ThreadStatus::WaitSynchAny:
+ case Kernel::ThreadStatus::WaitSynch:
case Kernel::ThreadStatus::WaitMutex:
case Kernel::ThreadStatus::WaitCondVar:
case Kernel::ThreadStatus::WaitArb:
@@ -325,10 +323,9 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex")));
}
- if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynchAny ||
- thread.GetStatus() == Kernel::ThreadStatus::WaitSynchAll) {
+ if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) {
list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetWaitObjects(),
- thread.IsSleepingOnWaitAll()));
+ thread.IsSleepingOnWait()));
}
list.push_back(std::make_unique<WaitTreeCallstack>(thread));
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 3db0e90da..2cf5c58a0 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -95,7 +95,7 @@ public:
if (row2.isEmpty())
return row1;
- return row1 + "\n " + row2;
+ return QString(row1 + "\n " + row2);
}
return GameListItem::data(role);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index bdee44b04..e33e3aaaf 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -8,6 +8,7 @@
#include <thread>
// VFS includes must be before glad as they will conflict with Windows file api, which uses defines.
+#include "applets/error.h"
#include "applets/profile_select.h"
#include "applets/software_keyboard.h"
#include "applets/web_browser.h"
@@ -15,6 +16,7 @@
#include "configuration/configure_per_general.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_real.h"
+#include "core/frontend/applets/general_frontend.h"
#include "core/frontend/scope_acquire_window_context.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/applets/applets.h"
@@ -795,9 +797,13 @@ bool GMainWindow::LoadROM(const QString& filename) {
system.SetGPUDebugContext(debug_context);
- system.SetProfileSelector(std::make_unique<QtProfileSelector>(*this));
- system.SetSoftwareKeyboard(std::make_unique<QtSoftwareKeyboard>(*this));
- system.SetWebBrowser(std::make_unique<QtWebBrowser>(*this));
+ system.SetAppletFrontendSet({
+ std::make_unique<QtErrorDisplay>(*this),
+ nullptr,
+ std::make_unique<QtProfileSelector>(*this),
+ std::make_unique<QtSoftwareKeyboard>(*this),
+ std::make_unique<QtWebBrowser>(*this),
+ });
const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
@@ -1583,6 +1589,11 @@ void GMainWindow::OnLoadComplete() {
loading_screen->OnLoadComplete();
}
+void GMainWindow::ErrorDisplayDisplayError(QString body) {
+ QMessageBox::critical(this, tr("Error Display"), body);
+ emit ErrorDisplayFinished();
+}
+
void GMainWindow::OnMenuReportCompatibility() {
if (!Settings::values.yuzu_token.empty() && !Settings::values.yuzu_username.empty()) {
CompatDB compatdb{this};
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index ce5045819..fb2a193cb 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -102,6 +102,8 @@ signals:
// Signal that tells widgets to update icons to use the current theme
void UpdateThemedIcons();
+ void ErrorDisplayFinished();
+
void ProfileSelectorFinishedSelection(std::optional<Service::Account::UUID> uuid);
void SoftwareKeyboardFinishedText(std::optional<std::u16string> text);
void SoftwareKeyboardFinishedCheckDialog();
@@ -111,6 +113,7 @@ signals:
public slots:
void OnLoadComplete();
+ void ErrorDisplayDisplayError(QString body);
void ProfileSelectorSelectProfile();
void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters);
void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);