Merge pull request #11569 from german77/lle_applet

service: am: Add support for LLE Mii Edit Applet
This commit is contained in:
liamwhite 2023-09-24 10:50:38 -04:00 committed by GitHub
commit 37a4a6751a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 362 additions and 35 deletions

View file

@ -19,6 +19,7 @@
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/am/applets/applet_mii_edit_types.h"
#include "core/hle/service/am/applets/applet_profile_select.h" #include "core/hle/service/am/applets/applet_profile_select.h"
#include "core/hle/service/am/applets/applet_web_browser.h" #include "core/hle/service/am/applets/applet_web_browser.h"
#include "core/hle/service/am/applets/applets.h" #include "core/hle/service/am/applets/applets.h"
@ -190,7 +191,7 @@ IDisplayController::IDisplayController(Core::System& system_)
{5, nullptr, "GetLastForegroundCaptureImageEx"}, {5, nullptr, "GetLastForegroundCaptureImageEx"},
{6, nullptr, "GetLastApplicationCaptureImageEx"}, {6, nullptr, "GetLastApplicationCaptureImageEx"},
{7, nullptr, "GetCallerAppletCaptureImageEx"}, {7, nullptr, "GetCallerAppletCaptureImageEx"},
{8, nullptr, "TakeScreenShotOfOwnLayer"}, {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"},
{9, nullptr, "CopyBetweenCaptureBuffers"}, {9, nullptr, "CopyBetweenCaptureBuffers"},
{10, nullptr, "AcquireLastApplicationCaptureBuffer"}, {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
{11, nullptr, "ReleaseLastApplicationCaptureBuffer"}, {11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
@ -218,6 +219,13 @@ IDisplayController::IDisplayController(Core::System& system_)
IDisplayController::~IDisplayController() = default; IDisplayController::~IDisplayController() = default;
void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
IDebugFunctions::IDebugFunctions(Core::System& system_) IDebugFunctions::IDebugFunctions(Core::System& system_)
: ServiceFramework{system_, "IDebugFunctions"} { : ServiceFramework{system_, "IDebugFunctions"} {
// clang-format off // clang-format off
@ -724,7 +732,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{110, nullptr, "OpenMyGpuErrorHandler"}, {110, nullptr, "OpenMyGpuErrorHandler"},
{120, nullptr, "GetAppletLaunchedHistory"}, {120, nullptr, "GetAppletLaunchedHistory"},
{200, nullptr, "GetOperationModeSystemInfo"}, {200, nullptr, "GetOperationModeSystemInfo"},
{300, nullptr, "GetSettingsPlatformRegion"}, {300, &ICommonStateGetter::GetSettingsPlatformRegion, "GetSettingsPlatformRegion"},
{400, nullptr, "ActivateMigrationService"}, {400, nullptr, "ActivateMigrationService"},
{401, nullptr, "DeactivateMigrationService"}, {401, nullptr, "DeactivateMigrationService"},
{500, nullptr, "DisableSleepTillShutdown"}, {500, nullptr, "DisableSleepTillShutdown"},
@ -736,6 +744,10 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
// Configure applets to be in foreground state
msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
} }
ICommonStateGetter::~ICommonStateGetter() = default; ICommonStateGetter::~ICommonStateGetter() = default;
@ -867,6 +879,14 @@ void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext&
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void ICommonStateGetter::GetSettingsPlatformRegion(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(SysPlatformRegion::Global);
}
void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(
HLERequestContext& ctx) { HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
@ -1324,18 +1344,19 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
: ServiceFramework{system_, "ILibraryAppletSelfAccessor"} { : ServiceFramework{system_, "ILibraryAppletSelfAccessor"} {
// clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, nullptr, "PopInData"}, {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"},
{1, nullptr, "PushOutData"}, {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"},
{2, nullptr, "PopInteractiveInData"}, {2, nullptr, "PopInteractiveInData"},
{3, nullptr, "PushInteractiveOutData"}, {3, nullptr, "PushInteractiveOutData"},
{5, nullptr, "GetPopInDataEvent"}, {5, nullptr, "GetPopInDataEvent"},
{6, nullptr, "GetPopInteractiveInDataEvent"}, {6, nullptr, "GetPopInteractiveInDataEvent"},
{10, nullptr, "ExitProcessAndReturn"}, {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
{11, nullptr, "GetLibraryAppletInfo"}, {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
{12, nullptr, "GetMainAppletIdentityInfo"}, {12, nullptr, "GetMainAppletIdentityInfo"},
{13, nullptr, "CanUseApplicationCore"}, {13, nullptr, "CanUseApplicationCore"},
{14, nullptr, "GetCallerAppletIdentityInfo"}, {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
{15, nullptr, "GetMainAppletApplicationControlProperty"}, {15, nullptr, "GetMainAppletApplicationControlProperty"},
{16, nullptr, "GetMainAppletStorageId"}, {16, nullptr, "GetMainAppletStorageId"},
{17, nullptr, "GetCallerAppletIdentityInfoStack"}, {17, nullptr, "GetCallerAppletIdentityInfoStack"},
@ -1361,10 +1382,142 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
{140, nullptr, "SetApplicationMemoryReservation"}, {140, nullptr, "SetApplicationMemoryReservation"},
{150, nullptr, "ShouldSetGpuTimeSliceManually"}, {150, nullptr, "ShouldSetGpuTimeSliceManually"},
}; };
// clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
PushInShowMiiEditData();
} }
ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) {
LOG_INFO(Service_AM, "called");
if (queue_data.empty()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultNoDataInChannel);
return;
}
auto data = queue_data.front();
queue_data.pop_front();
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IStorage>(system, std::move(data));
}
void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
system.Exit();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
struct LibraryAppletInfo {
Applets::AppletId applet_id;
Applets::LibraryAppletMode library_applet_mode;
};
LOG_WARNING(Service_AM, "(STUBBED) called");
const LibraryAppletInfo applet_info{
.applet_id = Applets::AppletId::MiiEdit,
.library_applet_mode = Applets::LibraryAppletMode::AllForeground,
};
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.PushRaw(applet_info);
}
void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
struct AppletIdentityInfo {
Applets::AppletId applet_id;
INSERT_PADDING_BYTES(0x4);
u64 application_id;
};
LOG_WARNING(Service_AM, "(STUBBED) called");
const AppletIdentityInfo applet_info{
.applet_id = Applets::AppletId::QLaunch,
.application_id = 0x0100000000001000ull,
};
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
rb.PushRaw(applet_info);
}
void ILibraryAppletSelfAccessor::PushInShowMiiEditData() {
struct MiiEditV3 {
Applets::MiiEditAppletInputCommon common;
Applets::MiiEditAppletInputV3 input;
};
static_assert(sizeof(MiiEditV3) == 0x100, "MiiEditV3 has incorrect size.");
MiiEditV3 mii_arguments{
.common =
{
.version = Applets::MiiEditAppletVersion::Version3,
.applet_mode = Applets::MiiEditAppletMode::ShowMiiEdit,
},
.input{},
};
std::vector<u8> argument_data(sizeof(mii_arguments));
std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments));
queue_data.emplace_back(std::move(argument_data));
}
IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_)
: ServiceFramework{system_, "IAppletCommonFunctions"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SetTerminateResult"},
{10, nullptr, "ReadThemeStorage"},
{11, nullptr, "WriteThemeStorage"},
{20, nullptr, "PushToAppletBoundChannel"},
{21, nullptr, "TryPopFromAppletBoundChannel"},
{40, nullptr, "GetDisplayLogicalResolution"},
{42, nullptr, "SetDisplayMagnification"},
{50, nullptr, "SetHomeButtonDoubleClickEnabled"},
{51, nullptr, "GetHomeButtonDoubleClickEnabled"},
{52, nullptr, "IsHomeButtonShortPressedBlocked"},
{60, nullptr, "IsVrModeCurtainRequired"},
{61, nullptr, "IsSleepRequiredByHighTemperature"},
{62, nullptr, "IsSleepRequiredByLowBattery"},
{70, &IAppletCommonFunctions::SetCpuBoostRequestPriority, "SetCpuBoostRequestPriority"},
{80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"},
{81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"},
{90, nullptr, "OpenNamedChannelAsParent"},
{91, nullptr, "OpenNamedChannelAsChild"},
{100, nullptr, "SetApplicationCoreUsageMode"},
};
// clang-format on
RegisterHandlers(functions);
}
IAppletCommonFunctions::~IAppletCommonFunctions() = default;
void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
IApplicationFunctions::IApplicationFunctions(Core::System& system_) IApplicationFunctions::IApplicationFunctions(Core::System& system_)
: ServiceFramework{system_, "IApplicationFunctions"}, service_context{system, : ServiceFramework{system_, "IApplicationFunctions"}, service_context{system,
@ -2049,8 +2202,8 @@ IProcessWindingController::IProcessWindingController(Core::System& system_)
: ServiceFramework{system_, "IProcessWindingController"} { : ServiceFramework{system_, "IProcessWindingController"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, nullptr, "GetLaunchReason"}, {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"},
{11, nullptr, "OpenCallingLibraryApplet"}, {11, &IProcessWindingController::OpenCallingLibraryApplet, "OpenCallingLibraryApplet"},
{21, nullptr, "PushContext"}, {21, nullptr, "PushContext"},
{22, nullptr, "PopContext"}, {22, nullptr, "PopContext"},
{23, nullptr, "CancelWindingReservation"}, {23, nullptr, "CancelWindingReservation"},
@ -2064,4 +2217,46 @@ IProcessWindingController::IProcessWindingController(Core::System& system_)
} }
IProcessWindingController::~IProcessWindingController() = default; IProcessWindingController::~IProcessWindingController() = default;
void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
struct AppletProcessLaunchReason {
u8 flag;
INSERT_PADDING_BYTES(3);
};
static_assert(sizeof(AppletProcessLaunchReason) == 0x4,
"AppletProcessLaunchReason is an invalid size");
AppletProcessLaunchReason reason{
.flag = 0,
};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushRaw(reason);
}
void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) {
const auto applet_id = Applets::AppletId::MiiEdit;
const auto applet_mode = Applets::LibraryAppletMode::AllForeground;
LOG_WARNING(Service_AM, "(STUBBED) called with applet_id={:08X}, applet_mode={:08X}", applet_id,
applet_mode);
const auto& applet_manager{system.GetAppletManager()};
const auto applet = applet_manager.GetApplet(applet_id, applet_mode);
if (applet == nullptr) {
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultUnknown);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet);
}
} // namespace Service::AM } // namespace Service::AM

