mirror of
https://github.com/yuzu-emu/yuzu-android
synced 2025-08-09 02:42:33 -07:00
Fix merge conflicts?
This commit is contained in:
@@ -44,49 +44,65 @@ EmuThread::EmuThread() = default;
|
||||
EmuThread::~EmuThread() = default;
|
||||
|
||||
void EmuThread::run() {
|
||||
MicroProfileOnThreadCreate("EmuThread");
|
||||
std::string name = "yuzu:EmuControlThread";
|
||||
MicroProfileOnThreadCreate(name.c_str());
|
||||
Common::SetCurrentThreadName(name.c_str());
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
|
||||
system.RegisterHostThread();
|
||||
|
||||
auto& gpu = system.GPU();
|
||||
|
||||
// Main process has been loaded. Make the context current to this thread and begin GPU and CPU
|
||||
// execution.
|
||||
Core::System::GetInstance().GPU().Start();
|
||||
gpu.Start();
|
||||
|
||||
gpu.ObtainContext();
|
||||
|
||||
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||
|
||||
Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources(
|
||||
system.Renderer().Rasterizer().LoadDiskResources(
|
||||
stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
|
||||
emit LoadProgress(stage, value, total);
|
||||
});
|
||||
|
||||
emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
||||
|
||||
gpu.ReleaseContext();
|
||||
|
||||
// Holds whether the cpu was running during the last iteration,
|
||||
// so that the DebugModeLeft signal can be emitted before the
|
||||
// next execution step
|
||||
bool was_active = false;
|
||||
while (!stop_run) {
|
||||
if (running) {
|
||||
if (!was_active)
|
||||
if (was_active) {
|
||||
emit DebugModeLeft();
|
||||
|
||||
Core::System::ResultStatus result = Core::System::GetInstance().RunLoop();
|
||||
if (result != Core::System::ResultStatus::Success) {
|
||||
this->SetRunning(false);
|
||||
emit ErrorThrown(result, Core::System::GetInstance().GetStatusDetails());
|
||||
}
|
||||
|
||||
was_active = running || exec_step;
|
||||
if (!was_active && !stop_run)
|
||||
running_guard = true;
|
||||
Core::System::ResultStatus result = system.Run();
|
||||
if (result != Core::System::ResultStatus::Success) {
|
||||
running_guard = false;
|
||||
this->SetRunning(false);
|
||||
emit ErrorThrown(result, system.GetStatusDetails());
|
||||
}
|
||||
running_wait.Wait();
|
||||
result = system.Pause();
|
||||
if (result != Core::System::ResultStatus::Success) {
|
||||
running_guard = false;
|
||||
this->SetRunning(false);
|
||||
emit ErrorThrown(result, system.GetStatusDetails());
|
||||
}
|
||||
running_guard = false;
|
||||
|
||||
if (!stop_run) {
|
||||
was_active = true;
|
||||
emit DebugModeEntered();
|
||||
}
|
||||
} else if (exec_step) {
|
||||
if (!was_active)
|
||||
emit DebugModeLeft();
|
||||
|
||||
exec_step = false;
|
||||
Core::System::GetInstance().SingleStep();
|
||||
emit DebugModeEntered();
|
||||
yieldCurrentThread();
|
||||
|
||||
was_active = false;
|
||||
UNIMPLEMENTED();
|
||||
} else {
|
||||
std::unique_lock lock{running_mutex};
|
||||
running_cv.wait(lock, [this] { return IsRunning() || exec_step || stop_run; });
|
||||
@@ -94,7 +110,7 @@ void EmuThread::run() {
|
||||
}
|
||||
|
||||
// Shutdown the core emulation
|
||||
Core::System::GetInstance().Shutdown();
|
||||
system.Shutdown();
|
||||
|
||||
#if MICROPROFILE_ENABLED
|
||||
MicroProfileOnThreadExit();
|
||||
@@ -360,7 +376,7 @@ QByteArray GRenderWindow::saveGeometry() {
|
||||
}
|
||||
|
||||
qreal GRenderWindow::windowPixelRatio() const {
|
||||
return devicePixelRatio();
|
||||
return devicePixelRatioF();
|
||||
}
|
||||
|
||||
std::pair<u32, u32> GRenderWindow::ScaleTouch(const QPointF& pos) const {
|
||||
|
@@ -59,6 +59,12 @@ public:
|
||||
this->running = running;
|
||||
lock.unlock();
|
||||
running_cv.notify_all();
|
||||
if (!running) {
|
||||
running_wait.Set();
|
||||
/// Wait until effectively paused
|
||||
while (running_guard)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,6 +90,8 @@ private:
|
||||
std::atomic_bool stop_run{false};
|
||||
std::mutex running_mutex;
|
||||
std::condition_variable running_cv;
|
||||
Common::Event running_wait{};
|
||||
std::atomic_bool running_guard{false};
|
||||
|
||||
signals:
|
||||
/**
|
||||
|
@@ -211,7 +211,7 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
|
||||
// This must be in alphabetical order according to action name as it must have the same order as
|
||||
// UISetting::values.shortcuts, which is alphabetically ordered.
|
||||
// clang-format off
|
||||
const std::array<UISettings::Shortcut, 15> Config::default_hotkeys{{
|
||||
const std::array<UISettings::Shortcut, 16> Config::default_hotkeys{{
|
||||
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
|
||||
@@ -222,6 +222,7 @@ const std::array<UISettings::Shortcut, 15> Config::default_hotkeys{{
|
||||
{QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Mute Audio"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
|
||||
|
@@ -27,7 +27,7 @@ public:
|
||||
default_mouse_buttons;
|
||||
static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys;
|
||||
static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods;
|
||||
static const std::array<UISettings::Shortcut, 15> default_hotkeys;
|
||||
static const std::array<UISettings::Shortcut, 16> default_hotkeys;
|
||||
|
||||
private:
|
||||
void ReadValues();
|
||||
|
@@ -23,6 +23,11 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||
|
||||
void ConfigureGeneral::SetConfiguration() {
|
||||
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
|
||||
|
||||
ui->use_multi_core->setEnabled(runtime_lock);
|
||||
ui->use_multi_core->setChecked(Settings::values.use_multi_core);
|
||||
|
||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
|
||||
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot);
|
||||
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background);
|
||||
@@ -41,6 +46,7 @@ void ConfigureGeneral::ApplyConfiguration() {
|
||||
|
||||
Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked();
|
||||
Settings::values.frame_limit = ui->frame_limit->value();
|
||||
Settings::values.use_multi_core = ui->use_multi_core->isChecked();
|
||||
}
|
||||
|
||||
void ConfigureGeneral::changeEvent(QEvent* event) {
|
||||
|
@@ -51,6 +51,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_multi_core">
|
||||
<property name="text">
|
||||
<string>Multicore CPU Emulation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_check_exit">
|
||||
<property name="text">
|
||||
|
@@ -2,10 +2,13 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "yuzu/debugger/wait_tree.h"
|
||||
#include "yuzu/util/util.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/mutex.h"
|
||||
@@ -59,8 +62,10 @@ std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList()
|
||||
std::size_t row = 0;
|
||||
auto add_threads = [&](const std::vector<std::shared_ptr<Kernel::Thread>>& threads) {
|
||||
for (std::size_t i = 0; i < threads.size(); ++i) {
|
||||
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[i]));
|
||||
item_list.back()->row = row;
|
||||
if (!threads[i]->IsHLEThread()) {
|
||||
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[i]));
|
||||
item_list.back()->row = row;
|
||||
}
|
||||
++row;
|
||||
}
|
||||
};
|
||||
@@ -114,20 +119,21 @@ QString WaitTreeCallstack::GetText() const {
|
||||
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() const {
|
||||
std::vector<std::unique_ptr<WaitTreeItem>> list;
|
||||
|
||||
constexpr std::size_t BaseRegister = 29;
|
||||
auto& memory = Core::System::GetInstance().Memory();
|
||||
u64 base_pointer = thread.GetContext64().cpu_registers[BaseRegister];
|
||||
if (thread.IsHLEThread()) {
|
||||
return list;
|
||||
}
|
||||
|
||||
while (base_pointer != 0) {
|
||||
const u64 lr = memory.Read64(base_pointer + sizeof(u64));
|
||||
if (lr == 0) {
|
||||
break;
|
||||
}
|
||||
if (thread.GetOwnerProcess() == nullptr || !thread.GetOwnerProcess()->Is64BitProcess()) {
|
||||
return list;
|
||||
}
|
||||
|
||||
list.push_back(std::make_unique<WaitTreeText>(
|
||||
tr("0x%1").arg(lr - sizeof(u32), 16, 16, QLatin1Char{'0'})));
|
||||
auto backtrace = Core::ARM_Interface::GetBacktraceFromContext(Core::System::GetInstance(),
|
||||
thread.GetContext64());
|
||||
|
||||
base_pointer = memory.Read64(base_pointer);
|
||||
for (auto& entry : backtrace) {
|
||||
std::string s = fmt::format("{:20}{:016X} {:016X} {:016X} {}", entry.module, entry.address,
|
||||
entry.original_address, entry.offset, entry.name);
|
||||
list.push_back(std::make_unique<WaitTreeText>(QString::fromStdString(s)));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -206,7 +212,15 @@ QString WaitTreeThread::GetText() const {
|
||||
status = tr("running");
|
||||
break;
|
||||
case Kernel::ThreadStatus::Ready:
|
||||
status = tr("ready");
|
||||
if (!thread.IsPaused()) {
|
||||
if (thread.WasRunning()) {
|
||||
status = tr("running");
|
||||
} else {
|
||||
status = tr("ready");
|
||||
}
|
||||
} else {
|
||||
status = tr("paused");
|
||||
}
|
||||
break;
|
||||
case Kernel::ThreadStatus::Paused:
|
||||
status = tr("paused");
|
||||
@@ -254,7 +268,15 @@ QColor WaitTreeThread::GetColor() const {
|
||||
case Kernel::ThreadStatus::Running:
|
||||
return QColor(Qt::GlobalColor::darkGreen);
|
||||
case Kernel::ThreadStatus::Ready:
|
||||
return QColor(Qt::GlobalColor::darkBlue);
|
||||
if (!thread.IsPaused()) {
|
||||
if (thread.WasRunning()) {
|
||||
return QColor(Qt::GlobalColor::darkGreen);
|
||||
} else {
|
||||
return QColor(Qt::GlobalColor::darkBlue);
|
||||
}
|
||||
} else {
|
||||
return QColor(Qt::GlobalColor::lightGray);
|
||||
}
|
||||
case Kernel::ThreadStatus::Paused:
|
||||
return QColor(Qt::GlobalColor::lightGray);
|
||||
case Kernel::ThreadStatus::WaitHLEEvent:
|
||||
@@ -319,7 +341,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
|
||||
|
||||
if (thread.GetStatus() == Kernel::ThreadStatus::WaitSynch) {
|
||||
list.push_back(std::make_unique<WaitTreeObjectList>(thread.GetSynchronizationObjects(),
|
||||
thread.IsSleepingOnWait()));
|
||||
thread.IsWaitingSync()));
|
||||
}
|
||||
|
||||
list.push_back(std::make_unique<WaitTreeCallstack>(thread));
|
||||
|
@@ -56,6 +56,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
||||
#include <QShortcut>
|
||||
#include <QStatusBar>
|
||||
#include <QSysInfo>
|
||||
#include <QUrl>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include <fmt/format.h>
|
||||
@@ -217,7 +218,20 @@ GMainWindow::GMainWindow()
|
||||
LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", yuzu_build_version, Common::g_scm_branch,
|
||||
Common::g_scm_desc);
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
LOG_INFO(Frontend, "Host CPU: {}", Common::GetCPUCaps().cpu_string);
|
||||
const auto& caps = Common::GetCPUCaps();
|
||||
std::string cpu_string = caps.cpu_string;
|
||||
if (caps.avx || caps.avx2 || caps.avx512) {
|
||||
cpu_string += " | AVX";
|
||||
if (caps.avx512) {
|
||||
cpu_string += "512";
|
||||
} else if (caps.avx2) {
|
||||
cpu_string += '2';
|
||||
}
|
||||
if (caps.fma || caps.fma4) {
|
||||
cpu_string += " | FMA";
|
||||
}
|
||||
}
|
||||
LOG_INFO(Frontend, "Host CPU: {}", cpu_string);
|
||||
#endif
|
||||
LOG_INFO(Frontend, "Host OS: {}", QSysInfo::prettyProductName().toStdString());
|
||||
LOG_INFO(Frontend, "Host RAM: {:.2f} GB",
|
||||
@@ -520,14 +534,36 @@ void GMainWindow::InitializeWidgets() {
|
||||
if (emulation_running) {
|
||||
return;
|
||||
}
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
!Settings::values.use_asynchronous_gpu_emulation;
|
||||
bool is_async =
|
||||
!Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
|
||||
Settings::values.use_asynchronous_gpu_emulation = is_async;
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
Settings::Apply();
|
||||
});
|
||||
async_status_button->setText(tr("ASYNC"));
|
||||
async_status_button->setCheckable(true);
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
|
||||
// Setup Multicore button
|
||||
multicore_status_button = new QPushButton();
|
||||
multicore_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
|
||||
multicore_status_button->setFocusPolicy(Qt::NoFocus);
|
||||
connect(multicore_status_button, &QPushButton::clicked, [&] {
|
||||
if (emulation_running) {
|
||||
return;
|
||||
}
|
||||
Settings::values.use_multi_core = !Settings::values.use_multi_core;
|
||||
bool is_async =
|
||||
Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
|
||||
Settings::values.use_asynchronous_gpu_emulation = is_async;
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core);
|
||||
Settings::Apply();
|
||||
});
|
||||
multicore_status_button->setText(tr("MULTICORE"));
|
||||
multicore_status_button->setCheckable(true);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core);
|
||||
statusBar()->insertPermanentWidget(0, multicore_status_button);
|
||||
statusBar()->insertPermanentWidget(0, async_status_button);
|
||||
|
||||
// Setup Renderer API button
|
||||
@@ -653,6 +689,11 @@ void GMainWindow::InitializeHotkeys() {
|
||||
ui.action_Capture_Screenshot->setShortcutContext(
|
||||
hotkey_registry.GetShortcutContext(main_window, capture_screenshot));
|
||||
|
||||
ui.action_Fullscreen->setShortcut(
|
||||
hotkey_registry.GetHotkey(main_window, fullscreen, this)->key());
|
||||
ui.action_Fullscreen->setShortcutContext(
|
||||
hotkey_registry.GetShortcutContext(main_window, fullscreen));
|
||||
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this),
|
||||
&QShortcut::activated, this, &GMainWindow::OnMenuLoadFile);
|
||||
connect(
|
||||
@@ -723,6 +764,9 @@ void GMainWindow::InitializeHotkeys() {
|
||||
Settings::values.use_docked_mode);
|
||||
dock_status_button->setChecked(Settings::values.use_docked_mode);
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
|
||||
&QShortcut::activated, this,
|
||||
[] { Settings::values.audio_muted = !Settings::values.audio_muted; });
|
||||
}
|
||||
|
||||
void GMainWindow::SetDefaultUIGeometry() {
|
||||
@@ -823,6 +867,10 @@ void GMainWindow::ConnectMenuEvents() {
|
||||
connect(ui.action_Stop, &QAction::triggered, this, &GMainWindow::OnStopGame);
|
||||
connect(ui.action_Report_Compatibility, &QAction::triggered, this,
|
||||
&GMainWindow::OnMenuReportCompatibility);
|
||||
connect(ui.action_Open_Mods_Page, &QAction::triggered, this, &GMainWindow::OnOpenModsPage);
|
||||
connect(ui.action_Open_Quickstart_Guide, &QAction::triggered, this,
|
||||
&GMainWindow::OnOpenQuickstartGuide);
|
||||
connect(ui.action_Open_FAQ, &QAction::triggered, this, &GMainWindow::OnOpenFAQ);
|
||||
connect(ui.action_Restart, &QAction::triggered, this, [this] { BootGame(QString(game_path)); });
|
||||
connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
|
||||
|
||||
@@ -836,10 +884,6 @@ void GMainWindow::ConnectMenuEvents() {
|
||||
connect(ui.action_Reset_Window_Size, &QAction::triggered, this, &GMainWindow::ResetWindowSize);
|
||||
|
||||
// Fullscreen
|
||||
ui.action_Fullscreen->setShortcut(
|
||||
hotkey_registry
|
||||
.GetHotkey(QStringLiteral("Main Window"), QStringLiteral("Fullscreen"), this)
|
||||
->key());
|
||||
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
|
||||
|
||||
// Movie
|
||||
@@ -907,6 +951,8 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
nullptr, // E-Commerce
|
||||
});
|
||||
|
||||
system.RegisterHostThread();
|
||||
|
||||
const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
|
||||
|
||||
const auto drd_callout =
|
||||
@@ -1023,6 +1069,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
}
|
||||
status_bar_update_timer.start(2000);
|
||||
async_status_button->setDisabled(true);
|
||||
multicore_status_button->setDisabled(true);
|
||||
renderer_status_button->setDisabled(true);
|
||||
|
||||
if (UISettings::values.hide_mouse) {
|
||||
@@ -1034,17 +1081,19 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||
const u64 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
|
||||
|
||||
std::string title_name;
|
||||
std::string title_version;
|
||||
const auto res = Core::System::GetInstance().GetGameName(title_name);
|
||||
if (res != Loader::ResultStatus::Success) {
|
||||
const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata();
|
||||
if (metadata.first != nullptr)
|
||||
title_name = metadata.first->GetApplicationName();
|
||||
|
||||
if (title_name.empty())
|
||||
title_name = FileUtil::GetFilename(filename.toStdString());
|
||||
const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata();
|
||||
if (metadata.first != nullptr) {
|
||||
title_version = metadata.first->GetVersionString();
|
||||
title_name = metadata.first->GetApplicationName();
|
||||
}
|
||||
LOG_INFO(Frontend, "Booting game: {:016X} | {}", title_id, title_name);
|
||||
UpdateWindowTitle(QString::fromStdString(title_name));
|
||||
if (res != Loader::ResultStatus::Success || title_name.empty()) {
|
||||
title_name = FileUtil::GetFilename(filename.toStdString());
|
||||
}
|
||||
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
|
||||
UpdateWindowTitle(title_name, title_version);
|
||||
|
||||
loading_screen->Prepare(Core::System::GetInstance().GetAppLoader());
|
||||
loading_screen->show();
|
||||
@@ -1110,6 +1159,7 @@ void GMainWindow::ShutdownGame() {
|
||||
game_fps_label->setVisible(false);
|
||||
emu_frametime_label->setVisible(false);
|
||||
async_status_button->setEnabled(true);
|
||||
multicore_status_button->setEnabled(true);
|
||||
#ifdef HAS_VULKAN
|
||||
renderer_status_button->setEnabled(true);
|
||||
#endif
|
||||
@@ -1794,6 +1844,26 @@ void GMainWindow::OnMenuReportCompatibility() {
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::OpenURL(const QUrl& url) {
|
||||
const bool open = QDesktopServices::openUrl(url);
|
||||
if (!open) {
|
||||
QMessageBox::warning(this, tr("Error opening URL"),
|
||||
tr("Unable to open the URL \"%1\".").arg(url.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenModsPage() {
|
||||
OpenURL(QUrl(QStringLiteral("https://github.com/yuzu-emu/yuzu/wiki/Switch-Mods")));
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenQuickstartGuide() {
|
||||
OpenURL(QUrl(QStringLiteral("https://yuzu-emu.org/help/quickstart/")));
|
||||
}
|
||||
|
||||
void GMainWindow::OnOpenFAQ() {
|
||||
OpenURL(QUrl(QStringLiteral("https://yuzu-emu.org/wiki/faq/")));
|
||||
}
|
||||
|
||||
void GMainWindow::ToggleFullscreen() {
|
||||
if (!emulation_running) {
|
||||
return;
|
||||
@@ -1905,7 +1975,11 @@ void GMainWindow::OnConfigure() {
|
||||
}
|
||||
|
||||
dock_status_button->setChecked(Settings::values.use_docked_mode);
|
||||
multicore_status_button->setChecked(Settings::values.use_multi_core);
|
||||
Settings::values.use_asynchronous_gpu_emulation =
|
||||
Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core;
|
||||
async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation);
|
||||
|
||||
#ifdef HAS_VULKAN
|
||||
renderer_status_button->setChecked(Settings::values.renderer_backend ==
|
||||
Settings::RendererBackend::Vulkan);
|
||||
@@ -1992,7 +2066,8 @@ void GMainWindow::OnCaptureScreenshot() {
|
||||
OnStartGame();
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateWindowTitle(const QString& title_name) {
|
||||
void GMainWindow::UpdateWindowTitle(const std::string& title_name,
|
||||
const std::string& title_version) {
|
||||
const auto full_name = std::string(Common::g_build_fullname);
|
||||
const auto branch_name = std::string(Common::g_scm_branch);
|
||||
const auto description = std::string(Common::g_scm_desc);
|
||||
@@ -2001,7 +2076,7 @@ void GMainWindow::UpdateWindowTitle(const QString& title_name) {
|
||||
const auto date =
|
||||
QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd")).toStdString();
|
||||
|
||||
if (title_name.isEmpty()) {
|
||||
if (title_name.empty()) {
|
||||
const auto fmt = std::string(Common::g_title_bar_format_idle);
|
||||
setWindowTitle(QString::fromStdString(fmt::format(fmt.empty() ? "yuzu {0}| {1}-{2}" : fmt,
|
||||
full_name, branch_name, description,
|
||||
@@ -2009,8 +2084,8 @@ void GMainWindow::UpdateWindowTitle(const QString& title_name) {
|
||||
} else {
|
||||
const auto fmt = std::string(Common::g_title_bar_format_running);
|
||||
setWindowTitle(QString::fromStdString(
|
||||
fmt::format(fmt.empty() ? "yuzu {0}| {3} | {1}-{2}" : fmt, full_name, branch_name,
|
||||
description, title_name.toStdString(), date, build_id)));
|
||||
fmt::format(fmt.empty() ? "yuzu {0}| {3} | {6} | {1}-{2}" : fmt, full_name, branch_name,
|
||||
description, title_name, date, build_id, title_version)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2032,7 +2107,7 @@ void GMainWindow::UpdateStatusBar() {
|
||||
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
||||
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
||||
|
||||
emu_speed_label->setVisible(true);
|
||||
emu_speed_label->setVisible(!Settings::values.use_multi_core);
|
||||
game_fps_label->setVisible(true);
|
||||
emu_frametime_label->setVisible(true);
|
||||
}
|
||||
@@ -2151,7 +2226,7 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||
"title.keys_autogenerated");
|
||||
}
|
||||
|
||||
Core::Crypto::KeyManager keys{};
|
||||
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
|
||||
if (keys.BaseDeriveNecessary()) {
|
||||
Core::Crypto::PartitionDataManager pdm{vfs->OpenDirectory(
|
||||
FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), FileSys::Mode::Read)};
|
||||
|
@@ -181,6 +181,9 @@ private slots:
|
||||
void OnPauseGame();
|
||||
void OnStopGame();
|
||||
void OnMenuReportCompatibility();
|
||||
void OnOpenModsPage();
|
||||
void OnOpenQuickstartGuide();
|
||||
void OnOpenFAQ();
|
||||
/// Called whenever a user selects a game in the game list widget.
|
||||
void OnGameListLoadFile(QString game_path);
|
||||
void OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path);
|
||||
@@ -215,10 +218,12 @@ private slots:
|
||||
|
||||
private:
|
||||
std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
|
||||
void UpdateWindowTitle(const QString& title_name = {});
|
||||
void UpdateWindowTitle(const std::string& title_name = {},
|
||||
const std::string& title_version = {});
|
||||
void UpdateStatusBar();
|
||||
void HideMouseCursor();
|
||||
void ShowMouseCursor();
|
||||
void OpenURL(const QUrl& url);
|
||||
|
||||
Ui::MainWindow ui;
|
||||
|
||||
@@ -234,6 +239,7 @@ private:
|
||||
QLabel* game_fps_label = nullptr;
|
||||
QLabel* emu_frametime_label = nullptr;
|
||||
QPushButton* async_status_button = nullptr;
|
||||
QPushButton* multicore_status_button = nullptr;
|
||||
QPushButton* renderer_status_button = nullptr;
|
||||
QPushButton* dock_status_button = nullptr;
|
||||
QTimer status_bar_update_timer;
|
||||
|
@@ -113,6 +113,9 @@
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<addaction name="action_Report_Compatibility"/>
|
||||
<addaction name="action_Open_Mods_Page"/>
|
||||
<addaction name="action_Open_Quickstart_Guide"/>
|
||||
<addaction name="action_Open_FAQ"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_About"/>
|
||||
</widget>
|
||||
@@ -256,6 +259,21 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_Mods_Page">
|
||||
<property name="text">
|
||||
<string>Open Mods Page</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_Quickstart_Guide">
|
||||
<property name="text">
|
||||
<string>Open Quickstart Guide</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_FAQ">
|
||||
<property name="text">
|
||||
<string>FAQ</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_yuzu_Folder">
|
||||
<property name="text">
|
||||
<string>Open yuzu Folder</string>
|
||||
|
@@ -16,4 +16,4 @@ IDI_ICON1 ICON "../../dist/yuzu.ico"
|
||||
// RT_MANIFEST
|
||||
//
|
||||
|
||||
1 RT_MANIFEST "../../dist/yuzu.manifest"
|
||||
0 RT_MANIFEST "../../dist/yuzu.manifest"
|
||||
|
Reference in New Issue
Block a user