frontend: yuzu (qt): Register a callback for ExecuteProgram.

This commit is contained in:
bunnei 2020-11-24 15:18:29 -08:00
parent 4fb5ca80c0
commit 4fbe4da911
4 changed files with 38 additions and 7 deletions

View File

@ -302,6 +302,12 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
this->setMouseTracking(true); this->setMouseTracking(true);
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); 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() { GRenderWindow::~GRenderWindow() {

View File

@ -166,6 +166,12 @@ public:
std::pair<u32, u32> ScaleTouch(const QPointF& pos) const; 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: public slots:
void OnEmulationStarting(EmuThread* emu_thread); void OnEmulationStarting(EmuThread* emu_thread);
void OnEmulationStopping(); void OnEmulationStopping();
@ -175,6 +181,7 @@ signals:
/// Emitted when the window is closed /// Emitted when the window is closed
void Closed(); void Closed();
void FirstFrameDisplayed(); void FirstFrameDisplayed();
void ExecuteProgramSignal(std::size_t program_index);
private: private:
void TouchBeginEvent(const QTouchEvent* event); void TouchBeginEvent(const QTouchEvent* event);

View File

@ -978,7 +978,7 @@ void GMainWindow::AllowOSSleep() {
#endif #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... // Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr) if (emu_thread != nullptr)
ShutdownGame(); ShutdownGame();
@ -1003,7 +1003,8 @@ bool GMainWindow::LoadROM(const QString& filename) {
system.RegisterHostThread(); 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 = const auto drd_callout =
(UISettings::values.callout_flags & static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0; (UISettings::values.callout_flags & static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
@ -1085,14 +1086,18 @@ void GMainWindow::SelectAndSetCurrentUser() {
Settings::values.current_user = dialog.GetIndex(); 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..."); LOG_INFO(Frontend, "yuzu starting...");
StoreRecentFile(filename); // Put the filename on top of the list StoreRecentFile(filename); // Put the filename on top of the list
u64 title_id{0}; u64 title_id{0};
last_filename_booted = filename;
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
const auto loader = Loader::GetLoader(system, v_file); const auto loader = Loader::GetLoader(system, v_file, program_index);
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
// Load per game settings // Load per game settings
Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig); Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
@ -1106,7 +1111,7 @@ void GMainWindow::BootGame(const QString& filename) {
SelectAndSetCurrentUser(); SelectAndSetCurrentUser();
} }
if (!LoadROM(filename)) if (!LoadROM(filename, program_index))
return; return;
// Create and start the emulation thread // Create and start the emulation thread
@ -1114,6 +1119,10 @@ void GMainWindow::BootGame(const QString& filename) {
emit EmulationStarting(emu_thread.get()); emit EmulationStarting(emu_thread.get());
emu_thread->start(); 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); connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
// BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
// before the CPU continues // before the CPU continues
@ -2136,6 +2145,11 @@ void GMainWindow::OnLoadComplete() {
loading_screen->OnLoadComplete(); loading_screen->OnLoadComplete();
} }
void GMainWindow::OnExecuteProgram(std::size_t program_index) {
ShutdownGame();
BootGame(last_filename_booted, program_index);
}
void GMainWindow::ErrorDisplayDisplayError(QString body) { void GMainWindow::ErrorDisplayDisplayError(QString body) {
QMessageBox::critical(this, tr("Error Display"), body); QMessageBox::critical(this, tr("Error Display"), body);
emit ErrorDisplayFinished(); emit ErrorDisplayFinished();

View File

@ -131,6 +131,7 @@ signals:
public slots: public slots:
void OnLoadComplete(); void OnLoadComplete();
void OnExecuteProgram(std::size_t program_index);
void ControllerSelectorReconfigureControllers( void ControllerSelectorReconfigureControllers(
const Core::Frontend::ControllerParameters& parameters); const Core::Frontend::ControllerParameters& parameters);
void ErrorDisplayDisplayError(QString body); void ErrorDisplayDisplayError(QString body);
@ -154,8 +155,8 @@ private:
void PreventOSSleep(); void PreventOSSleep();
void AllowOSSleep(); void AllowOSSleep();
bool LoadROM(const QString& filename); bool LoadROM(const QString& filename, std::size_t program_index);
void BootGame(const QString& filename); void BootGame(const QString& filename, std::size_t program_index = 0);
void ShutdownGame(); void ShutdownGame();
void ShowTelemetryCallout(); void ShowTelemetryCallout();
@ -317,6 +318,9 @@ private:
// Install progress dialog // Install progress dialog
QProgressDialog* install_progress; QProgressDialog* install_progress;
// Last game booted, used for multi-process apps
QString last_filename_booted;
protected: protected:
void dropEvent(QDropEvent* event) override; void dropEvent(QDropEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override;