View file

@ -120,6 +120,9 @@ class IDisplayController final : public ServiceFramework<IDisplayController> {
public: public:
explicit IDisplayController(Core::System& system_); explicit IDisplayController(Core::System& system_);
~IDisplayController() override; ~IDisplayController() override;
private:
void TakeScreenShotOfOwnLayer(HLERequestContext& ctx);
}; };
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
@ -212,6 +215,11 @@ private:
CaptureButtonLongPressing, CaptureButtonLongPressing,
}; };
enum class SysPlatformRegion : s32 {
Global = 1,
Terra = 2,
};
void GetEventHandle(HLERequestContext& ctx); void GetEventHandle(HLERequestContext& ctx);
void ReceiveMessage(HLERequestContext& ctx); void ReceiveMessage(HLERequestContext& ctx);
void GetCurrentFocusState(HLERequestContext& ctx); void GetCurrentFocusState(HLERequestContext& ctx);
@ -227,6 +235,7 @@ private:
void GetDefaultDisplayResolution(HLERequestContext& ctx); void GetDefaultDisplayResolution(HLERequestContext& ctx);
void SetCpuBoostMode(HLERequestContext& ctx); void SetCpuBoostMode(HLERequestContext& ctx);
void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx); void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx);
void GetSettingsPlatformRegion(HLERequestContext& ctx);
void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx); void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx);
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
@ -294,6 +303,26 @@ class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletS
public: public:
explicit ILibraryAppletSelfAccessor(Core::System& system_); explicit ILibraryAppletSelfAccessor(Core::System& system_);
~ILibraryAppletSelfAccessor() override; ~ILibraryAppletSelfAccessor() override;
private:
void PopInData(HLERequestContext& ctx);
void PushOutData(HLERequestContext& ctx);
void GetLibraryAppletInfo(HLERequestContext& ctx);
void ExitProcessAndReturn(HLERequestContext& ctx);
void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
void PushInShowMiiEditData();
std::deque<std::vector<u8>> queue_data;
};
class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> {
public:
explicit IAppletCommonFunctions(Core::System& system_);
~IAppletCommonFunctions() override;
private:
void SetCpuBoostRequestPriority(HLERequestContext& ctx);
}; };
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
@ -378,6 +407,10 @@ class IProcessWindingController final : public ServiceFramework<IProcessWindingC
public: public:
explicit IProcessWindingController(Core::System& system_); explicit IProcessWindingController(Core::System& system_);
~IProcessWindingController() override; ~IProcessWindingController() override;
private:
void GetLaunchReason(HLERequestContext& ctx);
void OpenCallingLibraryApplet(HLERequestContext& ctx);
}; };
void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system);

