summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/bootmanager.cpp6
-rw-r--r--src/yuzu/bootmanager.h7
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.ui46
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp7
-rw-r--r--src/yuzu/configuration/configure_per_game_addons.cpp6
-rw-r--r--src/yuzu/game_list_worker.cpp36
-rw-r--r--src/yuzu/main.cpp52
-rw-r--r--src/yuzu/main.h8
10 files changed, 127 insertions, 45 deletions
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index d62b0efc2..f0338cf7a 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -302,6 +302,12 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
this->setMouseTracking(true);
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
+ connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram,
+ Qt::QueuedConnection);
+}
+
+void GRenderWindow::ExecuteProgram(std::size_t program_index) {
+ emit ExecuteProgramSignal(program_index);
}
GRenderWindow::~GRenderWindow() {
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index ca35cf831..503b4f89e 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -166,6 +166,12 @@ public:
std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;
+ /**
+ * Instructs the window to re-launch the application using the specified program_index.
+ * @param program_index Specifies the index within the application of the program to launch.
+ */
+ void ExecuteProgram(std::size_t program_index);
+
public slots:
void OnEmulationStarting(EmuThread* emu_thread);
void OnEmulationStopping();
@@ -175,6 +181,7 @@ signals:
/// Emitted when the window is closed
void Closed();
void FirstFrameDisplayed();
+ void ExecuteProgramSignal(std::size_t program_index);
private:
void TouchBeginEvent(const QTouchEvent* event);
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 6fa842cd5..3c423a271 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -649,6 +649,8 @@ void Config::ReadDebuggingValues() {
Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool();
Settings::values.disable_macro_jit =
ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
+ Settings::values.extended_logging =
+ ReadSetting(QStringLiteral("extended_logging"), false).toBool();
qt_config->endGroup();
}
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 2bfe2c306..027099ab7 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -41,6 +41,7 @@ void ConfigureDebug::SetConfiguration() {
ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit);
+ ui->extended_logging->setChecked(Settings::values.extended_logging);
}
void ConfigureDebug::ApplyConfiguration() {
@@ -53,6 +54,7 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.quest_flag = ui->quest_flag->isChecked();
Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
+ Settings::values.extended_logging = ui->extended_logging->isChecked();
Debugger::ToggleConsole();
Log::Filter filter;
filter.ParseFilterString(Settings::values.log_filter);
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 9d6feb9f7..6f94fe304 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -90,7 +90,7 @@
<item>
<widget class="QCheckBox" name="toggle_console">
<property name="text">
- <string>Show Log Console (Windows Only)</string>
+ <string>Show Log in Console</string>
</property>
</widget>
</item>
@@ -103,6 +103,34 @@
</item>
</layout>
</item>
+ <item>
+ <widget class="QCheckBox" name="extended_logging">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip">
+ <string>When checked, the max size of the log increases from 100 MB to 1 GB</string>
+ </property>
+ <property name="text">
+ <string>Enable Extended Logging</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="font">
+ <font>
+ <italic>true</italic>
+ </font>
+ </property>
+ <property name="text">
+ <string>This will be reset automatically when yuzu closes.</string>
+ </property>
+ <property name="indent">
+ <number>20</number>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -115,7 +143,7 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
- <widget class="QLabel" name="label_3">
+ <widget class="QLabel" name="label_4">
<property name="text">
<string>Arguments String</string>
</property>
@@ -140,8 +168,8 @@
<property name="enabled">
<bool>true</bool>
</property>
- <property name="whatsThis">
- <string>When checked, the graphics API enters in a slower debugging mode</string>
+ <property name="toolTip">
+ <string>When checked, the graphics API enters a slower debugging mode</string>
</property>
<property name="text">
<string>Enable Graphics Debugging</string>
@@ -153,8 +181,8 @@
<property name="enabled">
<bool>true</bool>
</property>
- <property name="whatsThis">
- <string>When checked, it disables the macro Just In Time compiler. Enabled this makes games run slower</string>
+ <property name="toolTip">
+ <string>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</string>
</property>
<property name="text">
<string>Disable Macro JIT</string>
@@ -169,7 +197,7 @@
<property name="title">
<string>Dump</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_6">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="reporting_services">
<property name="text">
@@ -178,7 +206,7 @@
</widget>
</item>
<item>
- <widget class="QLabel" name="label">
+ <widget class="QLabel" name="label_5">
<property name="font">
<font>
<italic>true</italic>
@@ -200,7 +228,7 @@
<property name="title">
<string>Advanced</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_7">
+ <layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QCheckBox" name="quest_flag">
<property name="text">
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 81464dd37..8eac3bd9d 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -16,6 +16,7 @@
#include "common/common_paths.h"
#include "common/file_util.h"
+#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/xts_archive.h"
@@ -89,9 +90,11 @@ void ConfigurePerGame::LoadConfiguration() {
ui->display_title_id->setText(
QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper());
- FileSys::PatchManager pm{title_id};
+ auto& system = Core::System::GetInstance();
+ const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
- const auto loader = Loader::GetLoader(file);
+ const auto loader = Loader::GetLoader(system, file);
if (control.first != nullptr) {
ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp
index 793fd8975..cdeeec01c 100644
--- a/src/yuzu/configuration/configure_per_game_addons.cpp
+++ b/src/yuzu/configuration/configure_per_game_addons.cpp
@@ -112,8 +112,10 @@ void ConfigurePerGameAddons::LoadConfiguration() {
return;
}
- FileSys::PatchManager pm{title_id};
- const auto loader = Loader::GetLoader(file);
+ auto& system = Core::System::GetInstance();
+ const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
+ const auto loader = Loader::GetLoader(system, file);
FileSys::VirtualFile update_raw;
loader->ReadUpdateRaw(update_raw);
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index e0ce45fd9..23643aea2 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -235,12 +235,11 @@ GameListWorker::~GameListWorker() = default;
void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
using namespace FileSys;
- const auto& cache =
- dynamic_cast<ContentProviderUnion&>(Core::System::GetInstance().GetContentProvider());
+ auto& system = Core::System::GetInstance();
+ const auto& cache = dynamic_cast<ContentProviderUnion&>(system.GetContentProvider());
- std::vector<std::pair<ContentProviderUnionSlot, ContentProviderEntry>> installed_games;
- installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application,
- ContentRecordType::Program);
+ auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application,
+ ContentRecordType::Program);
if (parent_dir->type() == static_cast<int>(GameListItemType::SdmcDir)) {
installed_games = cache.ListEntriesFilterOrigin(
@@ -254,23 +253,27 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
}
for (const auto& [slot, game] : installed_games) {
- if (slot == ContentProviderUnionSlot::FrontendManual)
+ if (slot == ContentProviderUnionSlot::FrontendManual) {
continue;
+ }
const auto file = cache.GetEntryUnparsed(game.title_id, game.type);
- std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file);
- if (!loader)
+ std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(system, file);
+ if (!loader) {
continue;
+ }
std::vector<u8> icon;
std::string name;
u64 program_id = 0;
loader->ReadProgramId(program_id);
- const PatchManager patch{program_id};
+ const PatchManager patch{program_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
const auto control = cache.GetEntry(game.title_id, ContentRecordType::Control);
- if (control != nullptr)
+ if (control != nullptr) {
GetMetadataFromControlNCA(patch, *control, icon, name);
+ }
emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id,
compatibility_list, patch),
@@ -280,9 +283,11 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path,
unsigned int recursion, GameListDir* parent_dir) {
- const auto callback = [this, target, recursion,
- parent_dir](u64* num_entries_out, const std::string& directory,
- const std::string& virtual_name) -> bool {
+ auto& system = Core::System::GetInstance();
+
+ const auto callback = [this, target, recursion, parent_dir,
+ &system](u64* num_entries_out, const std::string& directory,
+ const std::string& virtual_name) -> bool {
if (stop_processing) {
// Breaks the callback loop.
return false;
@@ -293,7 +298,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
if (!is_dir &&
(HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read);
- auto loader = Loader::GetLoader(file);
+ auto loader = Loader::GetLoader(system, file);
if (!loader) {
return true;
}
@@ -331,7 +336,8 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
std::string name = " ";
[[maybe_unused]] const auto res3 = loader->ReadTitle(name);
- const FileSys::PatchManager patch{program_id};
+ const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
compatibility_list, patch),
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 9dabd8889..805619ccf 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -978,7 +978,7 @@ void GMainWindow::AllowOSSleep() {
#endif
}
-bool GMainWindow::LoadROM(const QString& filename) {
+bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) {
// Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr)
ShutdownGame();
@@ -1003,7 +1003,8 @@ bool GMainWindow::LoadROM(const QString& filename) {
system.RegisterHostThread();
- const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
+ const Core::System::ResultStatus result{
+ system.Load(*render_window, filename.toStdString(), program_index)};
const auto drd_callout =
(UISettings::values.callout_flags & static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
@@ -1085,14 +1086,18 @@ void GMainWindow::SelectAndSetCurrentUser() {
Settings::values.current_user = dialog.GetIndex();
}
-void GMainWindow::BootGame(const QString& filename) {
+void GMainWindow::BootGame(const QString& filename, std::size_t program_index) {
LOG_INFO(Frontend, "yuzu starting...");
StoreRecentFile(filename); // Put the filename on top of the list
u64 title_id{0};
+ last_filename_booted = filename;
+
+ auto& system = Core::System::GetInstance();
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
- const auto loader = Loader::GetLoader(v_file);
+ const auto loader = Loader::GetLoader(system, v_file, program_index);
+
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
// Load per game settings
Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
@@ -1106,7 +1111,7 @@ void GMainWindow::BootGame(const QString& filename) {
SelectAndSetCurrentUser();
}
- if (!LoadROM(filename))
+ if (!LoadROM(filename, program_index))
return;
// Create and start the emulation thread
@@ -1114,6 +1119,10 @@ void GMainWindow::BootGame(const QString& filename) {
emit EmulationStarting(emu_thread.get());
emu_thread->start();
+ // Register an ExecuteProgram callback such that Core can execute a sub-program
+ system.RegisterExecuteProgramCallback(
+ [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); });
+
connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
// before the CPU continues
@@ -1144,9 +1153,13 @@ void GMainWindow::BootGame(const QString& filename) {
std::string title_name;
std::string title_version;
- const auto res = Core::System::GetInstance().GetGameName(title_name);
+ const auto res = system.GetGameName(title_name);
- const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata();
+ const auto metadata = [&system, title_id] {
+ const FileSys::PatchManager pm(title_id, system.GetFileSystemController(),
+ system.GetContentProvider());
+ return pm.GetControlMetadata();
+ }();
if (metadata.first != nullptr) {
title_version = metadata.first->GetVersionString();
title_name = metadata.first->GetApplicationName();
@@ -1157,7 +1170,7 @@ void GMainWindow::BootGame(const QString& filename) {
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->Prepare(system.GetAppLoader());
loading_screen->show();
emulation_running = true;
@@ -1276,16 +1289,18 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
const std::string& game_path) {
std::string path;
QString open_target;
+ auto& system = Core::System::GetInstance();
- const auto [user_save_size, device_save_size] = [this, &program_id, &game_path] {
- FileSys::PatchManager pm{program_id};
+ const auto [user_save_size, device_save_size] = [this, &game_path, &program_id, &system] {
+ const FileSys::PatchManager pm{program_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
const auto control = pm.GetControlMetadata().first;
if (control != nullptr) {
return std::make_pair(control->GetDefaultNormalSaveSize(),
control->GetDeviceSaveDataSize());
} else {
const auto file = Core::GetGameFileFromPath(vfs, game_path);
- const auto loader = Loader::GetLoader(file);
+ const auto loader = Loader::GetLoader(system, file);
FileSys::NACP nacp{};
loader->ReadControlData(nacp);
@@ -1612,7 +1627,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
"cancelled the operation."));
};
- const auto loader = Loader::GetLoader(vfs->OpenFile(game_path, FileSys::Mode::Read));
+ auto& system = Core::System::GetInstance();
+ const auto loader = Loader::GetLoader(system, vfs->OpenFile(game_path, FileSys::Mode::Read));
if (loader == nullptr) {
failed();
return;
@@ -1624,7 +1640,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
return;
}
- const auto& installed = Core::System::GetInstance().GetContentProvider();
+ const auto& installed = system.GetContentProvider();
const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
if (!romfs_title_id) {
@@ -1639,7 +1655,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
if (*romfs_title_id == program_id) {
const u64 ivfc_offset = loader->ReadRomFSIVFCOffset();
- FileSys::PatchManager pm{program_id};
+ const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed};
romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program);
} else {
romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS();
@@ -1756,7 +1772,8 @@ void GMainWindow::OnGameListShowList(bool show) {
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
u64 title_id{};
const auto v_file = Core::GetGameFileFromPath(vfs, file);
- const auto loader = Loader::GetLoader(v_file);
+ const auto loader = Loader::GetLoader(Core::System::GetInstance(), v_file);
+
if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
QMessageBox::information(this, tr("Properties"),
tr("The game properties could not be loaded."));
@@ -2128,6 +2145,11 @@ void GMainWindow::OnLoadComplete() {
loading_screen->OnLoadComplete();
}
+void GMainWindow::OnExecuteProgram(std::size_t program_index) {
+ ShutdownGame();
+ BootGame(last_filename_booted, program_index);
+}
+
void GMainWindow::ErrorDisplayDisplayError(QString body) {
QMessageBox::critical(this, tr("Error Display"), body);
emit ErrorDisplayFinished();
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index b380a66f3..6242341d1 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -131,6 +131,7 @@ signals:
public slots:
void OnLoadComplete();
+ void OnExecuteProgram(std::size_t program_index);
void ControllerSelectorReconfigureControllers(
const Core::Frontend::ControllerParameters& parameters);
void ErrorDisplayDisplayError(QString body);
@@ -154,8 +155,8 @@ private:
void PreventOSSleep();
void AllowOSSleep();
- bool LoadROM(const QString& filename);
- void BootGame(const QString& filename);
+ bool LoadROM(const QString& filename, std::size_t program_index);
+ void BootGame(const QString& filename, std::size_t program_index = 0);
void ShutdownGame();
void ShowTelemetryCallout();
@@ -317,6 +318,9 @@ private:
// Install progress dialog
QProgressDialog* install_progress;
+ // Last game booted, used for multi-process apps
+ QString last_filename_booted;
+
protected:
void dropEvent(QDropEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override;