summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/am/am.cpp216
-rw-r--r--src/core/hle/service/am/am.h33
-rw-r--r--src/core/hle/service/am/applet_ae.cpp48
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.cpp52
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.h7
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp65
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp1
-rw-r--r--src/core/hle/service/mii/mii.cpp114
-rw-r--r--src/core/hle/service/mii/mii.h18
-rw-r--r--src/core/hle/service/mii/mii_database_manager.cpp2
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp6
-rw-r--r--src/core/hle/service/mii/mii_types.h2
-rw-r--r--src/core/hle/service/mii/types/core_data.cpp5
-rw-r--r--src/core/hle/service/mii/types/raw_data.cpp12
-rw-r--r--src/core/hle/service/nfc/common/device.cpp2
-rw-r--r--src/core/hle/service/ns/iplatform_service_manager.cpp17
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);