View file

@ -27,7 +27,7 @@ public:
{10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"}, {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"},
{11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
{20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"}, {20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"},
{21, nullptr, "GetAppletCommonFunctions"}, {21, &ILibraryAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"},
{22, nullptr, "GetHomeMenuFunctions"}, {22, nullptr, "GetHomeMenuFunctions"},
{23, nullptr, "GetGlobalStateController"}, {23, nullptr, "GetGlobalStateController"},
{1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
@ -86,14 +86,6 @@ private:
rb.PushIpcInterface<IProcessWindingController>(system); rb.PushIpcInterface<IProcessWindingController>(system);
} }
void GetDebugFunctions(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IDebugFunctions>(system);
}
void GetLibraryAppletCreator(HLERequestContext& ctx) { void GetLibraryAppletCreator(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
@ -110,6 +102,22 @@ private:
rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system); rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system);
} }
void GetAppletCommonFunctions(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IAppletCommonFunctions>(system);
}
void GetDebugFunctions(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IDebugFunctions>(system);
}
Nvnflinger::Nvnflinger& nvnflinger; Nvnflinger::Nvnflinger& nvnflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
}; };
@ -133,7 +141,7 @@ public:
{20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"},
{21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"},
{22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"}, {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"},
{23, nullptr, "GetAppletCommonFunctions"}, {23, &ISystemAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"},
{1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
}; };
// clang-format on // clang-format on
@ -182,14 +190,6 @@ private:
rb.PushIpcInterface<IDisplayController>(system); rb.PushIpcInterface<IDisplayController>(system);
} }
void GetDebugFunctions(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IDebugFunctions>(system);
}
void GetLibraryAppletCreator(HLERequestContext& ctx) { void GetLibraryAppletCreator(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
@ -222,6 +222,22 @@ private:
rb.PushIpcInterface<IApplicationCreator>(system); rb.PushIpcInterface<IApplicationCreator>(system);
} }
void GetAppletCommonFunctions(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IAppletCommonFunctions>(system);
}
void GetDebugFunctions(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IDebugFunctions>(system);
}
Nvnflinger::Nvnflinger& nvnflinger; Nvnflinger::Nvnflinger& nvnflinger;
std::shared_ptr<AppletMessageQueue> msg_queue; std::shared_ptr<AppletMessageQueue> msg_queue;
}; };

