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