diff options
Diffstat (limited to 'src/yuzu')
-rw-r--r-- | src/yuzu/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/yuzu/applets/error.cpp | 59 | ||||
-rw-r--r-- | src/yuzu/applets/error.h | 33 | ||||
-rw-r--r-- | src/yuzu/bootmanager.cpp | 13 | ||||
-rw-r--r-- | src/yuzu/bootmanager.h | 1 | ||||
-rw-r--r-- | src/yuzu/configuration/config.cpp | 3 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_dialog.cpp | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics.cpp | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics.ui | 7 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_hotkeys.cpp | 19 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_hotkeys.h | 3 | ||||
-rw-r--r-- | src/yuzu/debugger/wait_tree.cpp | 11 | ||||
-rw-r--r-- | src/yuzu/game_list_p.h | 2 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 17 | ||||
-rw-r--r-- | src/yuzu/main.h | 3 |
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); |