View file

@ -698,7 +698,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{19, nullptr, "FormatSdCardFileSystem"}, {19, nullptr, "FormatSdCardFileSystem"},
{21, nullptr, "DeleteSaveDataFileSystem"}, {21, nullptr, "DeleteSaveDataFileSystem"},
{22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"}, {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"},
{23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"}, {23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"},
{24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"}, {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
{25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"}, {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
{26, nullptr, "FormatSdCardDryRun"}, {26, nullptr, "FormatSdCardDryRun"},
@ -712,7 +712,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, {35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
{36, nullptr, "OpenHostFileSystemWithOption"}, {36, nullptr, "OpenHostFileSystemWithOption"},
{51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"}, {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"}, {52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"},
{53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
{58, nullptr, "ReadSaveDataFileSystemExtraData"}, {58, nullptr, "ReadSaveDataFileSystemExtraData"},
@ -870,6 +870,21 @@ void FSP_SRV::CreateSaveDataFileSystem(HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto save_struct = rp.PopRaw<FileSys::SaveDataAttribute>();
[[maybe_unused]] auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo());
FileSys::VirtualDir save_data_dir{};
fsc.CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandSystem, save_struct);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) { void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
@ -916,6 +931,11 @@ void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) {
rb.PushIpcInterface<IFileSystem>(std::move(filesystem)); rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
} }
void FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
OpenSaveDataFileSystem(ctx);
}
void FSP_SRV::OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx) { void FSP_SRV::OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
OpenSaveDataFileSystem(ctx); OpenSaveDataFileSystem(ctx);

View file

@ -39,7 +39,9 @@ private:
void OpenFileSystemWithPatch(HLERequestContext& ctx); void OpenFileSystemWithPatch(HLERequestContext& ctx);
void OpenSdCardFileSystem(HLERequestContext& ctx); void OpenSdCardFileSystem(HLERequestContext& ctx);
void CreateSaveDataFileSystem(HLERequestContext& ctx); void CreateSaveDataFileSystem(HLERequestContext& ctx);
void CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx);
void OpenSaveDataFileSystem(HLERequestContext& ctx); void OpenSaveDataFileSystem(HLERequestContext& ctx);
void OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx);
void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx);
void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx);
void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx);

