diff options
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/service/am/am.cpp | 216 | ||||
-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/am/applets/applet_mii_edit.cpp | 52 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.h | 7 | ||||
-rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 65 | ||||
-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.cpp | 114 | ||||
-rw-r--r-- | src/core/hle/service/mii/mii.h | 18 | ||||
-rw-r--r-- | src/core/hle/service/mii/mii_database_manager.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/mii/mii_manager.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/mii/mii_types.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/mii/types/core_data.cpp | 5 | ||||
-rw-r--r-- | src/core/hle/service/mii/types/raw_data.cpp | 12 | ||||
-rw-r--r-- | src/core/hle/service/nfc/common/device.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/ns/iplatform_service_manager.cpp | 17 |
17 files changed, 492 insertions, 110 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 8ffdd19e7..a83622f7c 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, @@ -1941,9 +2094,6 @@ void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) { void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { auto message_queue = std::make_shared<AppletMessageQueue>(system); - // Needed on game boot - message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); - auto server_manager = std::make_unique<ServerManager>(system); server_manager->RegisterNamedService( @@ -2049,8 +2199,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 +2214,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/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index 350a90818..50adc7c02 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp @@ -7,7 +7,9 @@ #include "core/frontend/applets/mii_edit.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/applet_mii_edit.h" +#include "core/hle/service/mii/mii.h" #include "core/hle/service/mii/mii_manager.h" +#include "core/hle/service/sm/sm.h" namespace Service::AM::Applets { @@ -56,6 +58,12 @@ void MiiEdit::Initialize() { sizeof(MiiEditAppletInputV4)); break; } + + manager = system.ServiceManager().GetService<Mii::MiiDBModule>("mii:e")->GetMiiManager(); + if (manager == nullptr) { + manager = std::make_shared<Mii::MiiManager>(); + } + manager->Initialize(metadata); } bool MiiEdit::TransactionComplete() const { @@ -78,22 +86,46 @@ void MiiEdit::Execute() { // This is a default stub for each of the MiiEdit applet modes. switch (applet_input_common.applet_mode) { case MiiEditAppletMode::ShowMiiEdit: - case MiiEditAppletMode::AppendMii: case MiiEditAppletMode::AppendMiiImage: case MiiEditAppletMode::UpdateMiiImage: MiiEditOutput(MiiEditResult::Success, 0); break; - case MiiEditAppletMode::CreateMii: - case MiiEditAppletMode::EditMii: { - Mii::CharInfo char_info{}; + case MiiEditAppletMode::AppendMii: { Mii::StoreData store_data{}; - store_data.BuildBase(Mii::Gender::Male); - char_info.SetFromStoreData(store_data); + store_data.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); + store_data.SetNickname({u'y', u'u', u'z', u'u'}); + store_data.SetChecksum(); + const auto result = manager->AddOrReplace(metadata, store_data); + + if (result.IsError()) { + MiiEditOutput(MiiEditResult::Cancel, 0); + break; + } + + s32 index = manager->FindIndex(store_data.GetCreateId(), false); + + if (index == -1) { + MiiEditOutput(MiiEditResult::Cancel, 0); + break; + } + + MiiEditOutput(MiiEditResult::Success, index); + break; + } + case MiiEditAppletMode::CreateMii: { + Mii::CharInfo char_info{}; + manager->BuildRandom(char_info, Mii::Age::All, Mii::Gender::All, Mii::Race::All); const MiiEditCharInfo edit_char_info{ - .mii_info{applet_input_common.applet_mode == MiiEditAppletMode::EditMii - ? applet_input_v4.char_info.mii_info - : char_info}, + .mii_info{char_info}, + }; + + MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); + break; + } + case MiiEditAppletMode::EditMii: { + const MiiEditCharInfo edit_char_info{ + .mii_info{applet_input_v4.char_info.mii_info}, }; MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); @@ -113,6 +145,8 @@ void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) { .index{index}, }; + LOG_INFO(Input, "called, result={}, index={}", result, index); + std::vector<u8> out_data(sizeof(MiiEditAppletOutput)); std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutput)); diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h index 3f46fae1b..7ff34af49 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ b/src/core/hle/service/am/applets/applet_mii_edit.h @@ -11,6 +11,11 @@ namespace Core { class System; } // namespace Core +namespace Service::Mii { +struct DatabaseSessionMetadata; +class MiiManager; +} // namespace Service::Mii + namespace Service::AM::Applets { class MiiEdit final : public Applet { @@ -40,6 +45,8 @@ private: MiiEditAppletInputV4 applet_input_v4{}; bool is_complete{false}; + std::shared_ptr<Mii::MiiManager> manager = nullptr; + Mii::DatabaseSessionMetadata metadata{}; }; } // namespace Service::AM::Applets diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 6e4d26b1e..c2054e8a0 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -329,6 +329,7 @@ public: {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"}, {15, nullptr, "QueryEntry"}, + {16, &IFileSystem::GetFileSystemAttribute, "GetFileSystemAttribute"}, }; RegisterHandlers(functions); } @@ -521,6 +522,46 @@ public: rb.PushRaw(vfs_timestamp); } + void GetFileSystemAttribute(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + struct FileSystemAttribute { + u8 dir_entry_name_length_max_defined; + u8 file_entry_name_length_max_defined; + u8 dir_path_name_length_max_defined; + u8 file_path_name_length_max_defined; + INSERT_PADDING_BYTES_NOINIT(0x5); + u8 utf16_dir_entry_name_length_max_defined; + u8 utf16_file_entry_name_length_max_defined; + u8 utf16_dir_path_name_length_max_defined; + u8 utf16_file_path_name_length_max_defined; + INSERT_PADDING_BYTES_NOINIT(0x18); + s32 dir_entry_name_length_max; + s32 file_entry_name_length_max; + s32 dir_path_name_length_max; + s32 file_path_name_length_max; + INSERT_PADDING_WORDS_NOINIT(0x5); + s32 utf16_dir_entry_name_length_max; + s32 utf16_file_entry_name_length_max; + s32 utf16_dir_path_name_length_max; + s32 utf16_file_path_name_length_max; + INSERT_PADDING_WORDS_NOINIT(0x18); + INSERT_PADDING_WORDS_NOINIT(0x1); + }; + static_assert(sizeof(FileSystemAttribute) == 0xc0, + "FileSystemAttribute has incorrect size"); + + FileSystemAttribute savedata_attribute{}; + savedata_attribute.dir_entry_name_length_max_defined = true; + savedata_attribute.file_entry_name_length_max_defined = true; + savedata_attribute.dir_entry_name_length_max = 0x40; + savedata_attribute.file_entry_name_length_max = 0x40; + + IPC::ResponseBuilder rb{ctx, 50}; + rb.Push(ResultSuccess); + rb.PushRaw(savedata_attribute); + } + private: VfsDirectoryServiceWrapper backend; SizeGetter size; @@ -698,7 +739,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 +753,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 +911,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 +972,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.cpp b/src/core/hle/service/mii/mii.cpp index 8de806cfb..c28eed926 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -18,8 +18,10 @@ namespace Service::Mii { class IDatabaseService final : public ServiceFramework<IDatabaseService> { public: - explicit IDatabaseService(Core::System& system_, bool is_system_) - : ServiceFramework{system_, "IDatabaseService"}, is_system{is_system_} { + explicit IDatabaseService(Core::System& system_, std::shared_ptr<MiiManager> mii_manager, + bool is_system_) + : ServiceFramework{system_, "IDatabaseService"}, manager{mii_manager}, is_system{ + is_system_} { // clang-format off static const FunctionInfo functions[] = { {0, &IDatabaseService::IsUpdated, "IsUpdated"}, @@ -54,7 +56,7 @@ public: RegisterHandlers(functions); - manager.Initialize(metadata); + manager->Initialize(metadata); } private: @@ -64,7 +66,7 @@ private: LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); - const bool is_updated = manager.IsUpdated(metadata, source_flag); + const bool is_updated = manager->IsUpdated(metadata, source_flag); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); @@ -74,7 +76,7 @@ private: void IsFullDatabase(HLERequestContext& ctx) { LOG_DEBUG(Service_Mii, "called"); - const bool is_full_database = manager.IsFullDatabase(); + const bool is_full_database = manager->IsFullDatabase(); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); @@ -85,7 +87,7 @@ private: IPC::RequestParser rp{ctx}; const auto source_flag{rp.PopRaw<SourceFlag>()}; - const u32 mii_count = manager.GetCount(metadata, source_flag); + const u32 mii_count = manager->GetCount(metadata, source_flag); LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, mii_count); @@ -101,7 +103,7 @@ private: u32 mii_count{}; std::vector<CharInfoElement> char_info_elements(output_size); - const auto result = manager.Get(metadata, char_info_elements, mii_count, source_flag); + const auto result = manager->Get(metadata, char_info_elements, mii_count, source_flag); if (mii_count != 0) { ctx.WriteBuffer(char_info_elements); @@ -122,7 +124,7 @@ private: u32 mii_count{}; std::vector<CharInfo> char_info(output_size); - const auto result = manager.Get(metadata, char_info, mii_count, source_flag); + const auto result = manager->Get(metadata, char_info, mii_count, source_flag); if (mii_count != 0) { ctx.WriteBuffer(char_info); @@ -144,7 +146,7 @@ private: LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); CharInfo new_char_info{}; - const auto result = manager.UpdateLatest(metadata, new_char_info, char_info, source_flag); + const auto result = manager->UpdateLatest(metadata, new_char_info, char_info, source_flag); if (result.IsFailure()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -183,7 +185,7 @@ private: } CharInfo char_info{}; - manager.BuildRandom(char_info, age, gender, race); + manager->BuildRandom(char_info, age, gender, race); IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(ResultSuccess); @@ -203,7 +205,7 @@ private: } CharInfo char_info{}; - manager.BuildDefault(char_info, index); + manager->BuildDefault(char_info, index); IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(ResultSuccess); @@ -217,7 +219,7 @@ private: u32 mii_count{}; std::vector<StoreDataElement> store_data_elements(output_size); - const auto result = manager.Get(metadata, store_data_elements, mii_count, source_flag); + const auto result = manager->Get(metadata, store_data_elements, mii_count, source_flag); if (mii_count != 0) { ctx.WriteBuffer(store_data_elements); @@ -238,7 +240,7 @@ private: u32 mii_count{}; std::vector<StoreData> store_data(output_size); - const auto result = manager.Get(metadata, store_data, mii_count, source_flag); + const auto result = manager->Get(metadata, store_data, mii_count, source_flag); if (mii_count != 0) { ctx.WriteBuffer(store_data); @@ -266,7 +268,7 @@ private: StoreData new_store_data{}; if (result.IsSuccess()) { - result = manager.UpdateLatest(metadata, new_store_data, store_data, source_flag); + result = manager->UpdateLatest(metadata, new_store_data, store_data, source_flag); } if (result.IsFailure()) { @@ -288,7 +290,7 @@ private: LOG_INFO(Service_Mii, "called with create_id={}, is_special={}", create_id.FormattedString(), is_special); - const s32 index = manager.FindIndex(create_id, is_special); + const s32 index = manager->FindIndex(create_id, is_special); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); @@ -309,14 +311,14 @@ private: } if (result.IsSuccess()) { - const u32 count = manager.GetCount(metadata, SourceFlag::Database); + const u32 count = manager->GetCount(metadata, SourceFlag::Database); if (new_index < 0 || new_index >= static_cast<s32>(count)) { result = ResultInvalidArgument; } } if (result.IsSuccess()) { - result = manager.Move(metadata, new_index, create_id); + result = manager->Move(metadata, new_index, create_id); } IPC::ResponseBuilder rb{ctx, 2}; @@ -336,7 +338,7 @@ private: } if (result.IsSuccess()) { - result = manager.AddOrReplace(metadata, store_data); + result = manager->AddOrReplace(metadata, store_data); } IPC::ResponseBuilder rb{ctx, 2}; @@ -356,7 +358,7 @@ private: } if (result.IsSuccess()) { - result = manager.Delete(metadata, create_id); + result = manager->Delete(metadata, create_id); } IPC::ResponseBuilder rb{ctx, 2}; @@ -376,7 +378,7 @@ private: } if (result.IsSuccess()) { - result = manager.DestroyFile(metadata); + result = manager->DestroyFile(metadata); } IPC::ResponseBuilder rb{ctx, 2}; @@ -396,7 +398,7 @@ private: } if (result.IsSuccess()) { - result = manager.DeleteFile(); + result = manager->DeleteFile(); } IPC::ResponseBuilder rb{ctx, 2}; @@ -416,7 +418,7 @@ private: } if (result.IsSuccess()) { - result = manager.Format(metadata); + result = manager->Format(metadata); } IPC::ResponseBuilder rb{ctx, 2}; @@ -434,7 +436,7 @@ private: } if (result.IsSuccess()) { - is_broken_with_clear_flag = manager.IsBrokenWithClearFlag(metadata); + is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata); } IPC::ResponseBuilder rb{ctx, 3}; @@ -449,7 +451,7 @@ private: LOG_DEBUG(Service_Mii, "called"); s32 index{}; - const auto result = manager.GetIndex(metadata, info, index); + const auto result = manager->GetIndex(metadata, info, index); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(result); @@ -462,7 +464,7 @@ private: LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version); - manager.SetInterfaceVersion(metadata, interface_version); + manager->SetInterfaceVersion(metadata, interface_version); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -475,7 +477,7 @@ private: LOG_INFO(Service_Mii, "called"); CharInfo char_info{}; - const auto result = manager.ConvertV3ToCharInfo(char_info, mii_v3); + const auto result = manager->ConvertV3ToCharInfo(char_info, mii_v3); IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(result); @@ -489,7 +491,7 @@ private: LOG_INFO(Service_Mii, "called"); CharInfo char_info{}; - const auto result = manager.ConvertCoreDataToCharInfo(char_info, core_data); + const auto result = manager->ConvertCoreDataToCharInfo(char_info, core_data); IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(result); @@ -503,7 +505,7 @@ private: LOG_INFO(Service_Mii, "called"); CoreData core_data{}; - const auto result = manager.ConvertCharInfoToCoreData(core_data, char_info); + const auto result = manager->ConvertCharInfoToCoreData(core_data, char_info); IPC::ResponseBuilder rb{ctx, 2 + sizeof(CoreData) / sizeof(u32)}; rb.Push(result); @@ -516,41 +518,46 @@ private: LOG_INFO(Service_Mii, "called"); - const auto result = manager.Append(metadata, char_info); + const auto result = manager->Append(metadata, char_info); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } - MiiManager manager{}; + std::shared_ptr<MiiManager> manager = nullptr; DatabaseSessionMetadata metadata{}; bool is_system{}; }; -class MiiDBModule final : public ServiceFramework<MiiDBModule> { -public: - explicit MiiDBModule(Core::System& system_, const char* name_, bool is_system_) - : ServiceFramework{system_, name_}, is_system{is_system_} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, - }; - // clang-format on +MiiDBModule::MiiDBModule(Core::System& system_, const char* name_, + std::shared_ptr<MiiManager> mii_manager, bool is_system_) + : ServiceFramework{system_, name_}, manager{mii_manager}, is_system{is_system_} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, + }; + // clang-format on - RegisterHandlers(functions); + RegisterHandlers(functions); + + if (manager == nullptr) { + manager = std::make_shared<MiiManager>(); } +} -private: - void GetDatabaseService(HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IDatabaseService>(system, is_system); +MiiDBModule::~MiiDBModule() = default; - LOG_DEBUG(Service_Mii, "called"); - } +void MiiDBModule::GetDatabaseService(HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IDatabaseService>(system, manager, is_system); - bool is_system{}; -}; + LOG_DEBUG(Service_Mii, "called"); +} + +std::shared_ptr<MiiManager> MiiDBModule::GetMiiManager() { + return manager; +} class MiiImg final : public ServiceFramework<MiiImg> { public: @@ -596,11 +603,12 @@ private: void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); + std::shared_ptr<MiiManager> manager = nullptr; - server_manager->RegisterNamedService("mii:e", - std::make_shared<MiiDBModule>(system, "mii:e", true)); - server_manager->RegisterNamedService("mii:u", - std::make_shared<MiiDBModule>(system, "mii:u", false)); + server_manager->RegisterNamedService( + "mii:e", std::make_shared<MiiDBModule>(system, "mii:e", manager, true)); + server_manager->RegisterNamedService( + "mii:u", std::make_shared<MiiDBModule>(system, "mii:u", manager, false)); server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h index ed4e3f62b..9aa4426f6 100644 --- a/src/core/hle/service/mii/mii.h +++ b/src/core/hle/service/mii/mii.h @@ -3,11 +3,29 @@ #pragma once +#include "core/hle/service/service.h" + namespace Core { class System; } namespace Service::Mii { +class MiiManager; + +class MiiDBModule final : public ServiceFramework<MiiDBModule> { +public: + explicit MiiDBModule(Core::System& system_, const char* name_, + std::shared_ptr<MiiManager> mii_manager, bool is_system_); + ~MiiDBModule() override; + + std::shared_ptr<MiiManager> GetMiiManager(); + +private: + void GetDatabaseService(HLERequestContext& ctx); + + std::shared_ptr<MiiManager> manager = nullptr; + bool is_system{}; +}; void LoopProcess(Core::System& system); diff --git a/src/core/hle/service/mii/mii_database_manager.cpp b/src/core/hle/service/mii/mii_database_manager.cpp index c39898594..0080b6705 100644 --- a/src/core/hle/service/mii/mii_database_manager.cpp +++ b/src/core/hle/service/mii/mii_database_manager.cpp @@ -168,7 +168,7 @@ Result DatabaseManager::FindIndex(s32& out_index, const Common::UUID& create_id, return ResultSuccess; } - for (std::size_t i = 0; i <= index; ++i) { + for (std::size_t i = 0; i < index; ++i) { if (database.Get(i).IsSpecial()) { continue; } diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index a5a2a9232..dcfd6b2e2 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -130,11 +130,11 @@ Result MiiManager::GetIndex(const DatabaseSessionMetadata& metadata, const CharI } s32 index{}; - Result result = {}; - // FindIndex(index); + const bool is_special = metadata.magic == MiiMagic; + const auto result = database_manager.FindIndex(index, char_info.GetCreateId(), is_special); if (result.IsError()) { - return ResultNotFound; + index = -1; } if (index == -1) { 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/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp index 465c6293a..970c748ca 100644 --- a/src/core/hle/service/mii/types/core_data.cpp +++ b/src/core/hle/service/mii/types/core_data.cpp @@ -113,7 +113,7 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { .values[MiiUtil::GetRandomValue<std::size_t>(eyebrow_type_info.values_count)]); const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0}; - const auto eyebrow_y{race == Race::Asian ? 9 : 10}; + const auto eyebrow_y{race == Race::Asian ? 6 : 7}; const auto eyebrow_rotate_offset{32 - RawData::EyebrowRotateLookup[eyebrow_rotate_1] + 6}; const auto eyebrow_rotate{ 32 - RawData::EyebrowRotateLookup[static_cast<std::size_t>(data.eyebrow_type.Value())]}; @@ -171,7 +171,7 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { u8 glasses_type{}; while (glasses_type_start < glasses_type_info.values[glasses_type]) { if (++glasses_type >= glasses_type_info.values_count) { - ASSERT(false); + glasses_type = 0; break; } } @@ -179,6 +179,7 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { SetGlassType(static_cast<GlassType>(glasses_type)); SetGlassColor(RawData::GetGlassColorFromVer3(0)); SetGlassScale(4); + SetGlassY(static_cast<u8>(axis_y + 10)); SetMoleType(MoleType::None); SetMoleScale(4); diff --git a/src/core/hle/service/mii/types/raw_data.cpp b/src/core/hle/service/mii/types/raw_data.cpp index 5143abcc8..0e1a07fd7 100644 --- a/src/core/hle/service/mii/types/raw_data.cpp +++ b/src/core/hle/service/mii/types/raw_data.cpp @@ -1716,18 +1716,18 @@ const std::array<RandomMiiData4, 18> RandomMiiMouthType{ const std::array<RandomMiiData2, 3> RandomMiiGlassType{ RandomMiiData2{ .arg_1 = 0, - .values_count = 9, - .values = {90, 94, 96, 100, 0, 0, 0, 0, 0}, + .values_count = 4, + .values = {90, 94, 96, 100}, }, RandomMiiData2{ .arg_1 = 1, - .values_count = 9, - .values = {83, 86, 90, 93, 94, 96, 98, 100, 0}, + .values_count = 8, + .values = {83, 86, 90, 93, 94, 96, 98, 100}, }, RandomMiiData2{ .arg_1 = 2, - .values_count = 9, - .values = {78, 83, 0, 93, 0, 0, 98, 100, 0}, + .values_count = 8, + .values = {78, 83, 0, 93, 0, 0, 98, 100}, }, }; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 05951d8cb..68c407f81 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -1374,7 +1374,7 @@ NFP::AmiiboName NfcDevice::GetAmiiboName(const NFP::AmiiboSettings& settings) co // Convert from utf16 to utf8 const auto amiibo_name_utf8 = Common::UTF16ToUTF8(settings_amiibo_name.data()); - memcpy(amiibo_name.data(), amiibo_name_utf8.data(), amiibo_name_utf8.size() - 1); + memcpy(amiibo_name.data(), amiibo_name_utf8.data(), amiibo_name_utf8.size()); return amiibo_name; } 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); |