am: retrieve main applet creation info from frontend
This commit is contained in:
		| @@ -261,7 +261,7 @@ object NativeLibrary { | ||||
|     /** | ||||
|      * Begins emulation. | ||||
|      */ | ||||
|     external fun run(path: String?, programIndex: Int = 0) | ||||
|     external fun run(path: String?, programIndex: Int, frontendInitiated: Boolean) | ||||
|  | ||||
|     // Surface Handling | ||||
|     external fun surfaceChanged(surf: Surface?) | ||||
|   | ||||
| @@ -927,7 +927,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|             emulationThread.join() | ||||
|             emulationThread = Thread({ | ||||
|                 Log.debug("[EmulationFragment] Starting emulation thread.") | ||||
|                 NativeLibrary.run(gamePath, programIndex) | ||||
|                 NativeLibrary.run(gamePath, programIndex, false) | ||||
|             }, "NativeEmulation") | ||||
|             emulationThread.start() | ||||
|         } | ||||
| @@ -981,7 +981,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|                 State.STOPPED -> { | ||||
|                     emulationThread = Thread({ | ||||
|                         Log.debug("[EmulationFragment] Starting emulation thread.") | ||||
|                         NativeLibrary.run(gamePath, programIndex) | ||||
|                         NativeLibrary.run(gamePath, programIndex, true) | ||||
|                     }, "NativeEmulation") | ||||
|                     emulationThread.start() | ||||
|                 } | ||||
|   | ||||
| @@ -48,6 +48,7 @@ | ||||
| #include "core/frontend/applets/software_keyboard.h" | ||||
| #include "core/frontend/applets/web_browser.h" | ||||
| #include "core/hle/service/am/applet_ae.h" | ||||
| #include "core/hle/service/am/applet_manager.h" | ||||
| #include "core/hle/service/am/applet_oe.h" | ||||
| #include "core/hle/service/am/frontend/applets.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| @@ -211,8 +212,15 @@ void EmulationSession::InitializeSystem(bool reload) { | ||||
|     m_system.GetFileSystemController().CreateFactories(*m_vfs); | ||||
| } | ||||
|  | ||||
| void EmulationSession::SetAppletId(int applet_id) { | ||||
|     m_applet_id = applet_id; | ||||
|     m_system.GetFrontendAppletHolder().SetCurrentAppletId( | ||||
|         static_cast<Service::AM::AppletId>(m_applet_id)); | ||||
| } | ||||
|  | ||||
| Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath, | ||||
|                                                                const std::size_t program_index) { | ||||
|                                                                const std::size_t program_index, | ||||
|                                                                const bool frontend_initiated) { | ||||
|     std::scoped_lock lock(m_mutex); | ||||
|  | ||||
|     // Create the render window. | ||||
| @@ -242,8 +250,13 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string | ||||
|     ConfigureFilesystemProvider(filepath); | ||||
|  | ||||
|     // Load the ROM. | ||||
|     m_load_result = | ||||
|         m_system.Load(EmulationSession::GetInstance().Window(), filepath, 0, program_index); | ||||
|     Service::AM::FrontendAppletParameters params{ | ||||
|         .applet_id = static_cast<Service::AM::AppletId>(m_applet_id), | ||||
|         .launch_type = frontend_initiated ? Service::AM::LaunchType::FrontendInitiated | ||||
|                                           : Service::AM::LaunchType::ApplicationInitiated, | ||||
|         .program_index = static_cast<s32>(program_index), | ||||
|     }; | ||||
|     m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params); | ||||
|     if (m_load_result != Core::SystemResultStatus::Success) { | ||||
|         return m_load_result; | ||||
|     } | ||||
| @@ -339,6 +352,9 @@ void EmulationSession::RunEmulation() { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Reset current applet ID. | ||||
|     m_applet_id = static_cast<int>(Service::AM::AppletId::Application); | ||||
| } | ||||
|  | ||||
| bool EmulationSession::IsHandheldOnly() { | ||||
| @@ -434,7 +450,8 @@ u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) { | ||||
| } | ||||
|  | ||||
| static Core::SystemResultStatus RunEmulation(const std::string& filepath, | ||||
|                                              const size_t program_index = 0) { | ||||
|                                              const size_t program_index, | ||||
|                                              const bool frontend_initiated) { | ||||
|     MicroProfileOnThreadCreate("EmuThread"); | ||||
|     SCOPE_EXIT({ MicroProfileShutdown(); }); | ||||
|  | ||||
| @@ -447,7 +464,8 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath, | ||||
|  | ||||
|     SCOPE_EXIT({ EmulationSession::GetInstance().ShutdownEmulation(); }); | ||||
|  | ||||
|     jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index); | ||||
|     jconst result = EmulationSession::GetInstance().InitializeEmulation(filepath, program_index, | ||||
|                                                                         frontend_initiated); | ||||
|     if (result != Core::SystemResultStatus::Success) { | ||||
|         return result; | ||||
|     } | ||||
| @@ -744,10 +762,12 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj | ||||
| } | ||||
|  | ||||
| void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path, | ||||
|                                                jint j_program_index) { | ||||
|                                                jint j_program_index, | ||||
|                                                jboolean j_frontend_initiated) { | ||||
|     const std::string path = GetJString(env, j_path); | ||||
|  | ||||
|     const Core::SystemResultStatus result{RunEmulation(path, j_program_index)}; | ||||
|     const Core::SystemResultStatus result{ | ||||
|         RunEmulation(path, j_program_index, j_frontend_initiated)}; | ||||
|     if (result != Core::SystemResultStatus::Success) { | ||||
|         env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), | ||||
|                                   IDCache::GetExitEmulationActivity(), static_cast<int>(result)); | ||||
| @@ -809,8 +829,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, j | ||||
|  | ||||
| void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz, | ||||
|                                                               jint jappletId) { | ||||
|     EmulationSession::GetInstance().System().GetFrontendAppletHolder().SetCurrentAppletId( | ||||
|         static_cast<Service::AM::AppletId>(jappletId)); | ||||
|     EmulationSession::GetInstance().SetAppletId(jappletId); | ||||
| } | ||||
|  | ||||
| void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass clazz, | ||||
|   | ||||
| @@ -45,8 +45,10 @@ public: | ||||
|     const Core::PerfStatsResults& PerfStats(); | ||||
|     void ConfigureFilesystemProvider(const std::string& filepath); | ||||
|     void InitializeSystem(bool reload); | ||||
|     void SetAppletId(int applet_id); | ||||
|     Core::SystemResultStatus InitializeEmulation(const std::string& filepath, | ||||
|                                                  const std::size_t program_index = 0); | ||||
|                                                  const std::size_t program_index, | ||||
|                                                  const bool frontend_initiated); | ||||
|  | ||||
|     bool IsHandheldOnly(); | ||||
|     void SetDeviceType([[maybe_unused]] int index, int type); | ||||
| @@ -79,6 +81,7 @@ private: | ||||
|     std::atomic<bool> m_is_paused = false; | ||||
|     SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; | ||||
|     std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider; | ||||
|     int m_applet_id{1}; | ||||
|  | ||||
|     // GPU driver parameters | ||||
|     std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; | ||||
|   | ||||
| @@ -36,6 +36,7 @@ | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/physical_core.h" | ||||
| #include "core/hle/service/acc/profile_manager.h" | ||||
| #include "core/hle/service/am/applet_manager.h" | ||||
| #include "core/hle/service/am/frontend/applets.h" | ||||
| #include "core/hle/service/apm/apm_controller.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| @@ -136,7 +137,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | ||||
| struct System::Impl { | ||||
|     explicit Impl(System& system) | ||||
|         : kernel{system}, fs_controller{system}, hid_core{}, room_network{}, cpu_manager{system}, | ||||
|           reporter{system}, frontend_applets{system}, profile_manager{} {} | ||||
|           reporter{system}, applet_manager{system}, frontend_applets{system}, profile_manager{} {} | ||||
|  | ||||
|     void Initialize(System& system) { | ||||
|         device_memory = std::make_unique<Core::DeviceMemory>(); | ||||
| @@ -330,16 +331,27 @@ struct System::Impl { | ||||
|     } | ||||
|  | ||||
|     SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, | ||||
|                             const std::string& filepath, u64 program_id, | ||||
|                             std::size_t program_index) { | ||||
|                             const std::string& filepath, | ||||
|                             Service::AM::FrontendAppletParameters& params) { | ||||
|         app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath), | ||||
|                                        program_id, program_index); | ||||
|                                        params.program_id, params.program_index); | ||||
|  | ||||
|         if (!app_loader) { | ||||
|             LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); | ||||
|             return SystemResultStatus::ErrorGetLoader; | ||||
|         } | ||||
|  | ||||
|         if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) { | ||||
|             LOG_ERROR(Core, "Failed to find title id for ROM!"); | ||||
|         } | ||||
|  | ||||
|         std::string name = "Unknown program"; | ||||
|         if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) { | ||||
|             LOG_ERROR(Core, "Failed to read title for ROM!"); | ||||
|         } | ||||
|  | ||||
|         LOG_INFO(Core, "Loading {} ({})", name, params.program_id); | ||||
|  | ||||
|         InitializeKernel(system); | ||||
|  | ||||
|         // Create the application process. | ||||
| @@ -373,6 +385,10 @@ struct System::Impl { | ||||
|             cheat_engine->Initialize(); | ||||
|         } | ||||
|  | ||||
|         // Register with applet manager. | ||||
|         applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(), | ||||
|                                                                  params); | ||||
|  | ||||
|         // All threads are started, begin main process execution, now that we're in the clear. | ||||
|         main_process->Run(load_parameters->main_thread_priority, | ||||
|                           load_parameters->main_thread_stack_size); | ||||
| @@ -386,21 +402,13 @@ struct System::Impl { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (app_loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) { | ||||
|             LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", load_result); | ||||
|         } | ||||
|         perf_stats = std::make_unique<PerfStats>(program_id); | ||||
|         perf_stats = std::make_unique<PerfStats>(params.program_id); | ||||
|         // Reset counters and set time origin to current frame | ||||
|         GetAndResetPerfStats(); | ||||
|         perf_stats->BeginSystemFrame(); | ||||
|  | ||||
|         std::string name = "Unknown Game"; | ||||
|         if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) { | ||||
|             LOG_ERROR(Core, "Failed to read title for ROM (Error {})", load_result); | ||||
|         } | ||||
|  | ||||
|         std::string title_version; | ||||
|         const FileSys::PatchManager pm(program_id, system.GetFileSystemController(), | ||||
|         const FileSys::PatchManager pm(params.program_id, system.GetFileSystemController(), | ||||
|                                        system.GetContentProvider()); | ||||
|         const auto metadata = pm.GetControlMetadata(); | ||||
|         if (metadata.first != nullptr) { | ||||
| @@ -409,14 +417,15 @@ struct System::Impl { | ||||
|         if (auto room_member = room_network.GetRoomMember().lock()) { | ||||
|             Network::GameInfo game_info; | ||||
|             game_info.name = name; | ||||
|             game_info.id = program_id; | ||||
|             game_info.id = params.program_id; | ||||
|             game_info.version = title_version; | ||||
|             room_member->SendGameInfo(game_info); | ||||
|         } | ||||
|  | ||||
|         // Workarounds: | ||||
|         // Activate this in Super Smash Brothers Ultimate, it only affects AMD cards using AMDVLK | ||||
|         Settings::values.renderer_amdvlk_depth_bias_workaround = program_id == 0x1006A800016E000ULL; | ||||
|         Settings::values.renderer_amdvlk_depth_bias_workaround = | ||||
|             params.program_id == 0x1006A800016E000ULL; | ||||
|  | ||||
|         status = SystemResultStatus::Success; | ||||
|         return status; | ||||
| @@ -455,6 +464,7 @@ struct System::Impl { | ||||
|         } | ||||
|         kernel.CloseServices(); | ||||
|         kernel.ShutdownCores(); | ||||
|         applet_manager.Reset(); | ||||
|         services.reset(); | ||||
|         service_manager.reset(); | ||||
|         fs_controller.Reset(); | ||||
| @@ -566,7 +576,8 @@ struct System::Impl { | ||||
|  | ||||
|     std::unique_ptr<Tools::RenderdocAPI> renderdoc_api; | ||||
|  | ||||
|     /// Frontend applets | ||||
|     /// Applets | ||||
|     Service::AM::AppletManager applet_manager; | ||||
|     Service::AM::Frontend::FrontendAppletHolder frontend_applets; | ||||
|  | ||||
|     /// APM (Performance) services | ||||
| @@ -680,8 +691,8 @@ void System::InitializeDebugger() { | ||||
| } | ||||
|  | ||||
| SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath, | ||||
|                                 u64 program_id, std::size_t program_index) { | ||||
|     return impl->Load(*this, emu_window, filepath, program_id, program_index); | ||||
|                                 Service::AM::FrontendAppletParameters& params) { | ||||
|     return impl->Load(*this, emu_window, filepath, params); | ||||
| } | ||||
|  | ||||
| bool System::IsPoweredOn() const { | ||||
|   | ||||
| @@ -50,6 +50,11 @@ namespace Account { | ||||
| class ProfileManager; | ||||
| } // namespace Account | ||||
|  | ||||
| namespace AM { | ||||
| struct FrontendAppletParameters; | ||||
| class AppletManager; | ||||
| } // namespace AM | ||||
|  | ||||
| namespace AM::Frontend { | ||||
| struct FrontendAppletSet; | ||||
| class FrontendAppletHolder; | ||||
| @@ -203,8 +208,8 @@ public: | ||||
|      * @returns SystemResultStatus code, indicating if the operation succeeded. | ||||
|      */ | ||||
|     [[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window, | ||||
|                                           const std::string& filepath, u64 program_id = 0, | ||||
|                                           std::size_t program_index = 0); | ||||
|                                           const std::string& filepath, | ||||
|                                           Service::AM::FrontendAppletParameters& params); | ||||
|  | ||||
|     /** | ||||
|      * Indicates if the emulated system is powered on (all subsystems initialized and able to run an | ||||
|   | ||||
| @@ -596,14 +596,10 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri | ||||
|     connect(open_save_location, &QAction::triggered, [this, program_id, path]() { | ||||
|         emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path); | ||||
|     }); | ||||
|     connect(start_game, &QAction::triggered, [this, path]() { | ||||
|         emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal, | ||||
|                       AmLaunchType::UserInitiated); | ||||
|     }); | ||||
|     connect(start_game_global, &QAction::triggered, [this, path]() { | ||||
|         emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global, | ||||
|                       AmLaunchType::UserInitiated); | ||||
|     }); | ||||
|     connect(start_game, &QAction::triggered, | ||||
|             [this, path]() { emit BootGame(QString::fromStdString(path), StartGameType::Normal); }); | ||||
|     connect(start_game_global, &QAction::triggered, | ||||
|             [this, path]() { emit BootGame(QString::fromStdString(path), StartGameType::Global); }); | ||||
|     connect(open_mod_location, &QAction::triggered, [this, program_id, path]() { | ||||
|         emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path); | ||||
|     }); | ||||
|   | ||||
| @@ -106,8 +106,7 @@ public: | ||||
|     static const QStringList supported_file_extensions; | ||||
|  | ||||
| signals: | ||||
|     void BootGame(const QString& game_path, u64 program_id, std::size_t program_index, | ||||
|                   StartGameType type, AmLaunchType launch_type); | ||||
|     void BootGame(const QString& game_path, StartGameType type); | ||||
|     void GameChosen(const QString& game_path, const u64 title_id = 0); | ||||
|     void OpenFolderRequested(u64 program_id, GameListOpenTarget target, | ||||
|                              const std::string& game_path); | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <iostream> | ||||
| #include <memory> | ||||
| #include <thread> | ||||
| #include "core/hle/service/am/applet_manager.h" | ||||
| #include "core/loader/nca.h" | ||||
| #include "core/tools/renderdoc.h" | ||||
|  | ||||
| @@ -569,7 +570,7 @@ GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulk | ||||
|     } | ||||
|  | ||||
|     if (!game_path.isEmpty()) { | ||||
|         BootGame(game_path); | ||||
|         BootGame(game_path, ApplicationAppletParameters()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1474,7 +1475,7 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { | ||||
| } | ||||
|  | ||||
| void GMainWindow::ConnectWidgetEvents() { | ||||
|     connect(game_list, &GameList::BootGame, this, &GMainWindow::BootGame); | ||||
|     connect(game_list, &GameList::BootGame, this, &GMainWindow::BootGameFromList); | ||||
|     connect(game_list, &GameList::GameChosen, this, &GMainWindow::OnGameListLoadFile); | ||||
|     connect(game_list, &GameList::OpenDirectory, this, &GMainWindow::OnGameListOpenDirectory); | ||||
|     connect(game_list, &GameList::OpenFolderRequested, this, &GMainWindow::OnGameListOpenFolder); | ||||
| @@ -1762,8 +1763,7 @@ void GMainWindow::AllowOSSleep() { | ||||
| #endif | ||||
| } | ||||
|  | ||||
| bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index, | ||||
|                           AmLaunchType launch_type) { | ||||
| bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletParameters params) { | ||||
|     // Shutdown previous session if the emu thread is still active... | ||||
|     if (emu_thread != nullptr) { | ||||
|         ShutdownGame(); | ||||
| @@ -1775,7 +1775,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | ||||
|  | ||||
|     system->SetFilesystem(vfs); | ||||
|  | ||||
|     if (launch_type == AmLaunchType::UserInitiated) { | ||||
|     if (params.launch_type == Service::AM::LaunchType::FrontendInitiated) { | ||||
|         system->GetUserChannel().clear(); | ||||
|     } | ||||
|  | ||||
| @@ -1794,7 +1794,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | ||||
|     }); | ||||
|  | ||||
|     const Core::SystemResultStatus result{ | ||||
|         system->Load(*render_window, filename.toStdString(), program_id, program_index)}; | ||||
|         system->Load(*render_window, filename.toStdString(), params)}; | ||||
|  | ||||
|     const auto drd_callout = (UISettings::values.callout_flags.GetValue() & | ||||
|                               static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0; | ||||
| @@ -1917,12 +1917,12 @@ void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, | ||||
|                            StartGameType type, AmLaunchType launch_type) { | ||||
| void GMainWindow::BootGame(const QString& filename, Service::AM::FrontendAppletParameters params, | ||||
|                            StartGameType type) { | ||||
|     LOG_INFO(Frontend, "yuzu starting..."); | ||||
|  | ||||
|     if (program_id == 0 || | ||||
|         program_id > static_cast<u64>(Service::AM::AppletProgramId::MaxProgramId)) { | ||||
|     if (params.program_id == 0 || | ||||
|         params.program_id > static_cast<u64>(Service::AM::AppletProgramId::MaxProgramId)) { | ||||
|         StoreRecentFile(filename); // Put the filename on top of the list | ||||
|     } | ||||
|  | ||||
| @@ -1937,7 +1937,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | ||||
|  | ||||
|     ConfigureFilesystemProvider(filename.toStdString()); | ||||
|     const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); | ||||
|     const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index); | ||||
|     const auto loader = Loader::GetLoader(*system, v_file, params.program_id, params.program_index); | ||||
|  | ||||
|     if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success && | ||||
|         type == StartGameType::Normal) { | ||||
| @@ -1971,7 +1971,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | ||||
|     // behavior of asking. | ||||
|     user_flag_cmd_line = false; | ||||
|  | ||||
|     if (!LoadROM(filename, program_id, program_index, launch_type)) { | ||||
|     if (!LoadROM(filename, params)) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| @@ -2061,6 +2061,10 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | ||||
|     OnStartGame(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::BootGameFromList(const QString& filename, StartGameType with_config) { | ||||
|     BootGame(filename, ApplicationAppletParameters(), with_config); | ||||
| } | ||||
|  | ||||
| bool GMainWindow::OnShutdownBegin() { | ||||
|     if (!emulation_running) { | ||||
|         return false; | ||||
| @@ -2241,7 +2245,10 @@ void GMainWindow::UpdateRecentFiles() { | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) { | ||||
|     BootGame(game_path, program_id); | ||||
|     auto params = ApplicationAppletParameters(); | ||||
|     params.program_id = program_id; | ||||
|  | ||||
|     BootGame(game_path, params); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target, | ||||
| @@ -3173,7 +3180,7 @@ void GMainWindow::OnMenuLoadFile() { | ||||
|     } | ||||
|  | ||||
|     UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); | ||||
|     BootGame(filename); | ||||
|     BootGame(filename, ApplicationAppletParameters()); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnMenuLoadFolder() { | ||||
| @@ -3187,7 +3194,7 @@ void GMainWindow::OnMenuLoadFolder() { | ||||
|     const QDir dir{dir_path}; | ||||
|     const QStringList matching_main = dir.entryList({QStringLiteral("main")}, QDir::Files); | ||||
|     if (matching_main.size() == 1) { | ||||
|         BootGame(dir.path() + QDir::separator() + matching_main[0]); | ||||
|         BootGame(dir.path() + QDir::separator() + matching_main[0], ApplicationAppletParameters()); | ||||
|     } else { | ||||
|         QMessageBox::warning(this, tr("Invalid Directory Selected"), | ||||
|                              tr("The directory you have selected does not contain a 'main' file.")); | ||||
| @@ -3381,7 +3388,7 @@ void GMainWindow::OnMenuRecentFile() { | ||||
|  | ||||
|     const QString filename = action->data().toString(); | ||||
|     if (QFileInfo::exists(filename)) { | ||||
|         BootGame(filename); | ||||
|         BootGame(filename, ApplicationAppletParameters()); | ||||
|     } else { | ||||
|         // Display an error message and remove the file from the list. | ||||
|         QMessageBox::information(this, tr("File not found"), | ||||
| @@ -3419,7 +3426,7 @@ void GMainWindow::OnRestartGame() { | ||||
|         // Make a copy since ShutdownGame edits game_path | ||||
|         const auto current_game = QString(current_game_path); | ||||
|         ShutdownGame(); | ||||
|         BootGame(current_game); | ||||
|         BootGame(current_game, ApplicationAppletParameters()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -3487,8 +3494,11 @@ void GMainWindow::OnLoadComplete() { | ||||
|  | ||||
| void GMainWindow::OnExecuteProgram(std::size_t program_index) { | ||||
|     ShutdownGame(); | ||||
|     BootGame(last_filename_booted, 0, program_index, StartGameType::Normal, | ||||
|              AmLaunchType::ApplicationInitiated); | ||||
|  | ||||
|     auto params = ApplicationAppletParameters(); | ||||
|     params.program_index = static_cast<s32>(program_index); | ||||
|     params.launch_type = Service::AM::LaunchType::ApplicationInitiated; | ||||
|     BootGame(last_filename_booted, params); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnExit() { | ||||
| @@ -4174,7 +4184,7 @@ void GMainWindow::OnAlbum() { | ||||
|  | ||||
|     const auto filename = QString::fromStdString(album_nca->GetFullPath()); | ||||
|     UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); | ||||
|     BootGame(filename, AlbumId); | ||||
|     BootGame(filename, LibraryAppletParameters(AlbumId, Service::AM::AppletId::PhotoViewer)); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) { | ||||
| @@ -4198,7 +4208,7 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) { | ||||
|  | ||||
|     const auto filename = QString::fromStdString(cabinet_nca->GetFullPath()); | ||||
|     UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); | ||||
|     BootGame(filename, CabinetId); | ||||
|     BootGame(filename, LibraryAppletParameters(CabinetId, Service::AM::AppletId::Cabinet)); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnMiiEdit() { | ||||
| @@ -4221,7 +4231,7 @@ void GMainWindow::OnMiiEdit() { | ||||
|  | ||||
|     const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath())); | ||||
|     UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); | ||||
|     BootGame(filename, MiiEditId); | ||||
|     BootGame(filename, LibraryAppletParameters(MiiEditId, Service::AM::AppletId::MiiEdit)); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnOpenControllerMenu() { | ||||
| @@ -4245,7 +4255,8 @@ void GMainWindow::OnOpenControllerMenu() { | ||||
|  | ||||
|     const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath())); | ||||
|     UISettings::values.roms_path = QFileInfo(filename).path().toStdString(); | ||||
|     BootGame(filename, ControllerAppletId); | ||||
|     BootGame(filename, | ||||
|              LibraryAppletParameters(ControllerAppletId, Service::AM::AppletId::Controller)); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnCaptureScreenshot() { | ||||
| @@ -4728,7 +4739,7 @@ bool GMainWindow::DropAction(QDropEvent* event) { | ||||
|     } else { | ||||
|         // Game | ||||
|         if (ConfirmChangeGame()) { | ||||
|             BootGame(filename); | ||||
|             BootGame(filename, ApplicationAppletParameters()); | ||||
|         } | ||||
|     } | ||||
|     return true; | ||||
| @@ -4943,6 +4954,19 @@ void GMainWindow::changeEvent(QEvent* event) { | ||||
|     QWidget::changeEvent(event); | ||||
| } | ||||
|  | ||||
| Service::AM::FrontendAppletParameters GMainWindow::ApplicationAppletParameters() { | ||||
|     return Service::AM::FrontendAppletParameters{}; | ||||
| } | ||||
|  | ||||
| Service::AM::FrontendAppletParameters GMainWindow::LibraryAppletParameters( | ||||
|     u64 program_id, Service::AM::AppletId applet_id) { | ||||
|     return Service::AM::FrontendAppletParameters{ | ||||
|         .program_id = program_id, | ||||
|         .applet_id = applet_id, | ||||
|         .applet_type = Service::AM::AppletType::LibraryApplet, | ||||
|     }; | ||||
| } | ||||
|  | ||||
| void VolumeButton::wheelEvent(QWheelEvent* event) { | ||||
|  | ||||
|     int num_degrees = event->angleDelta().y() / 8; | ||||
|   | ||||
| @@ -64,11 +64,6 @@ enum class StartGameType { | ||||
|     Global, // Only uses global configuration | ||||
| }; | ||||
|  | ||||
| enum class AmLaunchType { | ||||
|     UserInitiated, | ||||
|     ApplicationInitiated, | ||||
| }; | ||||
|  | ||||
| namespace Core { | ||||
| enum class SystemResultStatus : u32; | ||||
| class System; | ||||
| @@ -101,6 +96,11 @@ namespace InputCommon { | ||||
| class InputSubsystem; | ||||
| } | ||||
|  | ||||
| namespace Service::AM { | ||||
| struct FrontendAppletParameters; | ||||
| enum class AppletId : u32; | ||||
| } // namespace Service::AM | ||||
|  | ||||
| namespace Service::AM::Frontend { | ||||
| enum class SwkbdResult : u32; | ||||
| enum class SwkbdTextCheckResult : u32; | ||||
| @@ -268,11 +268,10 @@ private: | ||||
|     void PreventOSSleep(); | ||||
|     void AllowOSSleep(); | ||||
|  | ||||
|     bool LoadROM(const QString& filename, u64 program_id, std::size_t program_index, | ||||
|                  AmLaunchType launch_type); | ||||
|     void BootGame(const QString& filename, u64 program_id = 0, std::size_t program_index = 0, | ||||
|                   StartGameType with_config = StartGameType::Normal, | ||||
|                   AmLaunchType launch_type = AmLaunchType::UserInitiated); | ||||
|     bool LoadROM(const QString& filename, Service::AM::FrontendAppletParameters params); | ||||
|     void BootGame(const QString& filename, Service::AM::FrontendAppletParameters params, | ||||
|                   StartGameType with_config = StartGameType::Normal); | ||||
|     void BootGameFromList(const QString& filename, StartGameType with_config); | ||||
|     void ShutdownGame(); | ||||
|  | ||||
|     void ShowTelemetryCallout(); | ||||
| @@ -325,6 +324,10 @@ private: | ||||
|     void SetGamemodeEnabled(bool state); | ||||
| #endif | ||||
|  | ||||
|     Service::AM::FrontendAppletParameters ApplicationAppletParameters(); | ||||
|     Service::AM::FrontendAppletParameters LibraryAppletParameters(u64 program_id, | ||||
|                                                                   Service::AM::AppletId applet_id); | ||||
|  | ||||
| private slots: | ||||
|     void OnStartGame(); | ||||
|     void OnRestartGame(); | ||||
|   | ||||
| @@ -26,6 +26,7 @@ | ||||
| #include "core/crypto/key_manager.h" | ||||
| #include "core/file_sys/registered_cache.h" | ||||
| #include "core/file_sys/vfs/vfs_real.h" | ||||
| #include "core/hle/service/am/applet_manager.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| #include "core/loader/loader.h" | ||||
| #include "core/telemetry_session.h" | ||||
| @@ -366,7 +367,10 @@ int main(int argc, char** argv) { | ||||
|     system.GetFileSystemController().CreateFactories(*system.GetFilesystem()); | ||||
|     system.GetUserChannel().clear(); | ||||
|  | ||||
|     const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath)}; | ||||
|     Service::AM::FrontendAppletParameters load_parameters{ | ||||
|         .applet_id = Service::AM::AppletId::Application, | ||||
|     }; | ||||
|     const Core::SystemResultStatus load_result{system.Load(*emu_window, filepath, load_parameters)}; | ||||
|  | ||||
|     switch (load_result) { | ||||
|     case Core::SystemResultStatus::ErrorGetLoader: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user