View file

@ -346,6 +346,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
} }
SignalStyleSetChangedEvent(npad_id); SignalStyleSetChangedEvent(npad_id);
WriteEmptyEntry(controller.shared_memory); WriteEmptyEntry(controller.shared_memory);
hid_core.SetLastActiveController(npad_id);
} }
void Controller_NPad::OnInit() { void Controller_NPad::OnInit() {

View file

@ -614,7 +614,7 @@ struct Nickname {
} }
std::size_t index = 1; std::size_t index = 1;
while (data[index] != 0) { while (index < MaxNameSize && data[index] != 0) {
index++; index++;
} }
while (index < MaxNameSize && data[index] == 0) { while (index < MaxNameSize && data[index] == 0) {

View file

@ -144,7 +144,7 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch
{3, &IPlatformServiceManager::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"}, {3, &IPlatformServiceManager::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"},
{4, &IPlatformServiceManager::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, {4, &IPlatformServiceManager::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
{5, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, {5, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"},
{6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"}, {6, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriorityForSystem"},
{100, nullptr, "RequestApplicationFunctionAuthorization"}, {100, nullptr, "RequestApplicationFunctionAuthorization"},
{101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"},
{102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"},
@ -262,8 +262,17 @@ void IPlatformServiceManager::GetSharedMemoryNativeHandle(HLERequestContext& ctx
} }
void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext& ctx) { void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext& ctx) {
// The maximum number of elements that can be returned is 6. Regardless of the available fonts
// or buffer size.
constexpr std::size_t MaxElementCount = 6;
IPC::RequestParser rp{ctx}; IPC::RequestParser rp{ctx};
const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
const std::size_t font_codes_count =
std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(0));
const std::size_t font_offsets_count =
std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(1));
const std::size_t font_sizes_count =
std::min(MaxElementCount, ctx.GetWriteBufferNumElements<u32>(2));
LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code); LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code);
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
@ -280,9 +289,9 @@ void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext&
} }
// Resize buffers if game requests smaller size output // Resize buffers if game requests smaller size output
font_codes.resize(std::min(font_codes.size(), ctx.GetWriteBufferNumElements<u32>(0))); font_codes.resize(std::min(font_codes.size(), font_codes_count));
font_offsets.resize(std::min(font_offsets.size(), ctx.GetWriteBufferNumElements<u32>(1))); font_offsets.resize(std::min(font_offsets.size(), font_offsets_count));
font_sizes.resize(std::min(font_sizes.size(), ctx.GetWriteBufferNumElements<u32>(2))); font_sizes.resize(std::min(font_sizes.size(), font_sizes_count));
ctx.WriteBuffer(font_codes, 0); ctx.WriteBuffer(font_codes, 0);
ctx.WriteBuffer(font_offsets, 1); ctx.WriteBuffer(font_offsets, 1);

View file

@ -1551,6 +1551,7 @@ void GMainWindow::ConnectMenuEvents() {
// Tools // Tools
connect_menu(ui->action_Rederive, std::bind(&GMainWindow::OnReinitializeKeys, this, connect_menu(ui->action_Rederive, std::bind(&GMainWindow::OnReinitializeKeys, this,
ReinitializeKeyBehavior::Warning)); ReinitializeKeyBehavior::Warning));
connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit);
connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot);
// TAS // TAS
@ -1590,6 +1591,8 @@ void GMainWindow::UpdateMenuState() {
} }
multiplayer_state->UpdateNotificationStatus(); multiplayer_state->UpdateNotificationStatus();
ui->action_Load_Mii_Edit->setEnabled(CheckFirmwarePresence());
} }
void GMainWindow::OnDisplayTitleBars(bool show) { void GMainWindow::OnDisplayTitleBars(bool show) {
@ -4134,6 +4137,27 @@ void GMainWindow::OnToggleStatusBar() {
statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked()); statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
} }
void GMainWindow::OnMiiEdit() {
constexpr u64 MiiEditId = 0x0100000000001009ull;
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
QMessageBox::warning(this, tr("No firmware available"),
tr("Please install the firmware to use the Mii editor."));
return;
}
auto mii_applet_nca = bis_system->GetEntry(MiiEditId, FileSys::ContentRecordType::Program);
if (!mii_applet_nca) {
QMessageBox::warning(this, tr("Mii Edit Applet"),
tr("Mii editor is not available. Please reinstall firmware."));
return;
}
const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path();
BootGame(filename);
}
void GMainWindow::OnCaptureScreenshot() { void GMainWindow::OnCaptureScreenshot() {
if (emu_thread == nullptr || !emu_thread->IsRunning()) { if (emu_thread == nullptr || !emu_thread->IsRunning()) {
return; return;
@ -4540,6 +4564,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
if (behavior == ReinitializeKeyBehavior::Warning) { if (behavior == ReinitializeKeyBehavior::Warning) {
game_list->PopulateAsync(UISettings::values.game_dirs); game_list->PopulateAsync(UISettings::values.game_dirs);
} }
UpdateMenuState();
} }
bool GMainWindow::CheckSystemArchiveDecryption() { bool GMainWindow::CheckSystemArchiveDecryption() {
@ -4561,6 +4587,22 @@ bool GMainWindow::CheckSystemArchiveDecryption() {
return mii_nca->GetRomFS().get() != nullptr; return mii_nca->GetRomFS().get() != nullptr;
} }
bool GMainWindow::CheckFirmwarePresence() {
constexpr u64 MiiEditId = 0x0100000000001009ull;
auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
return false;
}
auto mii_applet_nca = bis_system->GetEntry(MiiEditId, FileSys::ContentRecordType::Program);
if (!mii_applet_nca) {
return false;
}
return true;
}
bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id, bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
u64* selected_title_id, u8* selected_content_record_type) { u64* selected_title_id, u8* selected_content_record_type) {
using ContentInfo = std::pair<FileSys::TitleType, FileSys::ContentRecordType>; using ContentInfo = std::pair<FileSys::TitleType, FileSys::ContentRecordType>;

View file

@ -365,6 +365,7 @@ private slots:
void ResetWindowSize720(); void ResetWindowSize720();
void ResetWindowSize900(); void ResetWindowSize900();
void ResetWindowSize1080(); void ResetWindowSize1080();
void OnMiiEdit();
void OnCaptureScreenshot(); void OnCaptureScreenshot();
void OnReinitializeKeys(ReinitializeKeyBehavior behavior); void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
void OnLanguageChanged(const QString& locale); void OnLanguageChanged(const QString& locale);
@ -409,6 +410,7 @@ private:
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
bool CheckDarkMode(); bool CheckDarkMode();
bool CheckSystemArchiveDecryption(); bool CheckSystemArchiveDecryption();
bool CheckFirmwarePresence();
void ConfigureFilesystemProvider(const std::string& filepath); void ConfigureFilesystemProvider(const std::string& filepath);
QString GetTasStateDescription() const; QString GetTasStateDescription() const;

View file

@ -150,6 +150,8 @@
<addaction name="action_Rederive"/> <addaction name="action_Rederive"/>
<addaction name="action_Verify_installed_contents"/> <addaction name="action_Verify_installed_contents"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_Load_Mii_Edit"/>
<addaction name="separator"/>
<addaction name="action_Capture_Screenshot"/> <addaction name="action_Capture_Screenshot"/>
<addaction name="menuTAS"/> <addaction name="menuTAS"/>
</widget> </widget>
@ -217,7 +219,7 @@
</action> </action>
<action name="action_Verify_installed_contents"> <action name="action_Verify_installed_contents">
<property name="text"> <property name="text">
<string>Verify installed contents</string> <string>&amp;Verify Installed Contents</string>
</property> </property>
</action> </action>
<action name="action_About"> <action name="action_About">
@ -368,6 +370,11 @@
<string>&amp;Capture Screenshot</string> <string>&amp;Capture Screenshot</string>
</property> </property>
</action> </action>
<action name="action_Load_Mii_Edit">
<property name="text">
<string>Open &amp;Mii Editor</string>
</property>
</action>
<action name="action_Configure_Tas"> <action name="action_Configure_Tas">
<property name="text"> <property name="text">
<string>&amp;Configure TAS...</string> <string>&amp;Configure TAS...</string>