From 245139afa1ec216d1851f818fc18c3b93395f771 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sat, 23 Sep 2023 03:56:47 +0200 Subject: [PATCH] early-access version 3889 --- README.md | 2 +- src/core/hle/service/am/am.cpp | 213 +++++++++++++++++- src/core/hle/service/am/am.h | 33 +++ src/core/hle/service/am/applet_ae.cpp | 52 +++-- src/core/hle/service/filesystem/fsp_srv.cpp | 24 +- src/core/hle/service/filesystem/fsp_srv.h | 2 + src/core/hle/service/hid/controllers/npad.cpp | 1 + .../service/ns/iplatform_service_manager.cpp | 17 +- src/yuzu/main.cpp | 42 ++++ src/yuzu/main.h | 2 + src/yuzu/main.ui | 9 +- 11 files changed, 362 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 86d775bb4..017eed541 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3888. +This is the source code for early-access 3889. ## Legal Notice diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index a40b235a8..a0455c6e3 100755 --- 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(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 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_ERROR(Service_AM, "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(system, applet); +} } // namespace Service::AM diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index faf5532e8..b6d2b09bc 100755 --- 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 { public: explicit IDisplayController(Core::System& system_); ~IDisplayController() override; + +private: + void TakeScreenShotOfOwnLayer(HLERequestContext& ctx); }; class IDebugFunctions final : public ServiceFramework { @@ -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 msg_queue; @@ -294,6 +303,26 @@ class ILibraryAppletSelfAccessor final : public ServiceFramework> queue_data; +}; + +class IAppletCommonFunctions final : public ServiceFramework { +public: + explicit IAppletCommonFunctions(Core::System& system_); + ~IAppletCommonFunctions() override; + +private: + void SetCpuBoostRequestPriority(HLERequestContext& ctx); }; class IApplicationFunctions final : public ServiceFramework { @@ -378,6 +407,10 @@ class IProcessWindingController final : public ServiceFramework(system); } - void GetDebugFunctions(HLERequestContext& ctx) { - LOG_DEBUG(Service_AM, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system); - } - void GetLibraryAppletCreator(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); @@ -110,6 +102,22 @@ private: rb.PushIpcInterface(system); } + void GetAppletCommonFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + + void GetDebugFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + Nvnflinger::Nvnflinger& nvnflinger; std::shared_ptr msg_queue; }; @@ -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(system); } - void GetDebugFunctions(HLERequestContext& ctx) { - LOG_DEBUG(Service_AM, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system); - } - void GetLibraryAppletCreator(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); @@ -222,6 +222,22 @@ private: rb.PushIpcInterface(system); } + void GetAppletCommonFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + + void GetDebugFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } + Nvnflinger::Nvnflinger& nvnflinger; std::shared_ptr msg_queue; }; diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index e91195c0d..de792f3e6 100755 --- 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(); + [[maybe_unused]] auto save_create_struct = rp.PopRaw>(); + + 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(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 8010b22fb..5e2c6035c 100755 --- 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 da1cea8bf..f1562069e 100755 --- 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/ns/iplatform_service_manager.cpp b/src/core/hle/service/ns/iplatform_service_manager.cpp index 13cc60a28..5c4820159 100755 --- 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()}; // TODO(ogniK): Find out what this is used for + const std::size_t font_codes_count = + std::min(MaxElementCount, ctx.GetWriteBufferNumElements(0)); + const std::size_t font_offsets_count = + std::min(MaxElementCount, ctx.GetWriteBufferNumElements(1)); + const std::size_t font_sizes_count = + std::min(MaxElementCount, ctx.GetWriteBufferNumElements(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(0))); - font_offsets.resize(std::min(font_offsets.size(), ctx.GetWriteBufferNumElements(1))); - font_sizes.resize(std::min(font_sizes.size(), ctx.GetWriteBufferNumElements(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 1628b44e4..0d9159585 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1556,6 +1556,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 @@ -1595,6 +1596,8 @@ void GMainWindow::UpdateMenuState() { } multiplayer_state->UpdateNotificationStatus(); + + ui->action_Load_Mii_Edit->setEnabled(CheckFirmwarePresence()); } void GMainWindow::OnDisplayTitleBars(bool show) { @@ -4157,6 +4160,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; @@ -4563,6 +4587,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { if (behavior == ReinitializeKeyBehavior::Warning) { game_list->PopulateAsync(UISettings::values.game_dirs); } + + UpdateMenuState(); } bool GMainWindow::CheckSystemArchiveDecryption() { @@ -4584,6 +4610,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; diff --git a/src/yuzu/main.h b/src/yuzu/main.h index d65167b0e..7bb34084b 100755 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -370,6 +370,7 @@ private slots: void ResetWindowSize720(); void ResetWindowSize900(); void ResetWindowSize1080(); + void OnMiiEdit(); void OnCaptureScreenshot(); void OnReinitializeKeys(ReinitializeKeyBehavior behavior); void OnLanguageChanged(const QString& locale); @@ -415,6 +416,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 8587020c7..ef0c016c9 100755 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -150,6 +150,8 @@ + + @@ -217,7 +219,7 @@ - Verify installed contents + &Verify Installed Contents @@ -368,6 +370,11 @@ &Capture Screenshot + + + Open &Mii Editor + + &Configure TAS...