mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-29 18:08:08 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 726f4621ea | |||
| 6069529cec | |||
| bd6e843037 | |||
| fa9a087af7 | |||
| 9e750f7359 | |||
| f283b4ed36 | |||
| cd284033e3 | |||
| 17dccfe052 | |||
| 39af7d4c11 | |||
| 56126d3e2e | |||
| e45257eb86 | |||
| ca7ea96040 | |||
| dba2d68ca2 | |||
| 39db9f9362 | |||
| 71117e0542 | |||
| 301dd07881 | |||
| 261491fa94 | |||
| 8b3d425ca1 |
@@ -1089,6 +1089,8 @@ add_library(core STATIC
|
|||||||
hle/service/ssl/ssl.h
|
hle/service/ssl/ssl.h
|
||||||
hle/service/ssl/ssl_backend.h
|
hle/service/ssl/ssl_backend.h
|
||||||
hle/service/ssl/ssl_types.h
|
hle/service/ssl/ssl_types.h
|
||||||
|
hle/service/ulsf/ulsf.cpp
|
||||||
|
hle/service/ulsf/ulsf.h
|
||||||
hle/service/usb/usb.cpp
|
hle/service/usb/usb.cpp
|
||||||
hle/service/usb/usb.h
|
hle/service/usb/usb.h
|
||||||
hle/service/vi/application_display_service.cpp
|
hle/service/vi/application_display_service.cpp
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ constexpr size_t SlabCountKDeviceAddressSpace = 300;
|
|||||||
constexpr size_t SlabCountKSession = 1133;
|
constexpr size_t SlabCountKSession = 1133;
|
||||||
constexpr size_t SlabCountKLightSession = 100;
|
constexpr size_t SlabCountKLightSession = 100;
|
||||||
constexpr size_t SlabCountKObjectName = 7;
|
constexpr size_t SlabCountKObjectName = 7;
|
||||||
constexpr size_t SlabCountKResourceLimit = 5;
|
// TODO(lizzie): divergence that allows ulauncher to work
|
||||||
|
constexpr size_t SlabCountKResourceLimit = 5 + 1;
|
||||||
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
|
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
|
||||||
constexpr size_t SlabCountKIoPool = 1;
|
constexpr size_t SlabCountKIoPool = 1;
|
||||||
constexpr size_t SlabCountKIoRegion = 6;
|
constexpr size_t SlabCountKIoRegion = 6;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -94,7 +94,9 @@ enum class AppletId : u32 {
|
|||||||
LoginShare = 0x18,
|
LoginShare = 0x18,
|
||||||
WebAuth = 0x19,
|
WebAuth = 0x19,
|
||||||
MyPage = 0x1A,
|
MyPage = 0x1A,
|
||||||
Lhub = 0x35
|
Lhub = 0x35,
|
||||||
|
// Homebrew -- uses same ProgramId as qlaunch
|
||||||
|
UlauncherUmenu = 0xF000'0000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class AppletProgramId : u64 {
|
enum class AppletProgramId : u64 {
|
||||||
|
|||||||
@@ -24,6 +24,20 @@ namespace Service::AM {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr size_t NroPathSize = 512;
|
||||||
|
constexpr size_t NroArgvSize = 2048;
|
||||||
|
constexpr size_t MenuCaptionSize = 1024;
|
||||||
|
struct UloaderTargetInput {
|
||||||
|
u32 magic;
|
||||||
|
bool target_once;
|
||||||
|
bool is_auto_game_recording;
|
||||||
|
std::array<u8, 2> unused;
|
||||||
|
std::array<char, NroPathSize> nro_path;
|
||||||
|
std::array<char, NroArgvSize> nro_argv;
|
||||||
|
std::array<char, MenuCaptionSize> menu_caption;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(UloaderTargetInput) == 3592);
|
||||||
|
|
||||||
constexpr u32 LaunchParameterAccountPreselectedUserMagic = 0xC79497CA;
|
constexpr u32 LaunchParameterAccountPreselectedUserMagic = 0xC79497CA;
|
||||||
|
|
||||||
struct LaunchParameterAccountPreselectedUser {
|
struct LaunchParameterAccountPreselectedUser {
|
||||||
@@ -121,6 +135,44 @@ void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
|
|||||||
channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
|
channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PushInShowUlauncherUmenu(Core::System& system, AppletStorageChannel& channel) {
|
||||||
|
typedef std::array<u64, 2> AccountUid;
|
||||||
|
const CommonArguments common_args = {
|
||||||
|
.arguments_version = CommonArgumentVersion::Version3,
|
||||||
|
.size = CommonArgumentSize::Version3,
|
||||||
|
.library_version = 2,
|
||||||
|
.theme_color = ThemeColor::BasicBlack,
|
||||||
|
.play_startup_sound = true,
|
||||||
|
.system_tick = system.CoreTiming().GetClockTicks(),
|
||||||
|
};
|
||||||
|
struct UmenuInput {
|
||||||
|
AccountUid selected_user;
|
||||||
|
UloaderTargetInput suspended_hb_target_ipt; // Set if homebrew (launched as an application) is currently suspended
|
||||||
|
u64 suspended_app_id; // Set if any normal application is suspended
|
||||||
|
std::array<char, 0x301> last_menu_fs_path; //FS_MAX_PATH
|
||||||
|
std::array<char, 0x301> last_menu_path;
|
||||||
|
u32 last_menu_index;
|
||||||
|
bool reload_theme_cache;
|
||||||
|
bool warned_about_outdated_theme;
|
||||||
|
u32 last_added_app_count;
|
||||||
|
u32 last_deleted_app_count;
|
||||||
|
u32 in_verify_app_count;
|
||||||
|
} user_args = {};
|
||||||
|
static_assert(sizeof(UmenuInput) == 5176);
|
||||||
|
|
||||||
|
auto const user = system.GetProfileManager().GetUser(0);
|
||||||
|
user_args.selected_user[0] = user->uuid[0];
|
||||||
|
user_args.selected_user[1] = user->uuid[1];
|
||||||
|
user_args.warned_about_outdated_theme = true;
|
||||||
|
|
||||||
|
std::vector<u8> common_args_data(sizeof(common_args));
|
||||||
|
std::vector<u8> user_args_data(sizeof(user_args));
|
||||||
|
std::memcpy(common_args_data.data(), std::addressof(common_args), sizeof(common_args));
|
||||||
|
std::memcpy(user_args_data.data(), std::addressof(user_args), sizeof(user_args));
|
||||||
|
channel.Push(std::make_shared<IStorage>(system, std::move(common_args_data)));
|
||||||
|
channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
|
||||||
|
}
|
||||||
|
|
||||||
void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
|
void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
|
||||||
const CommonArguments arguments{
|
const CommonArguments arguments{
|
||||||
.arguments_version = CommonArgumentVersion::Version3,
|
.arguments_version = CommonArgumentVersion::Version3,
|
||||||
@@ -292,8 +344,18 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||||||
applet->previous_program_index = params.previous_program_index;
|
applet->previous_program_index = params.previous_program_index;
|
||||||
|
|
||||||
// Push UserChannel data from previous application
|
// Push UserChannel data from previous application
|
||||||
|
// Or ulaunch initialization where we push parameters willingly!
|
||||||
if (params.launch_type == LaunchType::ApplicationInitiated) {
|
if (params.launch_type == LaunchType::ApplicationInitiated) {
|
||||||
applet->user_channel_launch_parameter.swap(m_system.GetUserChannel());
|
applet->user_channel_launch_parameter.swap(m_system.GetUserChannel());
|
||||||
|
} else if (params.launch_type == LaunchType::FrontendUlaunchInitiated) {
|
||||||
|
UloaderTargetInput target_ipt = {};
|
||||||
|
target_ipt.magic = 0x49444C55; // "ULDI"
|
||||||
|
target_ipt.nro_path = {"sdmc:/hbmenu.nro"};
|
||||||
|
target_ipt.menu_caption = {"Loaded by uLoader v1.2.4 - uLaunch's custom hbloader replacement ;)"};
|
||||||
|
std::vector<u8> v(sizeof(target_ipt));
|
||||||
|
std::memcpy(v.data(), std::addressof(target_ipt), sizeof(target_ipt));
|
||||||
|
applet->user_channel_launch_parameter.clear();
|
||||||
|
applet->user_channel_launch_parameter.push_back(std::move(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Read whether we need a preselected user from NACP?
|
// TODO: Read whether we need a preselected user from NACP?
|
||||||
@@ -335,6 +397,9 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||||||
case AppletId::Controller:
|
case AppletId::Controller:
|
||||||
PushInShowController(m_system, InitializeFakeCallerApplet(m_system, applet));
|
PushInShowController(m_system, InitializeFakeCallerApplet(m_system, applet));
|
||||||
break;
|
break;
|
||||||
|
case AppletId::UlauncherUmenu:
|
||||||
|
PushInShowUlauncherUmenu(m_system, InitializeFakeCallerApplet(m_system, applet));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -342,7 +407,7 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|||||||
// Applet was started by frontend, so it is foreground.
|
// Applet was started by frontend, so it is foreground.
|
||||||
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
||||||
|
|
||||||
if (applet->applet_id == AppletId::QLaunch) {
|
if (applet->applet_id == AppletId::QLaunch || applet->applet_id == AppletId::UlauncherUmenu) {
|
||||||
applet->lifecycle_manager.SetFocusHandlingMode(false);
|
applet->lifecycle_manager.SetFocusHandlingMode(false);
|
||||||
applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false);
|
applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false);
|
||||||
m_window_system->TrackApplet(applet, false);
|
m_window_system->TrackApplet(applet, false);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -26,6 +26,9 @@ class WindowSystem;
|
|||||||
enum class LaunchType {
|
enum class LaunchType {
|
||||||
FrontendInitiated,
|
FrontendInitiated,
|
||||||
ApplicationInitiated,
|
ApplicationInitiated,
|
||||||
|
// Special masquerade for AMS + uLaunch CFW
|
||||||
|
FrontendUlaunchInitiated = 0x800,
|
||||||
|
FrontendUmenuInitiated,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrontendAppletParameters {
|
struct FrontendAppletParameters {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
|||||||
case AppletId::OverlayDisplay:
|
case AppletId::OverlayDisplay:
|
||||||
return AppletProgramId::OverlayDisplay;
|
return AppletProgramId::OverlayDisplay;
|
||||||
case AppletId::QLaunch:
|
case AppletId::QLaunch:
|
||||||
|
case AppletId::UlauncherUmenu: //reuses same id as Qlaunch
|
||||||
return AppletProgramId::QLaunch;
|
return AppletProgramId::QLaunch;
|
||||||
case AppletId::Starter:
|
case AppletId::Starter:
|
||||||
return AppletProgramId::Starter;
|
return AppletProgramId::Starter;
|
||||||
|
|||||||
@@ -8,18 +8,23 @@
|
|||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/am/applet_data_broker.h"
|
#include "core/hle/service/am/applet_data_broker.h"
|
||||||
#include "core/hle/service/am/applet_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/am/process_creation.h"
|
||||||
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
#include "core/hle/service/am/service/library_applet_self_accessor.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
|
#include "core/hle/service/am/window_system.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
#include "core/hle/service/ns/application_manager_interface.h"
|
#include "core/hle/service/ns/application_manager_interface.h"
|
||||||
#include "core/hle/service/ns/service_getter_interface.h"
|
#include "core/hle/service/ns/service_getter_interface.h"
|
||||||
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
@@ -44,8 +49,9 @@ AppletIdentityInfo GetCallerIdentity(Applet& applet) {
|
|||||||
|
|
||||||
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
|
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
|
||||||
std::shared_ptr<Applet> applet)
|
std::shared_ptr<Applet> applet)
|
||||||
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)},
|
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)}
|
||||||
m_broker{m_applet->caller_applet_broker} {
|
, m_broker{m_applet->caller_applet_broker}
|
||||||
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
|
{0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
|
||||||
@@ -96,9 +102,130 @@ Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_st
|
|||||||
R_RETURN(m_broker->GetInData().Pop(out_storage));
|
R_RETURN(m_broker->GetInData().Pop(out_storage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uLauncher emulation
|
||||||
|
static Result UloaderCreateApplication(Core::System& system, u64 program_id, std::shared_ptr<Applet> caller_applet) {
|
||||||
|
// Get the program NCA from storage.
|
||||||
|
auto& storage = system.GetContentProviderUnion();
|
||||||
|
FileSys::VirtualFile nca_raw = storage.GetEntryRaw(program_id, FileSys::ContentRecordType::Program);
|
||||||
|
// Ensure we retrieved a program NCA.
|
||||||
|
R_UNLESS(nca_raw != nullptr, ResultUnknown);
|
||||||
|
std::vector<u8> control;
|
||||||
|
std::unique_ptr<Loader::AppLoader> loader;
|
||||||
|
Loader::ResultStatus result;
|
||||||
|
auto process = CreateApplicationProcess(control, loader, result, system, nca_raw, program_id, 0);
|
||||||
|
R_UNLESS(process != nullptr, ResultUnknown);
|
||||||
|
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
|
||||||
|
applet->program_id = program_id;
|
||||||
|
applet->applet_id = AppletId::Application;
|
||||||
|
applet->type = AppletType::Application;
|
||||||
|
applet->library_applet_mode = LibraryAppletMode::AllForeground;
|
||||||
|
|
||||||
|
applet->caller_applet = caller_applet;
|
||||||
|
applet->caller_applet_broker = std::make_shared<AppletDataBroker>(system);
|
||||||
|
applet->frontend = caller_applet->frontend;
|
||||||
|
caller_applet->child_applets.push_back(applet);
|
||||||
|
|
||||||
|
system.GetAppletManager().GetWindowSystem()->TrackApplet(applet, true);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
|
Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
m_broker->GetOutData().Push(storage);
|
m_broker->GetOutData().Push(storage);
|
||||||
|
|
||||||
|
if (m_applet->applet_id == AppletId::UlauncherUmenu) {
|
||||||
|
enum class SystemMessage : u32 {
|
||||||
|
Invalid,
|
||||||
|
SetSelectedUser,
|
||||||
|
LaunchApplication,
|
||||||
|
ResumeApplication,
|
||||||
|
TerminateApplication,
|
||||||
|
LaunchHomebrewLibraryApplet,
|
||||||
|
LaunchHomebrewApplication,
|
||||||
|
ChooseHomebrew,
|
||||||
|
OpenWebPage,
|
||||||
|
OpenAlbum,
|
||||||
|
RestartMenu,
|
||||||
|
ReloadConfig,
|
||||||
|
UpdateMenuPaths,
|
||||||
|
UpdateMenuIndex,
|
||||||
|
OpenUserPage,
|
||||||
|
OpenMiiEdit,
|
||||||
|
OpenAddUser,
|
||||||
|
OpenNetConnect,
|
||||||
|
ListAddedApplications,
|
||||||
|
ListDeletedApplications,
|
||||||
|
OpenCabinet,
|
||||||
|
StartVerifyApplication,
|
||||||
|
ListInVerifyApplications,
|
||||||
|
NotifyWarnedAboutOutdatedTheme,
|
||||||
|
TerminateMenu,
|
||||||
|
OpenControllerKeyRemapping
|
||||||
|
};
|
||||||
|
struct CommandCommonHeader {
|
||||||
|
u32 magic;
|
||||||
|
u32 val;
|
||||||
|
};
|
||||||
|
std::shared_ptr<IStorage> req_storage;
|
||||||
|
m_broker->GetOutData().Pop(&req_storage);
|
||||||
|
auto req_data = req_storage->GetData();
|
||||||
|
CommandCommonHeader req_cmd{};
|
||||||
|
std::memcpy(&req_cmd, req_data.data(), sizeof(req_cmd));
|
||||||
|
|
||||||
|
LOG_WARNING(Service_AM, "uLauncher:IPC {}, {}", req_cmd.magic, req_cmd.val);
|
||||||
|
switch (SystemMessage(req_cmd.val)) {
|
||||||
|
case SystemMessage::SetSelectedUser:
|
||||||
|
break;
|
||||||
|
case SystemMessage::LaunchApplication: {
|
||||||
|
// all applet proxies OpenSystemAppletProxy
|
||||||
|
// applet proxy GetApplicationCreator
|
||||||
|
// application creator CreateApplication
|
||||||
|
u64 args_value{};
|
||||||
|
std::memcpy(std::addressof(args_value), req_data.data() + sizeof(req_cmd), sizeof(args_value));
|
||||||
|
LOG_WARNING(Service_AM, "program_id={:016x}", args_value);
|
||||||
|
UloaderCreateApplication(system, args_value, m_applet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SystemMessage::ResumeApplication:
|
||||||
|
case SystemMessage::TerminateApplication:
|
||||||
|
case SystemMessage::LaunchHomebrewLibraryApplet:
|
||||||
|
case SystemMessage::LaunchHomebrewApplication:
|
||||||
|
case SystemMessage::ChooseHomebrew:
|
||||||
|
case SystemMessage::OpenWebPage:
|
||||||
|
case SystemMessage::OpenAlbum:
|
||||||
|
case SystemMessage::RestartMenu:
|
||||||
|
case SystemMessage::ReloadConfig:
|
||||||
|
case SystemMessage::UpdateMenuPaths:
|
||||||
|
case SystemMessage::UpdateMenuIndex:
|
||||||
|
case SystemMessage::OpenUserPage:
|
||||||
|
case SystemMessage::OpenMiiEdit:
|
||||||
|
case SystemMessage::OpenAddUser:
|
||||||
|
case SystemMessage::OpenNetConnect:
|
||||||
|
case SystemMessage::ListAddedApplications:
|
||||||
|
case SystemMessage::ListDeletedApplications:
|
||||||
|
case SystemMessage::OpenCabinet:
|
||||||
|
case SystemMessage::StartVerifyApplication:
|
||||||
|
case SystemMessage::ListInVerifyApplications:
|
||||||
|
case SystemMessage::NotifyWarnedAboutOutdatedTheme:
|
||||||
|
break;
|
||||||
|
case SystemMessage::TerminateMenu:
|
||||||
|
system.GetUserChannel() = m_applet->user_channel_launch_parameter;
|
||||||
|
system.ExecuteProgram(0);
|
||||||
|
break;
|
||||||
|
case SystemMessage::OpenControllerKeyRemapping:
|
||||||
|
break;
|
||||||
|
case SystemMessage::Invalid:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandCommonHeader res_cmd{};
|
||||||
|
std::vector<u8> res_data(0x8000);
|
||||||
|
res_cmd.magic = 0x21494D53;
|
||||||
|
res_cmd.val = u32(ResultSuccess.raw);
|
||||||
|
std::memcpy(res_data.data(), &res_cmd, sizeof(res_cmd));
|
||||||
|
m_broker->GetInData().Push(std::make_shared<IStorage>(system, std::move(res_data)));
|
||||||
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void WindowSystem::Update() {
|
|||||||
void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) {
|
void WindowSystem::TrackApplet(std::shared_ptr<Applet> applet, bool is_application) {
|
||||||
std::scoped_lock lk{m_lock};
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
if (applet->applet_id == AppletId::QLaunch) {
|
if (applet->applet_id == AppletId::QLaunch || applet->applet_id == AppletId::UlauncherUmenu) {
|
||||||
ASSERT(m_home_menu == nullptr);
|
ASSERT(m_home_menu == nullptr);
|
||||||
m_home_menu = applet.get();
|
m_home_menu = applet.get();
|
||||||
} else if (applet->applet_id == AppletId::OverlayDisplay) {
|
} else if (applet->applet_id == AppletId::OverlayDisplay) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ IBtmSystemCore::IBtmSystemCore(Core::System& system_)
|
|||||||
{10, nullptr, "StartAudioDeviceDiscovery"},
|
{10, nullptr, "StartAudioDeviceDiscovery"},
|
||||||
{11, nullptr, "StopAudioDeviceDiscovery"},
|
{11, nullptr, "StopAudioDeviceDiscovery"},
|
||||||
{12, nullptr, "IsDiscoveryingAudioDevice"},
|
{12, nullptr, "IsDiscoveryingAudioDevice"},
|
||||||
{13, nullptr, "GetDiscoveredAudioDevice"},
|
{13, C<&IBtmSystemCore::GetDiscoveredAudioDevice>, "GetDiscoveredAudioDevice"},
|
||||||
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
|
{14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"},
|
||||||
{15, nullptr, "ConnectAudioDevice"},
|
{15, nullptr, "ConnectAudioDevice"},
|
||||||
{16, nullptr, "IsConnectingAudioDevice"},
|
{16, nullptr, "IsConnectingAudioDevice"},
|
||||||
@@ -93,6 +93,11 @@ Result IBtmSystemCore::AcquireRadioEvent(Out<bool> out_is_valid,
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result IBtmSystemCore::GetDiscoveredAudioDevice(OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out<s32> out_total) {
|
||||||
|
LOG_WARNING(Service_BTM, "(STUBBED) called");
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
|
Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent(
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_WARNING(Service_BTM, "(STUBBED) called");
|
LOG_WARNING(Service_BTM, "(STUBBED) called");
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
@@ -34,9 +37,8 @@ private:
|
|||||||
Result DisableRadio();
|
Result DisableRadio();
|
||||||
Result IsRadioEnabled(Out<bool> out_is_enabled);
|
Result IsRadioEnabled(Out<bool> out_is_enabled);
|
||||||
|
|
||||||
Result AcquireRadioEvent(Out<bool> out_is_valid,
|
Result AcquireRadioEvent(Out<bool> out_is_valid, OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result GetDiscoveredAudioDevice(OutArray<std::array<u8, 0xFF>, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out<s32> out_total);
|
||||||
|
|
||||||
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result AcquireAudioDeviceConnectionEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
|
|
||||||
Result GetConnectedAudioDevices(
|
Result GetConnectedAudioDevices(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
#include "core/hle/service/sockets/sockets.h"
|
#include "core/hle/service/sockets/sockets.h"
|
||||||
#include "core/hle/service/spl/spl_module.h"
|
#include "core/hle/service/spl/spl_module.h"
|
||||||
#include "core/hle/service/ssl/ssl.h"
|
#include "core/hle/service/ssl/ssl.h"
|
||||||
|
#include "core/hle/service/ulsf/ulsf.h"
|
||||||
#include "core/hle/service/usb/usb.h"
|
#include "core/hle/service/usb/usb.h"
|
||||||
#include "core/hle/service/vi/vi.h"
|
#include "core/hle/service/vi/vi.h"
|
||||||
|
|
||||||
@@ -144,7 +145,8 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
|||||||
{"ro", &RO::LoopProcess},
|
{"ro", &RO::LoopProcess},
|
||||||
{"spl", &SPL::LoopProcess},
|
{"spl", &SPL::LoopProcess},
|
||||||
{"ssl", &SSL::LoopProcess},
|
{"ssl", &SSL::LoopProcess},
|
||||||
{"usb", &USB::LoopProcess}
|
{"usb", &USB::LoopProcess},
|
||||||
|
{"ulsf", &ULSF::LoopProcess},
|
||||||
})
|
})
|
||||||
kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); });
|
kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,10 +142,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
|
|||||||
{22, C<&ISystemSettingsServer::SetEulaVersions>, "SetEulaVersions"},
|
{22, C<&ISystemSettingsServer::SetEulaVersions>, "SetEulaVersions"},
|
||||||
{23, C<&ISystemSettingsServer::GetColorSetId>, "GetColorSetId"},
|
{23, C<&ISystemSettingsServer::GetColorSetId>, "GetColorSetId"},
|
||||||
{24, C<&ISystemSettingsServer::SetColorSetId>, "SetColorSetId"},
|
{24, C<&ISystemSettingsServer::SetColorSetId>, "SetColorSetId"},
|
||||||
{25, nullptr, "GetConsoleInformationUploadFlag"},
|
{25, C<&ISystemSettingsServer::GetConsoleInformationUploadFlag>, "GetConsoleInformationUploadFlag"},
|
||||||
{26, nullptr, "SetConsoleInformationUploadFlag"},
|
{26, C<&ISystemSettingsServer::SetConsoleInformationUploadFlag>, "SetConsoleInformationUploadFlag"},
|
||||||
{27, nullptr, "GetAutomaticApplicationDownloadFlag"},
|
{27, C<&ISystemSettingsServer::GetAutomaticApplicationDownloadFlag>, "GetAutomaticApplicationDownloadFlag"},
|
||||||
{28, nullptr, "SetAutomaticApplicationDownloadFlag"},
|
{28, C<&ISystemSettingsServer::SetAutomaticApplicationDownloadFlag>, "SetAutomaticApplicationDownloadFlag"},
|
||||||
{29, C<&ISystemSettingsServer::GetNotificationSettings>, "GetNotificationSettings"},
|
{29, C<&ISystemSettingsServer::GetNotificationSettings>, "GetNotificationSettings"},
|
||||||
{30, C<&ISystemSettingsServer::SetNotificationSettings>, "SetNotificationSettings"},
|
{30, C<&ISystemSettingsServer::SetNotificationSettings>, "SetNotificationSettings"},
|
||||||
{31, C<&ISystemSettingsServer::GetAccountNotificationSettings>, "GetAccountNotificationSettings"},
|
{31, C<&ISystemSettingsServer::GetAccountNotificationSettings>, "GetAccountNotificationSettings"},
|
||||||
@@ -160,8 +160,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
|
|||||||
{42, nullptr, "SetEdid"},
|
{42, nullptr, "SetEdid"},
|
||||||
{43, C<&ISystemSettingsServer::GetAudioOutputMode>, "GetAudioOutputMode"},
|
{43, C<&ISystemSettingsServer::GetAudioOutputMode>, "GetAudioOutputMode"},
|
||||||
{44, C<&ISystemSettingsServer::SetAudioOutputMode>, "SetAudioOutputMode"},
|
{44, C<&ISystemSettingsServer::SetAudioOutputMode>, "SetAudioOutputMode"},
|
||||||
{45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag> , "GetSpeakerAutoMuteFlag"},
|
{45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag>, "GetSpeakerAutoMuteFlag"},
|
||||||
{46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag> , "SetSpeakerAutoMuteFlag"},
|
{46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag>, "SetSpeakerAutoMuteFlag"},
|
||||||
{47, C<&ISystemSettingsServer::GetQuestFlag>, "GetQuestFlag"},
|
{47, C<&ISystemSettingsServer::GetQuestFlag>, "GetQuestFlag"},
|
||||||
{48, C<&ISystemSettingsServer::SetQuestFlag>, "SetQuestFlag"},
|
{48, C<&ISystemSettingsServer::SetQuestFlag>, "SetQuestFlag"},
|
||||||
{49, nullptr, "GetDataDeletionSettings"},
|
{49, nullptr, "GetDataDeletionSettings"},
|
||||||
@@ -180,8 +180,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
|
|||||||
{62, C<&ISystemSettingsServer::GetDebugModeFlag>, "GetDebugModeFlag"},
|
{62, C<&ISystemSettingsServer::GetDebugModeFlag>, "GetDebugModeFlag"},
|
||||||
{63, C<&ISystemSettingsServer::GetPrimaryAlbumStorage>, "GetPrimaryAlbumStorage"},
|
{63, C<&ISystemSettingsServer::GetPrimaryAlbumStorage>, "GetPrimaryAlbumStorage"},
|
||||||
{64, C<&ISystemSettingsServer::SetPrimaryAlbumStorage>, "SetPrimaryAlbumStorage"},
|
{64, C<&ISystemSettingsServer::SetPrimaryAlbumStorage>, "SetPrimaryAlbumStorage"},
|
||||||
{65, nullptr, "GetUsb30EnableFlag"},
|
{65, C<&ISystemSettingsServer::GetUsb30EnableFlag>, "GetUsb30EnableFlag"},
|
||||||
{66, nullptr, "SetUsb30EnableFlag"},
|
{66, C<&ISystemSettingsServer::SetUsb30EnableFlag>, "SetUsb30EnableFlag"},
|
||||||
{67, C<&ISystemSettingsServer::GetBatteryLot>, "GetBatteryLot"},
|
{67, C<&ISystemSettingsServer::GetBatteryLot>, "GetBatteryLot"},
|
||||||
{68, C<&ISystemSettingsServer::GetSerialNumber>, "GetSerialNumber"},
|
{68, C<&ISystemSettingsServer::GetSerialNumber>, "GetSerialNumber"},
|
||||||
{69, C<&ISystemSettingsServer::GetNfcEnableFlag>, "GetNfcEnableFlag"},
|
{69, C<&ISystemSettingsServer::GetNfcEnableFlag>, "GetNfcEnableFlag"},
|
||||||
@@ -1074,6 +1074,45 @@ Result ISystemSettingsServer::SetNfcEnableFlag(bool nfc_enable_flag) {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ISystemSettingsServer::GetConsoleInformationUploadFlag(Out<bool> out_flag) {
|
||||||
|
LOG_INFO(Service_SET, "called {}", m_system_settings.console_information_upload_flag);
|
||||||
|
*out_flag = m_system_settings.console_information_upload_flag;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemSettingsServer::SetConsoleInformationUploadFlag(bool flag) {
|
||||||
|
LOG_INFO(Service_SET, "called {}", flag);
|
||||||
|
m_system_settings.usb_30_enable_flag = flag;
|
||||||
|
SetSaveNeeded();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemSettingsServer::GetAutomaticApplicationDownloadFlag(Out<bool> out_flag) {
|
||||||
|
LOG_INFO(Service_SET, "called {}", m_system_settings.usb_30_enable_flag);
|
||||||
|
*out_flag = m_system_settings.automatic_application_download_flag;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemSettingsServer::SetAutomaticApplicationDownloadFlag(bool flag) {
|
||||||
|
LOG_INFO(Service_SET, "called {}", flag);
|
||||||
|
m_system_settings.automatic_application_download_flag = flag;
|
||||||
|
SetSaveNeeded();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemSettingsServer::GetUsb30EnableFlag(Out<bool> out_usb30_enable_flag) {
|
||||||
|
LOG_INFO(Service_SET, "called, usb30_enable_flag={}", m_system_settings.usb_30_enable_flag);
|
||||||
|
*out_usb30_enable_flag = m_system_settings.usb_30_enable_flag;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemSettingsServer::SetUsb30EnableFlag(bool usb30_enable_flag) {
|
||||||
|
LOG_INFO(Service_SET, "called, usb30_enable_flag={}", usb30_enable_flag);
|
||||||
|
m_system_settings.usb_30_enable_flag = usb30_enable_flag;
|
||||||
|
SetSaveNeeded();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
Result ISystemSettingsServer::GetSleepSettings(Out<SleepSettings> out_sleep_settings) {
|
Result ISystemSettingsServer::GetSleepSettings(Out<SleepSettings> out_sleep_settings) {
|
||||||
LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}",
|
LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}",
|
||||||
m_system_settings.sleep_settings.flags.raw,
|
m_system_settings.sleep_settings.flags.raw,
|
||||||
|
|||||||
@@ -109,6 +109,12 @@ public:
|
|||||||
Result SetPrimaryAlbumStorage(PrimaryAlbumStorage primary_album_storage);
|
Result SetPrimaryAlbumStorage(PrimaryAlbumStorage primary_album_storage);
|
||||||
Result GetBatteryLot(Out<BatteryLot> out_battery_lot);
|
Result GetBatteryLot(Out<BatteryLot> out_battery_lot);
|
||||||
Result GetSerialNumber(Out<SerialNumber> out_console_serial);
|
Result GetSerialNumber(Out<SerialNumber> out_console_serial);
|
||||||
|
Result GetConsoleInformationUploadFlag(Out<bool> out_flag);
|
||||||
|
Result SetConsoleInformationUploadFlag(bool flag);
|
||||||
|
Result GetAutomaticApplicationDownloadFlag(Out<bool> out_flag);
|
||||||
|
Result SetAutomaticApplicationDownloadFlag(bool flag);
|
||||||
|
Result GetUsb30EnableFlag(Out<bool> out_usb30_enable_flag);
|
||||||
|
Result SetUsb30EnableFlag(bool usb30_enable_flag);
|
||||||
Result GetNfcEnableFlag(Out<bool> out_nfc_enable_flag);
|
Result GetNfcEnableFlag(Out<bool> out_nfc_enable_flag);
|
||||||
Result SetNfcEnableFlag(bool nfc_enable_flag);
|
Result SetNfcEnableFlag(bool nfc_enable_flag);
|
||||||
Result GetSleepSettings(Out<SleepSettings> out_sleep_settings);
|
Result GetSleepSettings(Out<SleepSettings> out_sleep_settings);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -11,6 +14,7 @@
|
|||||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||||
#include "core/hle/kernel/k_server_port.h"
|
#include "core/hle/kernel/k_server_port.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
@@ -250,15 +254,37 @@ void SM::UnregisterService(HLERequestContext& ctx) {
|
|||||||
rb.Push(service_manager.UnregisterService(name));
|
rb.Push(service_manager.UnregisterService(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SM::AtmosphereHasService(HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
std::string name(PopServiceName(rp));
|
||||||
|
LOG_WARNING(Service_SM, "(stubbed) called with name={}", name);
|
||||||
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
|
Kernel::KClientPort* out_client_port = nullptr;
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.Push<bool>(service_manager.GetServicePort(&out_client_port, name) == ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
||||||
: ServiceFramework{system_, "sm:", 4},
|
: ServiceFramework{system_, "sm:", 4}
|
||||||
service_manager{service_manager_}, kernel{system_.Kernel()} {
|
, service_manager{service_manager_}
|
||||||
|
, kernel{system_.Kernel()}
|
||||||
|
{
|
||||||
RegisterHandlers({
|
RegisterHandlers({
|
||||||
{0, &SM::Initialize, "Initialize"},
|
{0, &SM::Initialize, "Initialize"},
|
||||||
{1, &SM::GetServiceCmif, "GetService"},
|
{1, &SM::GetServiceCmif, "GetService"},
|
||||||
{2, &SM::RegisterServiceCmif, "RegisterService"},
|
{2, &SM::RegisterServiceCmif, "RegisterService"},
|
||||||
{3, &SM::UnregisterService, "UnregisterService"},
|
{3, &SM::UnregisterService, "UnregisterService"},
|
||||||
{4, nullptr, "DetachClient"},
|
{4, nullptr, "DetachClient"},
|
||||||
|
// TODO: are these non-TIPC as well?
|
||||||
|
{65000, nullptr, "AtmosphereInstallMitm"},
|
||||||
|
{65001, nullptr, "AtmosphereUninstallMitm"},
|
||||||
|
{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
|
||||||
|
{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
|
||||||
|
{65004, nullptr, "AtmosphereHasMitm"},
|
||||||
|
{65005, nullptr, "AtmosphereWaitMitm"},
|
||||||
|
{65006, nullptr, "AtmosphereDeclareFutureMitm"},
|
||||||
|
{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
|
||||||
|
{65101, nullptr, "AtmosphereWaitService"},
|
||||||
});
|
});
|
||||||
RegisterHandlersTipc({
|
RegisterHandlersTipc({
|
||||||
{0, &SM::Initialize, "Initialize"},
|
{0, &SM::Initialize, "Initialize"},
|
||||||
@@ -266,6 +292,15 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
|
|||||||
{2, &SM::RegisterServiceTipc, "RegisterService"},
|
{2, &SM::RegisterServiceTipc, "RegisterService"},
|
||||||
{3, &SM::UnregisterService, "UnregisterService"},
|
{3, &SM::UnregisterService, "UnregisterService"},
|
||||||
{4, nullptr, "DetachClient"},
|
{4, nullptr, "DetachClient"},
|
||||||
|
{65000, nullptr, "AtmosphereInstallMitm"},
|
||||||
|
{65001, nullptr, "AtmosphereUninstallMitm"},
|
||||||
|
{65002, nullptr, "Deprecated_AtmosphereAssociatePidTidForMitm"},
|
||||||
|
{65003, nullptr, "AtmosphereAcknowledgeMitmSession"},
|
||||||
|
{65004, nullptr, "AtmosphereHasMitm"},
|
||||||
|
{65005, nullptr, "AtmosphereWaitMitm"},
|
||||||
|
{65006, nullptr, "AtmosphereDeclareFutureMitm"},
|
||||||
|
{65100, &SM::AtmosphereHasService, "AtmosphereHasService"},
|
||||||
|
{65101, nullptr, "AtmosphereWaitService"},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ private:
|
|||||||
void RegisterServiceCmif(HLERequestContext& ctx);
|
void RegisterServiceCmif(HLERequestContext& ctx);
|
||||||
void RegisterServiceTipc(HLERequestContext& ctx);
|
void RegisterServiceTipc(HLERequestContext& ctx);
|
||||||
void UnregisterService(HLERequestContext& ctx);
|
void UnregisterService(HLERequestContext& ctx);
|
||||||
|
void AtmosphereHasService(HLERequestContext& ctx);
|
||||||
|
|
||||||
Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
|
Result GetServiceImpl(Kernel::KClientSession** out_client_session, HLERequestContext& ctx);
|
||||||
void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,
|
void RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_session_count,
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
#include "core/hle/service/ulsf/ulsf.h"
|
||||||
|
#include "core/hle/service/server_manager.h"
|
||||||
|
|
||||||
|
namespace Service::ULSF {
|
||||||
|
|
||||||
|
ULSF_U::ULSF_U(Core::System& system_) : ServiceFramework{system_, "ulsf:u"} {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &ULSF_U::GetVersion, "GetVersion"},
|
||||||
|
};
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
ULSF_U::~ULSF_U() = default;
|
||||||
|
|
||||||
|
// Result ULSF_U::GetVersion(Out<ULauncherVersion> out_version) {
|
||||||
|
// LOG_WARNING(Service_SM, "(stubbed)");
|
||||||
|
// *out_version = {};
|
||||||
|
// R_SUCCEED();
|
||||||
|
// }
|
||||||
|
|
||||||
|
void ULSF_U::GetVersion(HLERequestContext& ctx) {
|
||||||
|
LOG_WARNING(Service_SM, "(stubbed)");
|
||||||
|
ULauncherVersion version{1, 6, 7};
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.PushRaw(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class MenuMessage : u32 {
|
||||||
|
Invalid,
|
||||||
|
HomeRequest,
|
||||||
|
SdCardEjected,
|
||||||
|
GameCardMountFailure,
|
||||||
|
PreviousLaunchFailure,
|
||||||
|
ChosenHomebrew,
|
||||||
|
FinishedSleep,
|
||||||
|
ApplicationRecordsChanged,
|
||||||
|
ApplicationVerifyProgress,
|
||||||
|
ApplicationVerifyResult
|
||||||
|
};
|
||||||
|
struct MenuMessageContext {
|
||||||
|
MenuMessage msg;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
Result mount_rc;
|
||||||
|
} gc_mount_failure;
|
||||||
|
struct {
|
||||||
|
char nro_path[0x301];
|
||||||
|
} chosen_hb;
|
||||||
|
struct {
|
||||||
|
bool records_added_or_deleted;
|
||||||
|
} app_records_changed;
|
||||||
|
struct {
|
||||||
|
u64 app_id;
|
||||||
|
u64 done;
|
||||||
|
u64 total;
|
||||||
|
} app_verify_progress;
|
||||||
|
struct {
|
||||||
|
u64 app_id;
|
||||||
|
Result rc;
|
||||||
|
Result detail_rc;
|
||||||
|
} app_verify_rc;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ULSF_P final : public ServiceFramework<ULSF_P> {
|
||||||
|
public:
|
||||||
|
explicit ULSF_P(Core::System& system_) : ServiceFramework{system_, "ulsf:p"} {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, C<&ULSF_P::Initialize>, "Initialize"},
|
||||||
|
{1, C<&ULSF_P::TryPopMessageContext>, "TryPopMessageContext"},
|
||||||
|
};
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
~ULSF_P() = default;
|
||||||
|
|
||||||
|
Result Initialize(u64 pid) {
|
||||||
|
LOG_WARNING(Service_SM, "(stubbed) pid={}", pid);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
Result TryPopMessageContext(OutLargeData<MenuMessageContext, BufferAttr_HipcMapAlias> out_menu_message) {
|
||||||
|
//LOG_WARNING(Service_SM, "(stubbed)");
|
||||||
|
// *out_menu_message = {};
|
||||||
|
// R_SUCCEED();
|
||||||
|
R_THROW(Kernel::ResultInvalidAddress);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AVM final : public ServiceFramework<AVM> {
|
||||||
|
public:
|
||||||
|
explicit AVM(Core::System& system_): ServiceFramework{system_, "avm"} {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &AVM::Cmd0, "Cmd0"},
|
||||||
|
};
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
~AVM() = default;
|
||||||
|
void Cmd0(HLERequestContext& ctx) {
|
||||||
|
LOG_WARNING(Service_SM, "(stubbed)");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class WLAN final : public ServiceFramework<WLAN> {
|
||||||
|
public:
|
||||||
|
explicit WLAN(Core::System& system_): ServiceFramework{system_, "wlan"} {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &WLAN::Cmd0, "Cmd0"},
|
||||||
|
};
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
~WLAN() = default;
|
||||||
|
void Cmd0(HLERequestContext& ctx) {
|
||||||
|
LOG_WARNING(Service_SM, "(stubbed)");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void LoopProcess(Core::System& system) {
|
||||||
|
auto server_manager = std::make_unique<ServerManager>(system);
|
||||||
|
server_manager->RegisterNamedService("ulsf:u", std::make_shared<ULSF_U>(system));
|
||||||
|
server_manager->RegisterNamedService("ulsf:p", std::make_shared<ULSF_P>(system));
|
||||||
|
|
||||||
|
server_manager->RegisterNamedService("avm", std::make_shared<AVM>(system));
|
||||||
|
server_manager->RegisterNamedService("wlan", std::make_shared<WLAN>(system));
|
||||||
|
ServerManager::RunServer(std::move(server_manager));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Service::ULSF {
|
||||||
|
|
||||||
|
struct ULauncherVersion {
|
||||||
|
u8 major;
|
||||||
|
u8 minor;
|
||||||
|
u8 micro;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ULSF_U final : public ServiceFramework<ULSF_U> {
|
||||||
|
public:
|
||||||
|
explicit ULSF_U(Core::System& system_);
|
||||||
|
~ULSF_U();
|
||||||
|
//Result GetVersion(Out<ULauncherVersion> out_version);
|
||||||
|
void GetVersion(HLERequestContext& ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
void LoopProcess(Core::System& system);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "core/file_sys/content_archive.h"
|
#include "core/file_sys/content_archive.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
#include "core/file_sys/program_metadata.h"
|
||||||
#include "core/file_sys/romfs_factory.h"
|
#include "core/file_sys/romfs_factory.h"
|
||||||
#include "core/hle/kernel/k_page_table.h"
|
#include "core/hle/kernel/k_page_table.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
@@ -204,7 +205,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
|||||||
|
|
||||||
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
||||||
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
||||||
process, system, *module_file, code_size, should_pass_arguments, false, {},
|
process, system, *module_file, code_size, should_pass_arguments, false, nullptr, metadata, {},
|
||||||
patch_ctx.GetPatchers(), patch_ctx.GetLastIndex());
|
patch_ctx.GetPatchers(), patch_ctx.GetLastIndex());
|
||||||
if (!tentative_next_load_addr) {
|
if (!tentative_next_load_addr) {
|
||||||
return {ResultStatus::ErrorLoadingNSO, {}};
|
return {ResultStatus::ErrorLoadingNSO, {}};
|
||||||
@@ -251,8 +252,9 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
|||||||
|
|
||||||
const VAddr load_addr{next_load_addr};
|
const VAddr load_addr{next_load_addr};
|
||||||
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
const bool should_pass_arguments = std::strcmp(module, "rtld") == 0;
|
||||||
|
FileSys::ProgramMetadata tmp_metadata{};
|
||||||
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
const auto tentative_next_load_addr = AppLoader_NSO::LoadModule(
|
||||||
process, system, *module_file, load_addr, should_pass_arguments, true, pm,
|
process, system, *module_file, load_addr, should_pass_arguments, true, nullptr, metadata, pm,
|
||||||
patch_ctx.GetPatchers(), patch_ctx.GetIndex(i));
|
patch_ctx.GetPatchers(), patch_ctx.GetIndex(i));
|
||||||
if (!tentative_next_load_addr) {
|
if (!tentative_next_load_addr) {
|
||||||
return {ResultStatus::ErrorLoadingNSO, {}};
|
return {ResultStatus::ErrorLoadingNSO, {}};
|
||||||
|
|||||||
+50
-8
@@ -17,10 +17,14 @@
|
|||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
#include "core/file_sys/romfs_factory.h"
|
||||||
|
#include "core/file_sys/vfs/vfs_types.h"
|
||||||
#include "core/hle/kernel/code_set.h"
|
#include "core/hle/kernel/code_set.h"
|
||||||
#include "core/hle/kernel/k_page_table.h"
|
#include "core/hle/kernel/k_page_table.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
#include "core/loader/nso.h"
|
#include "core/loader/nso.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
@@ -66,7 +70,7 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) {
|
|||||||
return FileType::NSO;
|
return FileType::NSO;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional<FileSys::PatchManager> pm, std::vector<Core::NCE::Patcher>* patches, s32 patch_index) {
|
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, const VAddr load_base, const bool should_pass_arguments, const bool load_into_process, VAddr* out_load_base, FileSys::ProgramMetadata metadata, std::optional<FileSys::PatchManager> pm, std::vector<Core::NCE::Patcher>* patches, s32 patch_index) {
|
||||||
if (nso_file.GetSize() < sizeof(NSOHeader))
|
if (nso_file.GetSize() < sizeof(NSOHeader))
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
NSOHeader nso_header{};
|
NSOHeader nso_header{};
|
||||||
@@ -216,9 +220,19 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool is_hbl = true;
|
||||||
|
if (process
|
||||||
|
.LoadFromMetadata(metadata, image_size, 0, 0, is_hbl)
|
||||||
|
.IsError()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const new_load_base = process.GetEntryPoint().GetValue();
|
||||||
|
if (out_load_base)
|
||||||
|
*out_load_base = new_load_base; // no change
|
||||||
// Load codeset for current process
|
// Load codeset for current process
|
||||||
process.LoadModule(std::move(codeset), load_base);
|
process.LoadModule(std::move(codeset), new_load_base);
|
||||||
return load_base + image_size;
|
return new_load_base + image_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::System& system) {
|
AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::System& system) {
|
||||||
@@ -226,20 +240,34 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
|
|||||||
return {ResultStatus::ErrorAlreadyLoaded, {}};
|
return {ResultStatus::ErrorAlreadyLoaded, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
modules.clear();
|
FileSys::VirtualFile npdm_file{};
|
||||||
|
metadata = FileSys::ProgramMetadata::GetDefault();
|
||||||
|
if (auto const dir = file->GetContainingDirectory()) {
|
||||||
|
npdm_file = dir->GetFile("main.npdm");
|
||||||
|
if (npdm_file) {
|
||||||
|
metadata.Load(npdm_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modules.clear();
|
||||||
// Load module
|
// Load module
|
||||||
const VAddr base_address = GetInteger(process.GetEntryPoint());
|
VAddr base_address = GetInteger(process.GetEntryPoint());
|
||||||
if (!LoadModule(process, system, *file, base_address, true, true)) {
|
if (!LoadModule(process, system, *file, base_address, true, true, &base_address, metadata)) {
|
||||||
return {ResultStatus::ErrorLoadingNSO, {}};
|
return {ResultStatus::ErrorLoadingNSO, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
modules.insert_or_assign(base_address, file->GetName());
|
modules.insert_or_assign(base_address, file->GetName());
|
||||||
LOG_DEBUG(Loader, "loaded module {} @ {:#X}", file->GetName(), base_address);
|
LOG_DEBUG(Loader, "loaded module {} @ {:#X}", file->GetName(), base_address);
|
||||||
|
|
||||||
|
if (npdm_file) {
|
||||||
|
LOG_WARNING(Loader, "creating associated rom-fs factories for likely standalone NSO");
|
||||||
|
u64 program_id{};
|
||||||
|
ReadProgramId(program_id);
|
||||||
|
system.GetFileSystemController().RegisterProcess(process.GetProcessId(), program_id, std::make_unique<FileSys::RomFSFactory>(*this, system.GetContentProvider(), system.GetFileSystemController()));
|
||||||
|
}
|
||||||
|
|
||||||
is_loaded = true;
|
is_loaded = true;
|
||||||
return {ResultStatus::Success, LoadParameters{Kernel::KThread::DefaultThreadPriority,
|
return {ResultStatus::Success, LoadParameters{Kernel::KThread::DefaultThreadPriority, Core::Memory::DEFAULT_STACK_SIZE}};
|
||||||
Core::Memory::DEFAULT_STACK_SIZE}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) {
|
ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) {
|
||||||
@@ -247,4 +275,18 @@ ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) {
|
|||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultStatus AppLoader_NSO::ReadProgramId(u64& out_program_id) {
|
||||||
|
if (metadata.GetTitleID() == 0)
|
||||||
|
return ResultStatus::ErrorNoControl;
|
||||||
|
out_program_id = metadata.GetTitleID();
|
||||||
|
return ResultStatus::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultStatus AppLoader_NSO::ReadTitle(std::string& out_title) {
|
||||||
|
auto const raw_name = metadata.GetName();
|
||||||
|
out_title.resize(raw_name.size());
|
||||||
|
std::memcpy(out_title.data(), raw_name.data(), raw_name.size());
|
||||||
|
return ResultStatus::Success;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Loader
|
} // namespace Loader
|
||||||
|
|||||||
+11
-5
@@ -1,3 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -9,6 +12,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
#include "core/file_sys/program_metadata.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -90,18 +94,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<VAddr> LoadModule(Kernel::KProcess& process, Core::System& system,
|
static std::optional<VAddr> LoadModule(Kernel::KProcess& process, Core::System& system,
|
||||||
const FileSys::VfsFile& nso_file, VAddr load_base,
|
const FileSys::VfsFile& nso_file, const VAddr load_base,
|
||||||
bool should_pass_arguments, bool load_into_process,
|
const bool should_pass_arguments, const bool load_into_process, VAddr* out_load_base,
|
||||||
std::optional<FileSys::PatchManager> pm = {},
|
FileSys::ProgramMetadata metadata,
|
||||||
std::vector<Core::NCE::Patcher>* patches = nullptr,
|
std::optional<FileSys::PatchManager> pm = {}, std::vector<Core::NCE::Patcher>* patches = nullptr, s32 patch_index = -1);
|
||||||
s32 patch_index = -1);
|
|
||||||
|
|
||||||
LoadResult Load(Kernel::KProcess& process, Core::System& system) override;
|
LoadResult Load(Kernel::KProcess& process, Core::System& system) override;
|
||||||
|
|
||||||
ResultStatus ReadNSOModules(Modules& out_modules) override;
|
ResultStatus ReadNSOModules(Modules& out_modules) override;
|
||||||
|
ResultStatus ReadProgramId(u64& out_program_id) override;
|
||||||
|
ResultStatus ReadTitle(std::string& title) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Modules modules;
|
Modules modules;
|
||||||
|
FileSys::ProgramMetadata metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Loader
|
} // namespace Loader
|
||||||
|
|||||||
@@ -512,11 +512,12 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString game_path;
|
QString game_path{};
|
||||||
bool should_launch_qlaunch = false;
|
bool should_launch_qlaunch = false;
|
||||||
bool should_launch_hlaunch = false;
|
bool should_launch_hlaunch = false;
|
||||||
|
bool should_launch_hlaunch_uloader = false;
|
||||||
|
bool should_launch_ulaunch = false;
|
||||||
bool should_launch_setup = false;
|
bool should_launch_setup = false;
|
||||||
bool has_gamepath = false;
|
|
||||||
bool is_fullscreen = false;
|
bool is_fullscreen = false;
|
||||||
|
|
||||||
// Preserves drag/drop functionality
|
// Preserves drag/drop functionality
|
||||||
@@ -550,7 +551,6 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
|||||||
} else if (args[i] == QStringLiteral("-g") && i < args.size() - 1) {
|
} else if (args[i] == QStringLiteral("-g") && i < args.size() - 1) {
|
||||||
// Launch game at path
|
// Launch game at path
|
||||||
game_path = args[++i];
|
game_path = args[++i];
|
||||||
has_gamepath = true;
|
|
||||||
} else if (args[i] == QStringLiteral("-input-profile") && i < args.size() - 1) {
|
} else if (args[i] == QStringLiteral("-input-profile") && i < args.size() - 1) {
|
||||||
auto& players = Settings::values.players.GetValue();
|
auto& players = Settings::values.players.GetValue();
|
||||||
players[0].profile_name = args[++i].toStdString();
|
players[0].profile_name = args[++i].toStdString();
|
||||||
@@ -558,16 +558,19 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
|||||||
should_launch_qlaunch = true;
|
should_launch_qlaunch = true;
|
||||||
} else if (args[i] == QStringLiteral("-hlaunch")) {
|
} else if (args[i] == QStringLiteral("-hlaunch")) {
|
||||||
should_launch_hlaunch = true;
|
should_launch_hlaunch = true;
|
||||||
|
} else if (args[i] == QStringLiteral("-hlaunch-uloader")) {
|
||||||
|
should_launch_hlaunch_uloader = true;
|
||||||
|
} else if (args[i] == QStringLiteral("-ulaunch")) {
|
||||||
|
should_launch_ulaunch = true;
|
||||||
} else if (args[i] == QStringLiteral("-setup")) {
|
} else if (args[i] == QStringLiteral("-setup")) {
|
||||||
should_launch_setup = true;
|
should_launch_setup = true;
|
||||||
} else {
|
} else {
|
||||||
game_path = args[i];
|
game_path = args[i];
|
||||||
has_gamepath = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override fullscreen setting if gamepath or argument is provided
|
// Override fullscreen setting if gamepath or argument is provided
|
||||||
if (has_gamepath || is_fullscreen) {
|
if (!game_path.isEmpty() || is_fullscreen) {
|
||||||
ui->action_Fullscreen->setChecked(is_fullscreen);
|
ui->action_Fullscreen->setChecked(is_fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,8 +583,22 @@ MainWindow::MainWindow(bool has_broken_vulkan)
|
|||||||
LaunchFirmwareApplet(u64(Service::AM::AppletProgramId::QLaunch), std::nullopt);
|
LaunchFirmwareApplet(u64(Service::AM::AppletProgramId::QLaunch), std::nullopt);
|
||||||
} else if (should_launch_hlaunch) {
|
} else if (should_launch_hlaunch) {
|
||||||
std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir);
|
std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir);
|
||||||
auto const hbl_path = (sd_dir / "atmosphere" / "hbl.nsp").string();
|
auto const path = (sd_dir / "atmosphere" / "hbl.nsp").string();
|
||||||
BootGame(QString::fromStdString(hbl_path), ApplicationAppletParameters());
|
BootGame(QString::fromStdString(path), ApplicationAppletParameters());
|
||||||
|
} else if (should_launch_hlaunch_uloader) {
|
||||||
|
std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir);
|
||||||
|
auto const path = (sd_dir / "ulaunch" / "bin" / "uLoader" / "application" / "main").string();
|
||||||
|
auto params = ApplicationAppletParameters();
|
||||||
|
params.launch_type = Service::AM::LaunchType::FrontendUlaunchInitiated;
|
||||||
|
BootGame(QString::fromStdString(path), params);
|
||||||
|
} else if (should_launch_ulaunch) {
|
||||||
|
std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir);
|
||||||
|
auto const path = (sd_dir / "ulaunch" / "bin" / "uMenu" / "main").string();
|
||||||
|
auto const program_id = 0x010000000000FFFF;
|
||||||
|
auto const applet_id = Service::AM::AppletId::UlauncherUmenu;
|
||||||
|
auto params = LibraryAppletParameters(program_id, applet_id);
|
||||||
|
QtCommon::system->GetFrontendAppletHolder().SetCurrentAppletId(applet_id);
|
||||||
|
BootGame(QString::fromStdString(path), params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2779,7 +2796,7 @@ void MainWindow::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() > 0) {
|
||||||
BootGame(dir.path() + QDir::separator() + matching_main[0], ApplicationAppletParameters());
|
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"),
|
||||||
|
|||||||
Reference in New Issue
Block a user