diff options
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.h | 7 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 24 | ||||
| -rw-r--r-- | src/yuzu/main.h | 8 |
4 files changed, 38 insertions, 7 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_, | |||
| 302 | this->setMouseTracking(true); | 302 | this->setMouseTracking(true); |
| 303 | 303 | ||
| 304 | connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); | 304 | connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); |
| 305 | connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram, | ||
| 306 | Qt::QueuedConnection); | ||
| 307 | } | ||
| 308 | |||
| 309 | void GRenderWindow::ExecuteProgram(std::size_t program_index) { | ||
| 310 | emit ExecuteProgramSignal(program_index); | ||
| 305 | } | 311 | } |
| 306 | 312 | ||
| 307 | GRenderWindow::~GRenderWindow() { | 313 | 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: | |||
| 166 | 166 | ||
| 167 | std::pair<u32, u32> ScaleTouch(const QPointF& pos) const; | 167 | std::pair<u32, u32> ScaleTouch(const QPointF& pos) const; |
| 168 | 168 | ||
| 169 | /** | ||
| 170 | * Instructs the window to re-launch the application using the specified program_index. | ||
| 171 | * @param program_index Specifies the index within the application of the program to launch. | ||
| 172 | */ | ||
| 173 | void ExecuteProgram(std::size_t program_index); | ||
| 174 | |||
| 169 | public slots: | 175 | public slots: |
| 170 | void OnEmulationStarting(EmuThread* emu_thread); | 176 | void OnEmulationStarting(EmuThread* emu_thread); |
| 171 | void OnEmulationStopping(); | 177 | void OnEmulationStopping(); |
| @@ -175,6 +181,7 @@ signals: | |||
| 175 | /// Emitted when the window is closed | 181 | /// Emitted when the window is closed |
| 176 | void Closed(); | 182 | void Closed(); |
| 177 | void FirstFrameDisplayed(); | 183 | void FirstFrameDisplayed(); |
| 184 | void ExecuteProgramSignal(std::size_t program_index); | ||
| 178 | 185 | ||
| 179 | private: | 186 | private: |
| 180 | void TouchBeginEvent(const QTouchEvent* event); | 187 | void TouchBeginEvent(const QTouchEvent* event); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e704cc656..805619ccf 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -978,7 +978,7 @@ void GMainWindow::AllowOSSleep() { | |||
| 978 | #endif | 978 | #endif |
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | bool GMainWindow::LoadROM(const QString& filename) { | 981 | bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) { |
| 982 | // Shutdown previous session if the emu thread is still active... | 982 | // Shutdown previous session if the emu thread is still active... |
| 983 | if (emu_thread != nullptr) | 983 | if (emu_thread != nullptr) |
| 984 | ShutdownGame(); | 984 | ShutdownGame(); |
| @@ -1003,7 +1003,8 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 1003 | 1003 | ||
| 1004 | system.RegisterHostThread(); | 1004 | system.RegisterHostThread(); |
| 1005 | 1005 | ||
| 1006 | const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())}; | 1006 | const Core::System::ResultStatus result{ |
| 1007 | system.Load(*render_window, filename.toStdString(), program_index)}; | ||
| 1007 | 1008 | ||
| 1008 | const auto drd_callout = | 1009 | const auto drd_callout = |
| 1009 | (UISettings::values.callout_flags & static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0; | 1010 | (UISettings::values.callout_flags & static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0; |
| @@ -1085,14 +1086,18 @@ void GMainWindow::SelectAndSetCurrentUser() { | |||
| 1085 | Settings::values.current_user = dialog.GetIndex(); | 1086 | Settings::values.current_user = dialog.GetIndex(); |
| 1086 | } | 1087 | } |
| 1087 | 1088 | ||
| 1088 | void GMainWindow::BootGame(const QString& filename) { | 1089 | void GMainWindow::BootGame(const QString& filename, std::size_t program_index) { |
| 1089 | LOG_INFO(Frontend, "yuzu starting..."); | 1090 | LOG_INFO(Frontend, "yuzu starting..."); |
| 1090 | StoreRecentFile(filename); // Put the filename on top of the list | 1091 | StoreRecentFile(filename); // Put the filename on top of the list |
| 1091 | 1092 | ||
| 1092 | u64 title_id{0}; | 1093 | u64 title_id{0}; |
| 1094 | |||
| 1095 | last_filename_booted = filename; | ||
| 1096 | |||
| 1093 | auto& system = Core::System::GetInstance(); | 1097 | auto& system = Core::System::GetInstance(); |
| 1094 | const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); | 1098 | const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); |
| 1095 | const auto loader = Loader::GetLoader(system, v_file); | 1099 | const auto loader = Loader::GetLoader(system, v_file, program_index); |
| 1100 | |||
| 1096 | if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { | 1101 | if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { |
| 1097 | // Load per game settings | 1102 | // Load per game settings |
| 1098 | Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig); | 1103 | Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig); |
| @@ -1106,7 +1111,7 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1106 | SelectAndSetCurrentUser(); | 1111 | SelectAndSetCurrentUser(); |
| 1107 | } | 1112 | } |
| 1108 | 1113 | ||
| 1109 | if (!LoadROM(filename)) | 1114 | if (!LoadROM(filename, program_index)) |
| 1110 | return; | 1115 | return; |
| 1111 | 1116 | ||
| 1112 | // Create and start the emulation thread | 1117 | // Create and start the emulation thread |
| @@ -1114,6 +1119,10 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1114 | emit EmulationStarting(emu_thread.get()); | 1119 | emit EmulationStarting(emu_thread.get()); |
| 1115 | emu_thread->start(); | 1120 | emu_thread->start(); |
| 1116 | 1121 | ||
| 1122 | // Register an ExecuteProgram callback such that Core can execute a sub-program | ||
| 1123 | system.RegisterExecuteProgramCallback( | ||
| 1124 | [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); }); | ||
| 1125 | |||
| 1117 | connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); | 1126 | connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); |
| 1118 | // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views | 1127 | // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views |
| 1119 | // before the CPU continues | 1128 | // before the CPU continues |
| @@ -2136,6 +2145,11 @@ void GMainWindow::OnLoadComplete() { | |||
| 2136 | loading_screen->OnLoadComplete(); | 2145 | loading_screen->OnLoadComplete(); |
| 2137 | } | 2146 | } |
| 2138 | 2147 | ||
| 2148 | void GMainWindow::OnExecuteProgram(std::size_t program_index) { | ||
| 2149 | ShutdownGame(); | ||
| 2150 | BootGame(last_filename_booted, program_index); | ||
| 2151 | } | ||
| 2152 | |||
| 2139 | void GMainWindow::ErrorDisplayDisplayError(QString body) { | 2153 | void GMainWindow::ErrorDisplayDisplayError(QString body) { |
| 2140 | QMessageBox::critical(this, tr("Error Display"), body); | 2154 | QMessageBox::critical(this, tr("Error Display"), body); |
| 2141 | emit ErrorDisplayFinished(); | 2155 | 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: | |||
| 131 | 131 | ||
| 132 | public slots: | 132 | public slots: |
| 133 | void OnLoadComplete(); | 133 | void OnLoadComplete(); |
| 134 | void OnExecuteProgram(std::size_t program_index); | ||
| 134 | void ControllerSelectorReconfigureControllers( | 135 | void ControllerSelectorReconfigureControllers( |
| 135 | const Core::Frontend::ControllerParameters& parameters); | 136 | const Core::Frontend::ControllerParameters& parameters); |
| 136 | void ErrorDisplayDisplayError(QString body); | 137 | void ErrorDisplayDisplayError(QString body); |
| @@ -154,8 +155,8 @@ private: | |||
| 154 | void PreventOSSleep(); | 155 | void PreventOSSleep(); |
| 155 | void AllowOSSleep(); | 156 | void AllowOSSleep(); |
| 156 | 157 | ||
| 157 | bool LoadROM(const QString& filename); | 158 | bool LoadROM(const QString& filename, std::size_t program_index); |
| 158 | void BootGame(const QString& filename); | 159 | void BootGame(const QString& filename, std::size_t program_index = 0); |
| 159 | void ShutdownGame(); | 160 | void ShutdownGame(); |
| 160 | 161 | ||
| 161 | void ShowTelemetryCallout(); | 162 | void ShowTelemetryCallout(); |
| @@ -317,6 +318,9 @@ private: | |||
| 317 | // Install progress dialog | 318 | // Install progress dialog |
| 318 | QProgressDialog* install_progress; | 319 | QProgressDialog* install_progress; |
| 319 | 320 | ||
| 321 | // Last game booted, used for multi-process apps | ||
| 322 | QString last_filename_booted; | ||
| 323 | |||
| 320 | protected: | 324 | protected: |
| 321 | void dropEvent(QDropEvent* event) override; | 325 | void dropEvent(QDropEvent* event) override; |
| 322 | void dragEnterEvent(QDragEnterEvent* event) override; | 326 | void dragEnterEvent(QDragEnterEvent* event) override; |