Jelajahi Sumber

am: retrieve main applet creation info from frontend

Liam 2 tahun lalu
induk
melakukan
3155f4e96d

+ 1 - 1
src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt

@@ -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?)

+ 2 - 2
src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt

@@ -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()
                 }

+ 28 - 9
src/android/app/src/main/jni/native.cpp

@@ -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,

+ 4 - 1
src/android/app/src/main/jni/native.h

@@ -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;

+ 30 - 19
src/core/core.cpp

@@ -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 {

+ 7 - 2
src/core/core.h

@@ -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

+ 4 - 8
src/yuzu/game_list.cpp

@@ -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);
     });

+ 1 - 2
src/yuzu/game_list.h

@@ -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);

+ 48 - 24
src/yuzu/main.cpp

@@ -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;

+ 13 - 10
src/yuzu/main.h

@@ -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();

+ 5 - 1
src/yuzu_cmd/yuzu.cpp

@@ -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: