diff options
author | liamwhite <[email protected]> | 2023-09-24 10:50:38 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2023-09-24 10:50:38 -0400 |
commit | 37a4a6751a0c2fe1556bcea651dbe30a008ba166 (patch) | |
tree | 3d4ef39937966faf7bcb11efe42ba9d7f292257d /src | |
parent | 93a1cd75fecba13600bf5d27118da0e7cc23f815 (diff) | |
parent | bb28f4a0c4f457bc19ecfe550437644ebbc21a47 (diff) | |
download | yuzu-mainline-37a4a6751a0c2fe1556bcea651dbe30a008ba166.tar.gz yuzu-mainline-37a4a6751a0c2fe1556bcea651dbe30a008ba166.zip |
Merge pull request #11569 from german77/lle_applet
service: am: Add support for LLE Mii Edit Applet
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hle/service/am/am.cpp | 213 | ||||
-rw-r--r-- | src/core/hle/service/am/am.h | 33 | ||||
-rw-r--r-- | src/core/hle/service/am/applet_ae.cpp | 48 | ||||
-rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 24 | ||||
-rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/service/mii/mii_types.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/ns/iplatform_service_manager.cpp | 17 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 42 | ||||
-rw-r--r-- | src/yuzu/main.h | 2 | ||||
-rw-r--r-- | src/yuzu/main.ui | 9 |
11 files changed, 360 insertions, 33 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 8ffdd19e7..e9bd04842 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -19,6 +19,7 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.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_web_browser.h" #include "core/hle/service/am/applets/applets.h" @@ -190,7 +191,7 @@ IDisplayController::IDisplayController(Core::System& system_) {5, nullptr, "GetLastForegroundCaptureImageEx"}, {6, nullptr, "GetLastApplicationCaptureImageEx"}, {7, nullptr, "GetCallerAppletCaptureImageEx"}, - {8, nullptr, "TakeScreenShotOfOwnLayer"}, + {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"}, {9, nullptr, "CopyBetweenCaptureBuffers"}, {10, nullptr, "AcquireLastApplicationCaptureBuffer"}, {11, nullptr, "ReleaseLastApplicationCaptureBuffer"}, @@ -218,6 +219,13 @@ IDisplayController::IDisplayController(Core::System& system_) 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_) : ServiceFramework{system_, "IDebugFunctions"} { // clang-format off @@ -724,7 +732,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, {110, nullptr, "OpenMyGpuErrorHandler"}, {120, nullptr, "GetAppletLaunchedHistory"}, {200, nullptr, "GetOperationModeSystemInfo"}, - {300, nullptr, "GetSettingsPlatformRegion"}, + {300, &ICommonStateGetter::GetSettingsPlatformRegion, "GetSettingsPlatformRegion"}, {400, nullptr, "ActivateMigrationService"}, {401, nullptr, "DeactivateMigrationService"}, {500, nullptr, "DisableSleepTillShutdown"}, @@ -736,6 +744,10 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, // clang-format on RegisterHandlers(functions); + + // Configure applets to be in foreground state + msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); + msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); } ICommonStateGetter::~ICommonStateGetter() = default; @@ -867,6 +879,14 @@ void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext& 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( HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); @@ -1324,18 +1344,19 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) : ServiceFramework{system_, "ILibraryAppletSelfAccessor"} { + // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "PopInData"}, - {1, nullptr, "PushOutData"}, + {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, + {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"}, {2, nullptr, "PopInteractiveInData"}, {3, nullptr, "PushInteractiveOutData"}, {5, nullptr, "GetPopInDataEvent"}, {6, nullptr, "GetPopInteractiveInDataEvent"}, - {10, nullptr, "ExitProcessAndReturn"}, - {11, nullptr, "GetLibraryAppletInfo"}, + {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, + {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, {12, nullptr, "GetMainAppletIdentityInfo"}, {13, nullptr, "CanUseApplicationCore"}, - {14, nullptr, "GetCallerAppletIdentityInfo"}, + {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"}, {15, nullptr, "GetMainAppletApplicationControlProperty"}, {16, nullptr, "GetMainAppletStorageId"}, {17, nullptr, "GetCallerAppletIdentityInfoStack"}, @@ -1361,10 +1382,142 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) {140, nullptr, "SetApplicationMemoryReservation"}, {150, nullptr, "ShouldSetGpuTimeSliceManually"}, }; + // clang-format on RegisterHandlers(functions); + + PushInShowMiiEditData(); } 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_) : ServiceFramework{system_, "IApplicationFunctions"}, service_context{system, @@ -2049,8 +2202,8 @@ IProcessWindingController::IProcessWindingController(Core::System& system_) : ServiceFramework{system_, "IProcessWindingController"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "GetLaunchReason"}, - {11, nullptr, "OpenCallingLibraryApplet"}, + {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"}, + {11, &IProcessWindingController::OpenCallingLibraryApplet, "OpenCallingLibraryApplet"}, {21, nullptr, "PushContext"}, {22, nullptr, "PopContext"}, {23, nullptr, "CancelWindingReservation"}, @@ -2064,4 +2217,46 @@ IProcessWindingController::IProcessWindingController(Core::System& system_) } 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 diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index f86841c60..5b97eb5e3 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -120,6 +120,9 @@ class IDisplayController final : public ServiceFramework<IDisplayController> { public: explicit IDisplayController(Core::System& system_); ~IDisplayController() override; + +private: + void TakeScreenShotOfOwnLayer(HLERequestContext& ctx); }; class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { @@ -212,6 +215,11 @@ private: CaptureButtonLongPressing, }; + enum class SysPlatformRegion : s32 { + Global = 1, + Terra = 2, + }; + void GetEventHandle(HLERequestContext& ctx); void ReceiveMessage(HLERequestContext& ctx); void GetCurrentFocusState(HLERequestContext& ctx); @@ -227,6 +235,7 @@ private: void GetDefaultDisplayResolution(HLERequestContext& ctx); void SetCpuBoostMode(HLERequestContext& ctx); void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx); + void GetSettingsPlatformRegion(HLERequestContext& ctx); void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx); std::shared_ptr<AppletMessageQueue> msg_queue; @@ -294,6 +303,26 @@ class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletS public: explicit ILibraryAppletSelfAccessor(Core::System& system_); ~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> { @@ -378,6 +407,10 @@ class IProcessWindingController final : public ServiceFramework<IProcessWindingC public: explicit IProcessWindingController(Core::System& system_); ~IProcessWindingController() override; + +private: + void GetLaunchReason(HLERequestContext& ctx); + void OpenCallingLibraryApplet(HLERequestContext& ctx); }; void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index ee9d99a54..eb12312cc 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp @@ -27,7 +27,7 @@ public: {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"}, {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, {20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"}, - {21, nullptr, "GetAppletCommonFunctions"}, + {21, &ILibraryAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"}, {22, nullptr, "GetHomeMenuFunctions"}, {23, nullptr, "GetGlobalStateController"}, {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, @@ -86,28 +86,36 @@ private: rb.PushIpcInterface<IProcessWindingController>(system); } - void GetDebugFunctions(HLERequestContext& ctx) { + void GetLibraryAppletCreator(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<IDebugFunctions>(system); + rb.PushIpcInterface<ILibraryAppletCreator>(system); } - void GetLibraryAppletCreator(HLERequestContext& ctx) { + void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<ILibraryAppletCreator>(system); + rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system); } - void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { + void GetAppletCommonFunctions(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system); + 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; @@ -133,7 +141,7 @@ public: {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"}, - {23, nullptr, "GetAppletCommonFunctions"}, + {23, &ISystemAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"}, {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, }; // clang-format on @@ -182,14 +190,6 @@ private: 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) { LOG_DEBUG(Service_AM, "called"); @@ -222,6 +222,22 @@ private: 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; std::shared_ptr<AppletMessageQueue> msg_queue; }; diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 6e4d26b1e..2492bbc16 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -698,7 +698,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {19, nullptr, "FormatSdCardFileSystem"}, {21, nullptr, "DeleteSaveDataFileSystem"}, {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"}, - {23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"}, + {23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"}, {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"}, {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"}, {26, nullptr, "FormatSdCardDryRun"}, @@ -712,7 +712,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, {36, nullptr, "OpenHostFileSystemWithOption"}, {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"}, - {52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"}, + {52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"}, {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, {58, nullptr, "ReadSaveDataFileSystemExtraData"}, @@ -870,6 +870,21 @@ void FSP_SRV::CreateSaveDataFileSystem(HLERequestContext& ctx) { 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) { IPC::RequestParser rp{ctx}; @@ -916,6 +931,11 @@ void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) { 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) { LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); OpenSaveDataFileSystem(ctx); diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index 4f3c2f6de..280bc9867 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -39,7 +39,9 @@ private: void OpenFileSystemWithPatch(HLERequestContext& ctx); void OpenSdCardFileSystem(HLERequestContext& ctx); void CreateSaveDataFileSystem(HLERequestContext& ctx); + void CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); void OpenSaveDataFileSystem(HLERequestContext& ctx); + void OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 146bb486d..bc822f19e 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -346,6 +346,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { } SignalStyleSetChangedEvent(npad_id); WriteEmptyEntry(controller.shared_memory); + hid_core.SetLastActiveController(npad_id); } void Controller_NPad::OnInit() { diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h index f43efd83c..08c6029df 100644 --- a/src/core/hle/service/mii/mii_types.h +++ b/src/core/hle/service/mii/mii_types.h @@ -614,7 +614,7 @@ struct Nickname { } std::size_t index = 1; - while (data[index] != 0) { + while (index < MaxNameSize && data[index] != 0) { index++; } while (index < MaxNameSize && data[index] == 0) { diff --git a/src/core/hle/service/ns/iplatform_service_manager.cpp b/src/core/hle/service/ns/iplatform_service_manager.cpp index 6c2f5e70b..46268be95 100644 --- a/src/core/hle/service/ns/iplatform_service_manager.cpp +++ b/src/core/hle/service/ns/iplatform_service_manager.cpp @@ -144,7 +144,7 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch {3, &IPlatformServiceManager::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"}, {4, &IPlatformServiceManager::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}, {5, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, - {6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"}, + {6, &IPlatformServiceManager::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriorityForSystem"}, {100, nullptr, "RequestApplicationFunctionAuthorization"}, {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, @@ -262,8 +262,17 @@ void IPlatformServiceManager::GetSharedMemoryNativeHandle(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}; 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); IPC::ResponseBuilder rb{ctx, 4}; @@ -280,9 +289,9 @@ void IPlatformServiceManager::GetSharedFontInOrderOfPriority(HLERequestContext& } // Resize buffers if game requests smaller size output - font_codes.resize(std::min(font_codes.size(), ctx.GetWriteBufferNumElements<u32>(0))); - font_offsets.resize(std::min(font_offsets.size(), ctx.GetWriteBufferNumElements<u32>(1))); - font_sizes.resize(std::min(font_sizes.size(), ctx.GetWriteBufferNumElements<u32>(2))); + font_codes.resize(std::min(font_codes.size(), font_codes_count)); + font_offsets.resize(std::min(font_offsets.size(), font_offsets_count)); + font_sizes.resize(std::min(font_sizes.size(), font_sizes_count)); ctx.WriteBuffer(font_codes, 0); ctx.WriteBuffer(font_offsets, 1); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d32aa9615..b1b6b9354 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1551,6 +1551,7 @@ void GMainWindow::ConnectMenuEvents() { // Tools connect_menu(ui->action_Rederive, std::bind(&GMainWindow::OnReinitializeKeys, this, ReinitializeKeyBehavior::Warning)); + connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit); connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot); // TAS @@ -1590,6 +1591,8 @@ void GMainWindow::UpdateMenuState() { } multiplayer_state->UpdateNotificationStatus(); + + ui->action_Load_Mii_Edit->setEnabled(CheckFirmwarePresence()); } void GMainWindow::OnDisplayTitleBars(bool show) { @@ -4134,6 +4137,27 @@ void GMainWindow::OnToggleStatusBar() { 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() { if (emu_thread == nullptr || !emu_thread->IsRunning()) { return; @@ -4540,6 +4564,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { if (behavior == ReinitializeKeyBehavior::Warning) { game_list->PopulateAsync(UISettings::values.game_dirs); } + + UpdateMenuState(); } bool GMainWindow::CheckSystemArchiveDecryption() { @@ -4561,6 +4587,22 @@ bool GMainWindow::CheckSystemArchiveDecryption() { 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, u64* selected_title_id, u8* selected_content_record_type) { using ContentInfo = std::pair<FileSys::TitleType, FileSys::ContentRecordType>; diff --git a/src/yuzu/main.h b/src/yuzu/main.h index cf191f698..53bedfab3 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -365,6 +365,7 @@ private slots: void ResetWindowSize720(); void ResetWindowSize900(); void ResetWindowSize1080(); + void OnMiiEdit(); void OnCaptureScreenshot(); void OnReinitializeKeys(ReinitializeKeyBehavior behavior); void OnLanguageChanged(const QString& locale); @@ -409,6 +410,7 @@ private: void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); bool CheckDarkMode(); bool CheckSystemArchiveDecryption(); + bool CheckFirmwarePresence(); void ConfigureFilesystemProvider(const std::string& filepath); QString GetTasStateDescription() const; diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index e54d7d75d..91d6c5ef3 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -150,6 +150,8 @@ <addaction name="action_Rederive"/> <addaction name="action_Verify_installed_contents"/> <addaction name="separator"/> + <addaction name="action_Load_Mii_Edit"/> + <addaction name="separator"/> <addaction name="action_Capture_Screenshot"/> <addaction name="menuTAS"/> </widget> @@ -217,7 +219,7 @@ </action> <action name="action_Verify_installed_contents"> <property name="text"> - <string>Verify installed contents</string> + <string>&Verify Installed Contents</string> </property> </action> <action name="action_About"> @@ -368,6 +370,11 @@ <string>&Capture Screenshot</string> </property> </action> + <action name="action_Load_Mii_Edit"> + <property name="text"> + <string>Open &Mii Editor</string> + </property> + </action> <action name="action_Configure_Tas"> <property name="text"> <string>&Configure TAS...</string> |