summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/acc/acc.cpp17
-rw-r--r--src/core/hle/service/acc/acc_su.cpp36
-rw-r--r--src/core/hle/service/acc/acc_u1.cpp28
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp118
-rw-r--r--src/core/hle/service/am/am.h2
-rw-r--r--src/core/hle/service/am/applets/applets.cpp18
-rw-r--r--src/core/hle/service/am/applets/applets.h10
-rw-r--r--src/core/hle/service/am/applets/controller.cpp5
-rw-r--r--src/core/hle/service/am/applets/controller.h4
-rw-r--r--src/core/hle/service/am/applets/error.cpp5
-rw-r--r--src/core/hle/service/am/applets/error.h4
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp14
-rw-r--r--src/core/hle/service/am/applets/general_backend.h11
-rw-r--r--src/core/hle/service/am/applets/profile_select.cpp4
-rw-r--r--src/core/hle/service/am/applets/profile_select.h3
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp1153
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h187
-rw-r--r--src/core/hle/service/am/applets/software_keyboard_types.h295
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp5
-rw-r--r--src/core/hle/service/am/applets/web_browser.h4
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp4
-rw-r--r--src/core/hle/service/apm/controller.cpp2
-rw-r--r--src/core/hle/service/audio/audin_a.cpp8
-rw-r--r--src/core/hle/service/audio/audin_u.cpp14
-rw-r--r--src/core/hle/service/audio/audout_a.cpp12
-rw-r--r--src/core/hle/service/audio/audout_u.cpp6
-rw-r--r--src/core/hle/service/audio/audrec_a.cpp4
-rw-r--r--src/core/hle/service/audio/audrec_u.cpp7
-rw-r--r--src/core/hle/service/audio/audren_a.cpp12
-rw-r--r--src/core/hle/service/audio/audren_u.cpp6
-rw-r--r--src/core/hle/service/audio/audren_u.h2
-rw-r--r--src/core/hle/service/audio/codecctl.cpp26
-rw-r--r--src/core/hle/service/audio/hwopus.cpp4
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp2
-rw-r--r--src/core/hle/service/bcat/module.cpp4
-rw-r--r--src/core/hle/service/bpc/bpc.cpp4
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp19
-rw-r--r--src/core/hle/service/btm/btm.cpp1
-rw-r--r--src/core/hle/service/caps/caps_a.cpp1
-rw-r--r--src/core/hle/service/caps/caps_u.cpp1
-rw-r--r--src/core/hle/service/erpt/erpt.cpp7
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp2
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp19
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h2
-rw-r--r--src/core/hle/service/friend/friend.cpp14
-rw-r--r--src/core/hle/service/glue/arp.cpp11
-rw-r--r--src/core/hle/service/glue/arp.h2
-rw-r--r--src/core/hle/service/glue/bgtc.cpp27
-rw-r--r--src/core/hle/service/glue/bgtc.h8
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h2
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h2
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp14
-rw-r--r--src/core/hle/service/hid/controllers/npad.h4
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp108
-rw-r--r--src/core/hle/service/hid/hid.h1
-rw-r--r--src/core/hle/service/hid/xcd.cpp2
-rw-r--r--src/core/hle/service/ldr/ldr.cpp32
-rw-r--r--src/core/hle/service/nfc/nfc.cpp2
-rw-r--r--src/core/hle/service/nifm/nifm.cpp2
-rw-r--r--src/core/hle/service/nim/nim.cpp99
-rw-r--r--src/core/hle/service/npns/npns.cpp3
-rw-r--r--src/core/hle/service/ns/ns.cpp43
-rw-r--r--src/core/hle/service/ns/pl_u.cpp4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp17
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp2
-rw-r--r--src/core/hle/service/olsc/olsc.cpp1
-rw-r--r--src/core/hle/service/pcie/pcie.cpp2
-rw-r--r--src/core/hle/service/pctl/module.cpp251
-rw-r--r--src/core/hle/service/pctl/module.h19
-rw-r--r--src/core/hle/service/pctl/pctl.cpp5
-rw-r--r--src/core/hle/service/pctl/pctl.h3
-rw-r--r--src/core/hle/service/service.cpp6
-rw-r--r--src/core/hle/service/set/set.cpp2
-rw-r--r--src/core/hle/service/set/set_sys.cpp6
-rw-r--r--src/core/hle/service/sm/sm.cpp9
-rw-r--r--src/core/hle/service/sockets/ethc.cpp1
-rw-r--r--src/core/hle/service/sockets/nsd.cpp1
-rw-r--r--src/core/hle/service/sockets/sfdnsres.cpp4
-rw-r--r--src/core/hle/service/spl/module.cpp2
-rw-r--r--src/core/hle/service/spl/spl.cpp3
-rw-r--r--src/core/hle/service/time/clock_types.h8
-rw-r--r--src/core/hle/service/time/time.cpp48
-rw-r--r--src/core/hle/service/time/time.h2
-rw-r--r--src/core/hle/service/time/time_manager.cpp8
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.cpp2
-rw-r--r--src/core/hle/service/time/time_zone_manager.cpp2
-rw-r--r--src/core/hle/service/time/time_zone_service.cpp1
-rw-r--r--src/core/hle/service/time/time_zone_types.h4
-rw-r--r--src/core/hle/service/usb/usb.cpp42
-rw-r--r--src/core/hle/service/vi/vi.cpp10
-rw-r--r--src/core/hle/service/wlan/wlan.cpp7
98 files changed, 2447 insertions, 513 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 615e20a54..52535ecc0 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -610,12 +610,17 @@ public:
explicit DAUTH_O(Core::System& system_, Common::UUID) : ServiceFramework{system_, "dauth:o"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "EnsureAuthenticationTokenCacheAsync"}, // [5.0.0-5.1.0] GeneratePostData
- {1, nullptr, "LoadAuthenticationTokenCache"}, // 6.0.0+
- {2, nullptr, "InvalidateAuthenticationTokenCache"}, // 6.0.0+
- {10, nullptr, "EnsureEdgeTokenCacheAsync"}, // 6.0.0+
- {11, nullptr, "LoadEdgeTokenCache"}, // 6.0.0+
- {12, nullptr, "InvalidateEdgeTokenCache"}, // 6.0.0+
+ {0, nullptr, "EnsureAuthenticationTokenCacheAsync"},
+ {1, nullptr, "LoadAuthenticationTokenCache"},
+ {2, nullptr, "InvalidateAuthenticationTokenCache"},
+ {10, nullptr, "EnsureEdgeTokenCacheAsync"},
+ {11, nullptr, "LoadEdgeTokenCache"},
+ {12, nullptr, "InvalidateEdgeTokenCache"},
+ {20, nullptr, "EnsureApplicationAuthenticationCacheAsync"},
+ {21, nullptr, "LoadApplicationAuthenticationTokenCache"},
+ {22, nullptr, "LoadApplicationNetworkServiceClientConfigCache"},
+ {23, nullptr, "IsApplicationAuthenticationCacheAvailable"},
+ {24, nullptr, "InvalidateApplicationAuthenticationCache"},
};
// clang-format on
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
index 49b22583e..bb6118abf 100644
--- a/src/core/hle/service/acc/acc_su.cpp
+++ b/src/core/hle/service/acc/acc_su.cpp
@@ -17,28 +17,30 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{3, &ACC_SU::ListOpenUsers, "ListOpenUsers"},
{4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"},
{5, &ACC_SU::GetProfile, "GetProfile"},
- {6, nullptr, "GetProfileDigest"}, // 3.0.0+
+ {6, nullptr, "GetProfileDigest"},
{50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
{51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
- {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
- {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
+ {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
+ {99, nullptr, "DebugActivateOpenContextRetention"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
{102, nullptr, "GetBaasAccountManagerForSystemService"},
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{104, nullptr, "GetProfileUpdateNotifier"},
- {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
- {106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
+ {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ {106, nullptr, "GetProfileSyncNotifier"},
{110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{112, nullptr, "LoadSaveDataThumbnail"},
- {113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
- {120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+
- {130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+
- {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
- {150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+
- {190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0
- {191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+
+ {113, nullptr, "GetSaveDataThumbnailExistence"},
+ {120, nullptr, "ListOpenUsersInApplication"},
+ {130, nullptr, "ActivateOpenContextRetention"},
+ {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
+ {150, nullptr, "AuthenticateApplicationAsync"},
+ {151, nullptr, "Unknown151"},
+ {152, nullptr, "Unknown152"},
+ {190, nullptr, "GetUserLastOpenedApplication"},
+ {191, nullptr, "ActivateOpenContextHolder"},
{200, nullptr, "BeginUserRegistration"},
{201, nullptr, "CompleteUserRegistration"},
{202, nullptr, "CancelUserRegistration"},
@@ -46,15 +48,15 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{204, nullptr, "SetUserPosition"},
{205, &ACC_SU::GetProfileEditor, "GetProfileEditor"},
{206, nullptr, "CompleteUserRegistrationForcibly"},
- {210, nullptr, "CreateFloatingRegistrationRequest"}, // 3.0.0+
- {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+
- {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, // 8.0.0+
+ {210, nullptr, "CreateFloatingRegistrationRequest"},
+ {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
+ {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
{230, nullptr, "AuthenticateServiceAsync"},
{250, nullptr, "GetBaasAccountAdministrator"},
{290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
- {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, // 3.0.0+
+ {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
{299, nullptr, "SuspendBackgroundDaemon"},
- {997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+
+ {997, nullptr, "DebugInvalidateTokenCacheForUser"},
{998, nullptr, "DebugSetUserStateClose"},
{999, nullptr, "DebugSetUserStateOpen"},
};
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp
index 951081cd0..71982ad5a 100644
--- a/src/core/hle/service/acc/acc_u1.cpp
+++ b/src/core/hle/service/acc/acc_u1.cpp
@@ -17,29 +17,31 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{3, &ACC_U1::ListOpenUsers, "ListOpenUsers"},
{4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"},
{5, &ACC_U1::GetProfile, "GetProfile"},
- {6, nullptr, "GetProfileDigest"}, // 3.0.0+
+ {6, nullptr, "GetProfileDigest"},
{50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
{51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
- {60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
- {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
+ {60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
+ {99, nullptr, "DebugActivateOpenContextRetention"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
{102, nullptr, "GetBaasAccountManagerForSystemService"},
{103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
{104, nullptr, "GetProfileUpdateNotifier"},
- {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
- {106, nullptr, "GetProfileSyncNotifier"}, // 9.0.0+
+ {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ {106, nullptr, "GetProfileSyncNotifier"},
{110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{112, nullptr, "LoadSaveDataThumbnail"},
- {113, nullptr, "GetSaveDataThumbnailExistence"}, // 5.0.0+
- {120, nullptr, "ListOpenUsersInApplication"}, // 10.0.0+
- {130, nullptr, "ActivateOpenContextRetention"}, // 6.0.0+
- {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
- {150, nullptr, "AuthenticateApplicationAsync"}, // 10.0.0+
- {190, nullptr, "GetUserLastOpenedApplication"}, // 1.0.0 - 9.2.0
- {191, nullptr, "ActivateOpenContextHolder"}, // 7.0.0+
- {997, nullptr, "DebugInvalidateTokenCacheForUser"}, // 3.0.0+
+ {113, nullptr, "GetSaveDataThumbnailExistence"},
+ {120, nullptr, "ListOpenUsersInApplication"},
+ {130, nullptr, "ActivateOpenContextRetention"},
+ {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
+ {150, nullptr, "AuthenticateApplicationAsync"},
+ {151, nullptr, "Unknown151"},
+ {152, nullptr, "Unknown152"},
+ {190, nullptr, "GetUserLastOpenedApplication"},
+ {191, nullptr, "ActivateOpenContextHolder"},
+ {997, nullptr, "DebugInvalidateTokenCacheForUser"},
{998, nullptr, "DebugSetUserStateClose"},
{999, nullptr, "DebugSetUserStateOpen"},
};
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index 50b2c58e2..de83d82a4 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -8,8 +8,8 @@
#include <fmt/format.h>
#include "common/file_util.h"
+#include "common/settings.h"
#include "core/hle/service/acc/profile_manager.h"
-#include "core/settings.h"
namespace Service::Account {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 8e1fe9438..c59054468 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -7,6 +7,7 @@
#include <cinttypes>
#include <cstring>
#include "audio_core/audio_renderer.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -41,7 +42,6 @@
#include "core/hle/service/set/set.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/vi/vi.h"
-#include "core/settings.h"
namespace Service::AM {
@@ -231,6 +231,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
{10, nullptr, "PerformSystemButtonPressing"},
{20, nullptr, "InvalidateTransitionLayer"},
{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
+ {31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
{40, nullptr, "GetAppletResourceUsageInfo"},
{100, nullptr, "SetCpuBoostModeForApplet"},
{101, nullptr, "CancelCpuBoostModeForApplet"},
@@ -242,6 +243,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
{130, nullptr, "FriendInvitationSetApplicationParameter"},
{131, nullptr, "FriendInvitationClearApplicationParameter"},
{132, nullptr, "FriendInvitationPushApplicationParameter"},
+ {900, nullptr, "GetGrcProcessLaunchedSystemEvent"},
};
// clang-format on
@@ -295,8 +297,9 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
{80, nullptr, "SetWirelessPriorityMode"},
{90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"},
{91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
- {100, nullptr, "SetAlbumImageTakenNotificationEnabled"},
+ {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
{110, nullptr, "SetApplicationAlbumUserData"},
+ {120, nullptr, "SaveCurrentScreenshot"},
{1000, nullptr, "GetDebugStorageChannel"},
};
// clang-format on
@@ -560,6 +563,21 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
}
+void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ // This service call sets an internal flag whether a notification is shown when an image is
+ // captured. Currently we do not support capturing images via the capture button, so this can be
+ // stubbed for now.
+ const bool album_image_taken_notification_enabled = rp.Pop<bool>();
+
+ LOG_WARNING(Service_AM, "(STUBBED) called. album_image_taken_notification_enabled={}",
+ album_image_taken_notification_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived");
on_new_message->Initialize();
@@ -630,6 +648,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{11, nullptr, "ReleaseSleepLock"},
{12, nullptr, "ReleaseSleepLockTransiently"},
{13, nullptr, "GetAcquiredSleepLockEvent"},
+ {14, nullptr, "GetWakeupCount"},
{20, nullptr, "PushToGeneralChannel"},
{30, nullptr, "GetHomeButtonReaderLockAccessor"},
{31, nullptr, "GetReaderLockAccessorEx"},
@@ -641,6 +660,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"},
{54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"},
{55, nullptr, "IsInControllerFirmwareUpdateSection"},
+ {59, nullptr, "SetVrPositionForDebug"},
{60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"},
{61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"},
{62, nullptr, "GetHdcpAuthenticationState"},
@@ -649,14 +669,21 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{65, nullptr, "GetApplicationIdByContentActionName"},
{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
{67, nullptr, "CancelCpuBoostMode"},
+ {68, nullptr, "GetBuiltInDisplayType"},
{80, nullptr, "PerformSystemButtonPressingIfInFocus"},
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
{91, nullptr, "GetCurrentPerformanceConfiguration"},
{100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
+ {110, nullptr, "OpenMyGpuErrorHandler"},
{200, nullptr, "GetOperationModeSystemInfo"},
{300, nullptr, "GetSettingsPlatformRegion"},
{400, nullptr, "ActivateMigrationService"},
{401, nullptr, "DeactivateMigrationService"},
+ {500, nullptr, "DisableSleepTillShutdown"},
+ {501, nullptr, "SuppressDisablingSleepTemporarily"},
+ {502, nullptr, "IsSleepEnabled"},
+ {503, nullptr, "IsDisablingSleepSuppressed"},
+ {900, nullptr, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"},
};
// clang-format on
@@ -944,7 +971,7 @@ private:
auto storage = applet->GetBroker().PopNormalDataToGame();
if (storage == nullptr) {
- LOG_ERROR(Service_AM,
+ LOG_DEBUG(Service_AM,
"storage is a nullptr. There is no data in the current normal channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -975,7 +1002,7 @@ private:
auto storage = applet->GetBroker().PopInteractiveDataToGame();
if (storage == nullptr) {
- LOG_ERROR(Service_AM,
+ LOG_DEBUG(Service_AM,
"storage is a nullptr. There is no data in the current interactive channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -1098,7 +1125,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
{2, nullptr, "AreAnyLibraryAppletsLeft"},
{10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
{11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
- {12, nullptr, "CreateHandleStorage"},
+ {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"},
};
RegisterHandlers(functions);
}
@@ -1107,14 +1134,15 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default;
void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
+
const auto applet_id = rp.PopRaw<Applets::AppletId>();
- const auto applet_mode = rp.PopRaw<u32>();
+ const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>();
LOG_DEBUG(Service_AM, "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);
+ 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);
@@ -1132,9 +1160,18 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const u64 size{rp.Pop<u64>()};
+
+ const s64 size{rp.Pop<s64>()};
+
LOG_DEBUG(Service_AM, "called, size={}", size);
+ if (size <= 0) {
+ LOG_ERROR(Service_AM, "size is less than or equal to 0");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
+
std::vector<u8> buffer(size);
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -1143,18 +1180,65 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
}
void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_AM, "called");
+ IPC::RequestParser rp{ctx};
+
+ struct Parameters {
+ u8 permissions;
+ s64 size;
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+ const auto handle{ctx.GetCopyHandle(0)};
+
+ LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions,
+ parameters.size, handle);
+
+ if (parameters.size <= 0) {
+ LOG_ERROR(Service_AM, "size is less than or equal to 0");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
+
+ auto transfer_mem =
+ system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
+
+ if (transfer_mem == nullptr) {
+ LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
+
+ const u8* const mem_begin = transfer_mem->GetPointer();
+ const u8* const mem_end = mem_begin + transfer_mem->GetSize();
+ std::vector<u8> memory{mem_begin, mem_end};
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IStorage>(system, std::move(memory));
+}
+void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- rp.SetCurrentOffset(3);
- const auto handle{rp.Pop<Kernel::Handle>()};
+ const s64 size{rp.Pop<s64>()};
+ const auto handle{ctx.GetCopyHandle(0)};
+
+ LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle);
+
+ if (size <= 0) {
+ LOG_ERROR(Service_AM, "size is less than or equal to 0");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
auto transfer_mem =
system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
if (transfer_mem == nullptr) {
- LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
+ LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
@@ -1188,11 +1272,14 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
{26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
{27, nullptr, "CreateCacheStorage"},
+ {28, nullptr, "GetSaveDataSizeMax"},
+ {29, nullptr, "GetCacheStorageMax"},
{30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
{31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
{32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
{33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
{34, nullptr, "SelectApplicationLicense"},
+ {35, nullptr, "GetDeviceSaveDataSizeMax"},
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
{50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
{60, nullptr, "SetMediaPlaybackStateForApplication"},
@@ -1216,6 +1303,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
{124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
{130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
+ {131, nullptr, "SetDelayTimeToAbortOnGpuError"},
{140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
{141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"},
{150, nullptr, "GetNotificationStorageChannelEvent"},
@@ -1224,6 +1312,8 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{170, nullptr, "SetHdcpAuthenticationActivated"},
{180, nullptr, "GetLaunchRequiredVersion"},
{181, nullptr, "UpgradeLaunchRequiredVersion"},
+ {190, nullptr, "SendServerMaintenanceOverlayNotification"},
+ {200, nullptr, "GetLastApplicationExitReason"},
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
{1000, nullptr, "CreateMovieMaker"},
{1001, nullptr, "PrepareForJit"},
@@ -1690,9 +1780,12 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
{21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"},
{30, nullptr, "GetHomeButtonWriterLockAccessor"},
{31, nullptr, "GetWriterLockAccessorEx"},
+ {40, nullptr, "IsSleepEnabled"},
+ {41, nullptr, "IsRebootEnabled"},
{100, nullptr, "PopRequestLaunchApplicationForDebug"},
{110, nullptr, "IsForceTerminateApplicationDisabledForDebug"},
{200, nullptr, "LaunchDevMenu"},
+ {1000, nullptr, "SetLastApplicationExitReason"},
};
// clang-format on
@@ -1736,6 +1829,7 @@ IGlobalStateController::IGlobalStateController(Core::System& system_)
{13, nullptr, "UpdateDefaultDisplayResolution"},
{14, nullptr, "ShouldSleepOnBoot"},
{15, nullptr, "GetHdcpAuthenticationFailedEvent"},
+ {30, nullptr, "OpenCradleFirmwareUpdater"},
};
// clang-format on
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 6911f0d6e..aefbdf0d5 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -146,6 +146,7 @@ private:
void IsAutoSleepDisabled(Kernel::HLERequestContext& ctx);
void GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx);
void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
+ void SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx);
enum class ScreenshotPermission : u32 {
Inherit = 0,
@@ -253,6 +254,7 @@ private:
void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
void CreateStorage(Kernel::HLERequestContext& ctx);
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
+ void CreateHandleStorage(Kernel::HLERequestContext& ctx);
};
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index e2f3b7563..5ddad851a 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -241,31 +241,31 @@ void AppletManager::ClearAll() {
frontend = {};
}
-std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const {
+std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode mode) const {
switch (id) {
case AppletId::Auth:
- return std::make_shared<Auth>(system, *frontend.parental_controls);
+ return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
case AppletId::Controller:
- return std::make_shared<Controller>(system, *frontend.controller);
+ return std::make_shared<Controller>(system, mode, *frontend.controller);
case AppletId::Error:
- return std::make_shared<Error>(system, *frontend.error);
+ return std::make_shared<Error>(system, mode, *frontend.error);
case AppletId::ProfileSelect:
- return std::make_shared<ProfileSelect>(system, *frontend.profile_select);
+ return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select);
case AppletId::SoftwareKeyboard:
- return std::make_shared<SoftwareKeyboard>(system, *frontend.software_keyboard);
+ return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard);
case AppletId::Web:
case AppletId::Shop:
case AppletId::OfflineWeb:
case AppletId::LoginShare:
case AppletId::WebAuth:
- return std::make_shared<WebBrowser>(system, *frontend.web_browser);
+ return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser);
case AppletId::PhotoViewer:
- return std::make_shared<PhotoViewer>(system, *frontend.photo_viewer);
+ return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer);
default:
UNIMPLEMENTED_MSG(
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
static_cast<u8>(id));
- return std::make_shared<StubApplet>(system, id);
+ return std::make_shared<StubApplet>(system, id, mode);
}
}
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index b9a006317..26b482015 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -62,6 +62,14 @@ enum class AppletId : u32 {
MyPage = 0x1A,
};
+enum class LibraryAppletMode : u32 {
+ AllForeground = 0,
+ Background = 1,
+ NoUI = 2,
+ BackgroundIndirectDisplay = 3,
+ AllForegroundInitiallyHidden = 4,
+};
+
class AppletDataBroker final {
public:
explicit AppletDataBroker(Kernel::KernelCore& kernel_);
@@ -200,7 +208,7 @@ public:
void SetDefaultAppletsIfMissing();
void ClearAll();
- std::shared_ptr<Applet> GetApplet(AppletId id) const;
+ std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const;
private:
AppletFrontendSet frontend;
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index c2bfe698f..a33f05f97 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -45,8 +45,9 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
};
}
-Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_)
- : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
+Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::ControllerApplet& frontend_)
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
Controller::~Controller() = default;
diff --git a/src/core/hle/service/am/applets/controller.h b/src/core/hle/service/am/applets/controller.h
index d4c9da7b1..07cb92bf9 100644
--- a/src/core/hle/service/am/applets/controller.h
+++ b/src/core/hle/service/am/applets/controller.h
@@ -106,7 +106,8 @@ static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
class Controller final : public Applet {
public:
- explicit Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_);
+ explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::ControllerApplet& frontend_);
~Controller() override;
void Initialize() override;
@@ -119,6 +120,7 @@ public:
void ConfigurationComplete();
private:
+ LibraryAppletMode applet_mode;
const Core::Frontend::ControllerApplet& frontend;
Core::System& system;
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
index 0c8b632e8..a9f0a9c95 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -86,8 +86,9 @@ ResultCode Decode64BitError(u64 error) {
} // Anonymous namespace
-Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_)
- : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
+Error::Error(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::ErrorApplet& frontend_)
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
Error::~Error() = default;
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/error.h
index a105cdb0c..a3e520cd4 100644
--- a/src/core/hle/service/am/applets/error.h
+++ b/src/core/hle/service/am/applets/error.h
@@ -25,7 +25,8 @@ enum class ErrorAppletMode : u8 {
class Error final : public Applet {
public:
- explicit Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_);
+ explicit Error(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::ErrorApplet& frontend_);
~Error() override;
void Initialize() override;
@@ -40,6 +41,7 @@ public:
private:
union ErrorArguments;
+ LibraryAppletMode applet_mode;
const Core::Frontend::ErrorApplet& frontend;
ResultCode error_code = RESULT_SUCCESS;
ErrorAppletMode mode = ErrorAppletMode::ShowError;
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp
index 4d1df5cbe..71016cce7 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/general_backend.cpp
@@ -37,8 +37,9 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
}
}
-Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_)
- : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
+Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_,
+ Core::Frontend::ParentalControlsApplet& frontend_)
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
Auth::~Auth() = default;
@@ -152,8 +153,9 @@ void Auth::AuthFinished(bool is_successful) {
broker.SignalStateChanged();
}
-PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_)
- : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
+PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::PhotoViewerApplet& frontend_)
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
PhotoViewer::~PhotoViewer() = default;
@@ -202,8 +204,8 @@ void PhotoViewer::ViewFinished() {
broker.SignalStateChanged();
}
-StubApplet::StubApplet(Core::System& system_, AppletId id_)
- : Applet{system_.Kernel()}, id{id_}, system{system_} {}
+StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
+ : Applet{system_.Kernel()}, id{id_}, applet_mode{applet_mode_}, system{system_} {}
StubApplet::~StubApplet() = default;
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h
index ba76ae3d3..d9e6d4384 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/general_backend.h
@@ -20,7 +20,8 @@ enum class AuthAppletType : u32 {
class Auth final : public Applet {
public:
- explicit Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_);
+ explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_,
+ Core::Frontend::ParentalControlsApplet& frontend_);
~Auth() override;
void Initialize() override;
@@ -32,6 +33,7 @@ public:
void AuthFinished(bool is_successful = true);
private:
+ LibraryAppletMode applet_mode;
Core::Frontend::ParentalControlsApplet& frontend;
Core::System& system;
bool complete = false;
@@ -50,7 +52,8 @@ enum class PhotoViewerAppletMode : u8 {
class PhotoViewer final : public Applet {
public:
- explicit PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_);
+ explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::PhotoViewerApplet& frontend_);
~PhotoViewer() override;
void Initialize() override;
@@ -62,6 +65,7 @@ public:
void ViewFinished();
private:
+ LibraryAppletMode applet_mode;
const Core::Frontend::PhotoViewerApplet& frontend;
bool complete = false;
PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
@@ -70,7 +74,7 @@ private:
class StubApplet final : public Applet {
public:
- explicit StubApplet(Core::System& system_, AppletId id_);
+ explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_);
~StubApplet() override;
void Initialize() override;
@@ -82,6 +86,7 @@ public:
private:
AppletId id;
+ LibraryAppletMode applet_mode;
Core::System& system;
};
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp
index 77fba16c7..ab8b6fcc5 100644
--- a/src/core/hle/service/am/applets/profile_select.cpp
+++ b/src/core/hle/service/am/applets/profile_select.cpp
@@ -15,9 +15,9 @@ namespace Service::AM::Applets {
constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
-ProfileSelect::ProfileSelect(Core::System& system_,
+ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::ProfileSelectApplet& frontend_)
- : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
ProfileSelect::~ProfileSelect() = default;
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h
index 648d33a24..90f054030 100644
--- a/src/core/hle/service/am/applets/profile_select.h
+++ b/src/core/hle/service/am/applets/profile_select.h
@@ -33,7 +33,7 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco
class ProfileSelect final : public Applet {
public:
- explicit ProfileSelect(Core::System& system_,
+ explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::ProfileSelectApplet& frontend_);
~ProfileSelect() override;
@@ -47,6 +47,7 @@ public:
void SelectionComplete(std::optional<Common::UUID> uuid);
private:
+ LibraryAppletMode applet_mode;
const Core::Frontend::ProfileSelectApplet& frontend;
UserSelectionConfig config;
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index 79b209c6b..c3a05de9c 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -1,93 +1,80 @@
-// Copyright 2018 yuzu emulator team
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include <cstring>
-#include "common/assert.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/frontend/applets/software_keyboard.h"
-#include "core/hle/result.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/software_keyboard.h"
namespace Service::AM::Applets {
namespace {
-enum class Request : u32 {
- Finalize = 0x4,
- SetUserWordInfo = 0x6,
- SetCustomizeDic = 0x7,
- Calc = 0xa,
- SetCustomizedDictionaries = 0xb,
- UnsetCustomizedDictionaries = 0xc,
- UnknownD = 0xd,
- UnknownE = 0xe,
-};
-constexpr std::size_t SWKBD_INLINE_INIT_SIZE = 0x8;
-constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8;
-constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4;
-constexpr std::size_t DEFAULT_MAX_LENGTH = 500;
-constexpr bool INTERACTIVE_STATUS_OK = false;
+
+// The maximum number of UTF-16 characters that can be input into the swkbd text field.
+constexpr u32 DEFAULT_MAX_TEXT_LENGTH = 500;
+
+constexpr std::size_t REPLY_BASE_SIZE = sizeof(SwkbdState) + sizeof(SwkbdReplyType);
+constexpr std::size_t REPLY_UTF8_SIZE = 0x7D4;
+constexpr std::size_t REPLY_UTF16_SIZE = 0x3EC;
+
+constexpr const char* GetTextCheckResultName(SwkbdTextCheckResult text_check_result) {
+ switch (text_check_result) {
+ case SwkbdTextCheckResult::Success:
+ return "Success";
+ case SwkbdTextCheckResult::Failure:
+ return "Failure";
+ case SwkbdTextCheckResult::Confirm:
+ return "Confirm";
+ case SwkbdTextCheckResult::Silent:
+ return "Silent";
+ default:
+ UNIMPLEMENTED_MSG("Unknown TextCheckResult={}", text_check_result);
+ return "Unknown";
+ }
+}
+
+void SetReplyBase(std::vector<u8>& reply, SwkbdState state, SwkbdReplyType reply_type) {
+ std::memcpy(reply.data(), &state, sizeof(SwkbdState));
+ std::memcpy(reply.data() + sizeof(SwkbdState), &reply_type, sizeof(SwkbdReplyType));
+}
+
} // Anonymous namespace
-static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
- KeyboardConfig config, std::u16string initial_text) {
- Core::Frontend::SoftwareKeyboardParameters params{};
-
- params.submit_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
- config.submit_text.data(), config.submit_text.size());
- params.header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
- config.header_text.data(), config.header_text.size());
- params.sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(config.sub_text.data(),
- config.sub_text.size());
- params.guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(config.guide_text.data(),
- config.guide_text.size());
- params.initial_text = std::move(initial_text);
- params.max_length = config.length_limit == 0 ? DEFAULT_MAX_LENGTH : config.length_limit;
- params.password = static_cast<bool>(config.is_password);
- params.cursor_at_beginning = static_cast<bool>(config.initial_cursor_position);
- params.value = static_cast<u8>(config.keyset_disable_bitmask);
-
- return params;
-}
-
-SoftwareKeyboard::SoftwareKeyboard(Core::System& system_,
- const Core::Frontend::SoftwareKeyboardApplet& frontend_)
- : Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
+
+SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
+ Core::Frontend::SoftwareKeyboardApplet& frontend_)
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
SoftwareKeyboard::~SoftwareKeyboard() = default;
void SoftwareKeyboard::Initialize() {
- complete = false;
- is_inline = false;
- initial_text.clear();
- final_data.clear();
-
Applet::Initialize();
- const auto keyboard_config_storage = broker.PopNormalDataToApplet();
- ASSERT(keyboard_config_storage != nullptr);
- const auto& keyboard_config = keyboard_config_storage->GetData();
-
- if (keyboard_config.size() == SWKBD_INLINE_INIT_SIZE) {
- is_inline = true;
- return;
- }
-
- ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig));
- std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig));
+ LOG_INFO(Service_AM, "Initializing Software Keyboard Applet with LibraryAppletMode={}",
+ applet_mode);
- const auto work_buffer_storage = broker.PopNormalDataToApplet();
- ASSERT_OR_EXECUTE(work_buffer_storage != nullptr, { return; });
- const auto& work_buffer = work_buffer_storage->GetData();
+ LOG_DEBUG(Service_AM,
+ "Initializing Applet with common_args: arg_version={}, lib_version={}, "
+ "play_startup_sound={}, size={}, system_tick={}, theme_color={}",
+ common_args.arguments_version, common_args.library_version,
+ common_args.play_startup_sound, common_args.size, common_args.system_tick,
+ common_args.theme_color);
- if (config.initial_string_size == 0)
- return;
+ swkbd_applet_version = SwkbdAppletVersion{common_args.library_version};
- std::vector<char16_t> string(config.initial_string_size);
- std::memcpy(string.data(), work_buffer.data() + config.initial_string_offset,
- string.size() * 2);
- initial_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size());
+ switch (applet_mode) {
+ case LibraryAppletMode::AllForeground:
+ InitializeForeground();
+ break;
+ case LibraryAppletMode::Background:
+ case LibraryAppletMode::BackgroundIndirectDisplay:
+ InitializeBackground(applet_mode);
+ break;
+ default:
+ UNREACHABLE_MSG("Invalid LibraryAppletMode={}", applet_mode);
+ break;
+ }
}
bool SoftwareKeyboard::TransactionComplete() const {
@@ -95,106 +82,996 @@ bool SoftwareKeyboard::TransactionComplete() const {
}
ResultCode SoftwareKeyboard::GetStatus() const {
- return RESULT_SUCCESS;
+ return status;
}
void SoftwareKeyboard::ExecuteInteractive() {
- if (complete)
+ if (complete) {
return;
+ }
- const auto storage = broker.PopInteractiveDataToApplet();
- ASSERT(storage != nullptr);
- const auto data = storage->GetData();
- if (!is_inline) {
- const auto status = static_cast<bool>(data[0]);
- if (status == INTERACTIVE_STATUS_OK) {
- complete = true;
- } else {
- std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
- std::memcpy(string.data(), data.data() + 4, string.size() * 2);
- frontend.SendTextCheckDialog(
- Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
- [this] { broker.SignalStateChanged(); });
- }
+ if (is_background) {
+ ProcessInlineKeyboardRequest();
} else {
- Request request{};
- std::memcpy(&request, data.data(), sizeof(Request));
+ ProcessTextCheck();
+ }
+}
+
+void SoftwareKeyboard::Execute() {
+ if (complete) {
+ return;
+ }
+
+ if (is_background) {
+ return;
+ }
+
+ ShowNormalKeyboard();
+}
- switch (request) {
- case Request::Finalize:
- complete = true;
- broker.SignalStateChanged();
+void SoftwareKeyboard::SubmitTextNormal(SwkbdResult result, std::u16string submitted_text) {
+ if (complete) {
+ return;
+ }
+
+ if (swkbd_config_common.use_text_check && result == SwkbdResult::Ok) {
+ SubmitForTextCheck(submitted_text);
+ } else {
+ SubmitNormalOutputAndExit(result, submitted_text);
+ }
+}
+
+void SoftwareKeyboard::SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text,
+ s32 cursor_position) {
+ if (complete) {
+ return;
+ }
+
+ current_text = std::move(submitted_text);
+ current_cursor_position = cursor_position;
+
+ if (inline_use_utf8) {
+ switch (reply_type) {
+ case SwkbdReplyType::ChangedString:
+ reply_type = SwkbdReplyType::ChangedStringUtf8;
break;
- case Request::Calc: {
- broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{1}));
- broker.SignalStateChanged();
+ case SwkbdReplyType::MovedCursor:
+ reply_type = SwkbdReplyType::MovedCursorUtf8;
+ break;
+ case SwkbdReplyType::DecidedEnter:
+ reply_type = SwkbdReplyType::DecidedEnterUtf8;
+ break;
+ default:
break;
}
+ }
+
+ if (use_changed_string_v2) {
+ switch (reply_type) {
+ case SwkbdReplyType::ChangedString:
+ reply_type = SwkbdReplyType::ChangedStringV2;
+ break;
+ case SwkbdReplyType::ChangedStringUtf8:
+ reply_type = SwkbdReplyType::ChangedStringUtf8V2;
+ break;
default:
- UNIMPLEMENTED_MSG("Request {:X} is not implemented", request);
break;
}
}
+
+ if (use_moved_cursor_v2) {
+ switch (reply_type) {
+ case SwkbdReplyType::MovedCursor:
+ reply_type = SwkbdReplyType::MovedCursorV2;
+ break;
+ case SwkbdReplyType::MovedCursorUtf8:
+ reply_type = SwkbdReplyType::MovedCursorUtf8V2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ SendReply(reply_type);
}
-void SoftwareKeyboard::Execute() {
- if (complete) {
- broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
- broker.SignalStateChanged();
+void SoftwareKeyboard::InitializeForeground() {
+ LOG_INFO(Service_AM, "Initializing Normal Software Keyboard Applet.");
+
+ is_background = false;
+
+ const auto swkbd_config_storage = broker.PopNormalDataToApplet();
+ ASSERT(swkbd_config_storage != nullptr);
+
+ const auto& swkbd_config_data = swkbd_config_storage->GetData();
+ ASSERT(swkbd_config_data.size() >= sizeof(SwkbdConfigCommon));
+
+ std::memcpy(&swkbd_config_common, swkbd_config_data.data(), sizeof(SwkbdConfigCommon));
+
+ switch (swkbd_applet_version) {
+ case SwkbdAppletVersion::Version5:
+ case SwkbdAppletVersion::Version65542:
+ ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigOld));
+ std::memcpy(&swkbd_config_old, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
+ sizeof(SwkbdConfigOld));
+ break;
+ case SwkbdAppletVersion::Version196615:
+ case SwkbdAppletVersion::Version262152:
+ case SwkbdAppletVersion::Version327689:
+ ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigOld2));
+ std::memcpy(&swkbd_config_old2, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
+ sizeof(SwkbdConfigOld2));
+ break;
+ case SwkbdAppletVersion::Version393227:
+ case SwkbdAppletVersion::Version524301:
+ ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigNew));
+ std::memcpy(&swkbd_config_new, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
+ sizeof(SwkbdConfigNew));
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown SwkbdConfig revision={} with size={}", swkbd_applet_version,
+ swkbd_config_data.size());
+ ASSERT(swkbd_config_data.size() >= sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigNew));
+ std::memcpy(&swkbd_config_new, swkbd_config_data.data() + sizeof(SwkbdConfigCommon),
+ sizeof(SwkbdConfigNew));
+ break;
+ }
+
+ const auto work_buffer_storage = broker.PopNormalDataToApplet();
+ ASSERT(work_buffer_storage != nullptr);
+
+ if (swkbd_config_common.initial_string_length == 0) {
+ InitializeFrontendKeyboard();
return;
}
- const auto parameters = ConvertToFrontendParameters(config, initial_text);
- if (!is_inline) {
- frontend.RequestText(
- [this](std::optional<std::u16string> text) { WriteText(std::move(text)); }, parameters);
+ const auto& work_buffer = work_buffer_storage->GetData();
+
+ std::vector<char16_t> initial_string(swkbd_config_common.initial_string_length);
+
+ std::memcpy(initial_string.data(),
+ work_buffer.data() + swkbd_config_common.initial_string_offset,
+ swkbd_config_common.initial_string_length * sizeof(char16_t));
+
+ initial_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(initial_string.data(),
+ initial_string.size());
+
+ LOG_DEBUG(Service_AM, "\nInitial Text: {}", Common::UTF16ToUTF8(initial_text));
+
+ InitializeFrontendKeyboard();
+}
+
+void SoftwareKeyboard::InitializeBackground(LibraryAppletMode applet_mode) {
+ LOG_INFO(Service_AM, "Initializing Inline Software Keyboard Applet.");
+
+ is_background = true;
+
+ const auto swkbd_inline_initialize_arg_storage = broker.PopNormalDataToApplet();
+ ASSERT(swkbd_inline_initialize_arg_storage != nullptr);
+
+ const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData();
+ ASSERT(swkbd_inline_initialize_arg.size() == sizeof(SwkbdInitializeArg));
+
+ std::memcpy(&swkbd_initialize_arg, swkbd_inline_initialize_arg.data(),
+ swkbd_inline_initialize_arg.size());
+
+ if (swkbd_initialize_arg.library_applet_mode_flag) {
+ ASSERT(applet_mode == LibraryAppletMode::Background);
+ } else {
+ ASSERT(applet_mode == LibraryAppletMode::BackgroundIndirectDisplay);
+ }
+}
+
+void SoftwareKeyboard::ProcessTextCheck() {
+ const auto text_check_storage = broker.PopInteractiveDataToApplet();
+ ASSERT(text_check_storage != nullptr);
+
+ const auto& text_check_data = text_check_storage->GetData();
+ ASSERT(text_check_data.size() == sizeof(SwkbdTextCheck));
+
+ SwkbdTextCheck swkbd_text_check;
+
+ std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck));
+
+ std::u16string text_check_message = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ swkbd_text_check.text_check_message.data(), swkbd_text_check.text_check_message.size());
+
+ LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}",
+ GetTextCheckResultName(swkbd_text_check.text_check_result),
+ Common::UTF16ToUTF8(text_check_message));
+
+ switch (swkbd_text_check.text_check_result) {
+ case SwkbdTextCheckResult::Success:
+ SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text);
+ break;
+ case SwkbdTextCheckResult::Failure:
+ ShowTextCheckDialog(SwkbdTextCheckResult::Failure, text_check_message);
+ break;
+ case SwkbdTextCheckResult::Confirm:
+ ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, text_check_message);
+ break;
+ case SwkbdTextCheckResult::Silent:
+ default:
+ break;
}
}
-void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
- std::vector<u8> output_main(SWKBD_OUTPUT_BUFFER_SIZE);
+void SoftwareKeyboard::ProcessInlineKeyboardRequest() {
+ const auto request_data_storage = broker.PopInteractiveDataToApplet();
+ ASSERT(request_data_storage != nullptr);
+
+ const auto& request_data = request_data_storage->GetData();
+ ASSERT(request_data.size() >= sizeof(SwkbdRequestCommand));
- if (text.has_value()) {
- std::vector<u8> output_sub(SWKBD_OUTPUT_BUFFER_SIZE);
+ SwkbdRequestCommand request_command;
- if (config.utf_8) {
- const u64 size = text->size() + sizeof(u64);
- const auto new_text = Common::UTF16ToUTF8(*text);
+ std::memcpy(&request_command, request_data.data(), sizeof(SwkbdRequestCommand));
- std::memcpy(output_sub.data(), &size, sizeof(u64));
- std::memcpy(output_sub.data() + 8, new_text.data(),
- std::min(new_text.size(), SWKBD_OUTPUT_BUFFER_SIZE - 8));
+ switch (request_command) {
+ case SwkbdRequestCommand::Finalize:
+ RequestFinalize(request_data);
+ break;
+ case SwkbdRequestCommand::SetUserWordInfo:
+ RequestSetUserWordInfo(request_data);
+ break;
+ case SwkbdRequestCommand::SetCustomizeDic:
+ RequestSetCustomizeDic(request_data);
+ break;
+ case SwkbdRequestCommand::Calc:
+ RequestCalc(request_data);
+ break;
+ case SwkbdRequestCommand::SetCustomizedDictionaries:
+ RequestSetCustomizedDictionaries(request_data);
+ break;
+ case SwkbdRequestCommand::UnsetCustomizedDictionaries:
+ RequestUnsetCustomizedDictionaries(request_data);
+ break;
+ case SwkbdRequestCommand::SetChangedStringV2Flag:
+ RequestSetChangedStringV2Flag(request_data);
+ break;
+ case SwkbdRequestCommand::SetMovedCursorV2Flag:
+ RequestSetMovedCursorV2Flag(request_data);
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown SwkbdRequestCommand={}", request_command);
+ break;
+ }
+}
- output_main[0] = INTERACTIVE_STATUS_OK;
- std::memcpy(output_main.data() + 4, new_text.data(),
- std::min(new_text.size(), SWKBD_OUTPUT_BUFFER_SIZE - 4));
- } else {
- const u64 size = text->size() * 2 + sizeof(u64);
- std::memcpy(output_sub.data(), &size, sizeof(u64));
- std::memcpy(output_sub.data() + 8, text->data(),
- std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 8));
+void SoftwareKeyboard::SubmitNormalOutputAndExit(SwkbdResult result,
+ std::u16string submitted_text) {
+ std::vector<u8> out_data(sizeof(SwkbdResult) + STRING_BUFFER_SIZE);
- output_main[0] = INTERACTIVE_STATUS_OK;
- std::memcpy(output_main.data() + 4, text->data(),
- std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4));
- }
+ if (swkbd_config_common.use_utf8) {
+ std::string utf8_submitted_text = Common::UTF16ToUTF8(submitted_text);
- complete = !config.text_check;
- final_data = output_main;
+ LOG_DEBUG(Service_AM, "\nSwkbdResult: {}\nUTF-8 Submitted Text: {}", result,
+ utf8_submitted_text);
- if (complete) {
- broker.PushNormalDataFromApplet(
- std::make_shared<IStorage>(system, std::move(output_main)));
- broker.SignalStateChanged();
- } else {
- broker.PushInteractiveDataFromApplet(
- std::make_shared<IStorage>(system, std::move(output_sub)));
- }
+ std::memcpy(out_data.data(), &result, sizeof(SwkbdResult));
+ std::memcpy(out_data.data() + sizeof(SwkbdResult), utf8_submitted_text.data(),
+ utf8_submitted_text.size());
} else {
- output_main[0] = 1;
- complete = true;
- broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(output_main)));
- broker.SignalStateChanged();
+ LOG_DEBUG(Service_AM, "\nSwkbdResult: {}\nUTF-16 Submitted Text: {}", result,
+ Common::UTF16ToUTF8(submitted_text));
+
+ std::memcpy(out_data.data(), &result, sizeof(SwkbdResult));
+ std::memcpy(out_data.data() + sizeof(SwkbdResult), submitted_text.data(),
+ submitted_text.size() * sizeof(char16_t));
+ }
+
+ broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
+
+ ExitKeyboard();
+}
+
+void SoftwareKeyboard::SubmitForTextCheck(std::u16string submitted_text) {
+ current_text = std::move(submitted_text);
+
+ std::vector<u8> out_data(sizeof(u64) + STRING_BUFFER_SIZE);
+
+ if (swkbd_config_common.use_utf8) {
+ std::string utf8_submitted_text = Common::UTF16ToUTF8(current_text);
+ const u64 buffer_size = sizeof(u64) + utf8_submitted_text.size();
+
+ LOG_DEBUG(Service_AM, "\nBuffer Size: {}\nUTF-8 Submitted Text: {}", buffer_size,
+ utf8_submitted_text);
+
+ std::memcpy(out_data.data(), &buffer_size, sizeof(u64));
+ std::memcpy(out_data.data() + sizeof(u64), utf8_submitted_text.data(),
+ utf8_submitted_text.size());
+ } else {
+ const u64 buffer_size = sizeof(u64) + current_text.size() * sizeof(char16_t);
+
+ LOG_DEBUG(Service_AM, "\nBuffer Size: {}\nUTF-16 Submitted Text: {}", buffer_size,
+ Common::UTF16ToUTF8(current_text));
+
+ std::memcpy(out_data.data(), &buffer_size, sizeof(u64));
+ std::memcpy(out_data.data() + sizeof(u64), current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ }
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
+}
+
+void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) {
+ switch (reply_type) {
+ case SwkbdReplyType::FinishedInitialize:
+ ReplyFinishedInitialize();
+ break;
+ case SwkbdReplyType::Default:
+ ReplyDefault();
+ break;
+ case SwkbdReplyType::ChangedString:
+ ReplyChangedString();
+ break;
+ case SwkbdReplyType::MovedCursor:
+ ReplyMovedCursor();
+ break;
+ case SwkbdReplyType::MovedTab:
+ ReplyMovedTab();
+ break;
+ case SwkbdReplyType::DecidedEnter:
+ ReplyDecidedEnter();
+ break;
+ case SwkbdReplyType::DecidedCancel:
+ ReplyDecidedCancel();
+ break;
+ case SwkbdReplyType::ChangedStringUtf8:
+ ReplyChangedStringUtf8();
+ break;
+ case SwkbdReplyType::MovedCursorUtf8:
+ ReplyMovedCursorUtf8();
+ break;
+ case SwkbdReplyType::DecidedEnterUtf8:
+ ReplyDecidedEnterUtf8();
+ break;
+ case SwkbdReplyType::UnsetCustomizeDic:
+ ReplyUnsetCustomizeDic();
+ break;
+ case SwkbdReplyType::ReleasedUserWordInfo:
+ ReplyReleasedUserWordInfo();
+ break;
+ case SwkbdReplyType::UnsetCustomizedDictionaries:
+ ReplyUnsetCustomizedDictionaries();
+ break;
+ case SwkbdReplyType::ChangedStringV2:
+ ReplyChangedStringV2();
+ break;
+ case SwkbdReplyType::MovedCursorV2:
+ ReplyMovedCursorV2();
+ break;
+ case SwkbdReplyType::ChangedStringUtf8V2:
+ ReplyChangedStringUtf8V2();
+ break;
+ case SwkbdReplyType::MovedCursorUtf8V2:
+ ReplyMovedCursorUtf8V2();
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown SwkbdReplyType={}", reply_type);
+ ReplyDefault();
+ break;
+ }
+}
+
+void SoftwareKeyboard::ChangeState(SwkbdState state) {
+ swkbd_state = state;
+
+ ReplyDefault();
+}
+
+void SoftwareKeyboard::InitializeFrontendKeyboard() {
+ if (is_background) {
+ const auto& appear_arg = swkbd_calc_arg.appear_arg;
+
+ std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ appear_arg.ok_text.data(), appear_arg.ok_text.size());
+
+ const u32 max_text_length =
+ appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
+ ? appear_arg.max_text_length
+ : DEFAULT_MAX_TEXT_LENGTH;
+
+ const u32 min_text_length =
+ appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0;
+
+ const s32 initial_cursor_position =
+ current_cursor_position > 0 ? current_cursor_position : 0;
+
+ const auto text_draw_type =
+ max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
+
+ Core::Frontend::KeyboardInitializeParameters initialize_parameters{
+ .ok_text{ok_text},
+ .header_text{},
+ .sub_text{},
+ .guide_text{},
+ .initial_text{current_text},
+ .max_text_length{max_text_length},
+ .min_text_length{min_text_length},
+ .initial_cursor_position{initial_cursor_position},
+ .type{appear_arg.type},
+ .password_mode{SwkbdPasswordMode::Disabled},
+ .text_draw_type{text_draw_type},
+ .key_disable_flags{appear_arg.key_disable_flags},
+ .use_blur_background{false},
+ .enable_backspace_button{swkbd_calc_arg.enable_backspace_button},
+ .enable_return_button{appear_arg.enable_return_button},
+ .disable_cancel_button{appear_arg.disable_cancel_button},
+ };
+
+ frontend.InitializeKeyboard(
+ true, std::move(initialize_parameters), {},
+ [this](SwkbdReplyType reply_type, std::u16string submitted_text, s32 cursor_position) {
+ SubmitTextInline(reply_type, submitted_text, cursor_position);
+ });
+ } else {
+ std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ swkbd_config_common.ok_text.data(), swkbd_config_common.ok_text.size());
+
+ std::u16string header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ swkbd_config_common.header_text.data(), swkbd_config_common.header_text.size());
+
+ std::u16string sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ swkbd_config_common.sub_text.data(), swkbd_config_common.sub_text.size());
+
+ std::u16string guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ swkbd_config_common.guide_text.data(), swkbd_config_common.guide_text.size());
+
+ const u32 max_text_length =
+ swkbd_config_common.max_text_length > 0 &&
+ swkbd_config_common.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
+ ? swkbd_config_common.max_text_length
+ : DEFAULT_MAX_TEXT_LENGTH;
+
+ const u32 min_text_length = swkbd_config_common.min_text_length <= max_text_length
+ ? swkbd_config_common.min_text_length
+ : 0;
+
+ const s32 initial_cursor_position = [this] {
+ switch (swkbd_config_common.initial_cursor_position) {
+ case SwkbdInitialCursorPosition::Start:
+ default:
+ return 0;
+ case SwkbdInitialCursorPosition::End:
+ return static_cast<s32>(initial_text.size());
+ }
+ }();
+
+ const auto text_draw_type = [this, max_text_length] {
+ switch (swkbd_config_common.text_draw_type) {
+ case SwkbdTextDrawType::Line:
+ default:
+ return max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
+ case SwkbdTextDrawType::Box:
+ case SwkbdTextDrawType::DownloadCode:
+ return swkbd_config_common.text_draw_type;
+ }
+ }();
+
+ const auto enable_return_button = text_draw_type == SwkbdTextDrawType::Box
+ ? swkbd_config_common.enable_return_button
+ : false;
+
+ const auto disable_cancel_button = swkbd_applet_version >= SwkbdAppletVersion::Version393227
+ ? swkbd_config_new.disable_cancel_button
+ : false;
+
+ Core::Frontend::KeyboardInitializeParameters initialize_parameters{
+ .ok_text{ok_text},
+ .header_text{header_text},
+ .sub_text{sub_text},
+ .guide_text{guide_text},
+ .initial_text{initial_text},
+ .max_text_length{max_text_length},
+ .min_text_length{min_text_length},
+ .initial_cursor_position{initial_cursor_position},
+ .type{swkbd_config_common.type},
+ .password_mode{swkbd_config_common.password_mode},
+ .text_draw_type{text_draw_type},
+ .key_disable_flags{swkbd_config_common.key_disable_flags},
+ .use_blur_background{swkbd_config_common.use_blur_background},
+ .enable_backspace_button{true},
+ .enable_return_button{enable_return_button},
+ .disable_cancel_button{disable_cancel_button},
+ };
+
+ frontend.InitializeKeyboard(false, std::move(initialize_parameters),
+ [this](SwkbdResult result, std::u16string submitted_text) {
+ SubmitTextNormal(result, submitted_text);
+ },
+ {});
+ }
+}
+
+void SoftwareKeyboard::ShowNormalKeyboard() {
+ frontend.ShowNormalKeyboard();
+}
+
+void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
+ std::u16string text_check_message) {
+ frontend.ShowTextCheckDialog(text_check_result, text_check_message);
+}
+
+void SoftwareKeyboard::ShowInlineKeyboard() {
+ if (swkbd_state != SwkbdState::InitializedIsHidden) {
+ return;
+ }
+
+ ChangeState(SwkbdState::InitializedIsAppearing);
+
+ const auto& appear_arg = swkbd_calc_arg.appear_arg;
+
+ const u32 max_text_length =
+ appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
+ ? appear_arg.max_text_length
+ : DEFAULT_MAX_TEXT_LENGTH;
+
+ const u32 min_text_length =
+ appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0;
+
+ Core::Frontend::InlineAppearParameters appear_parameters{
+ .max_text_length{max_text_length},
+ .min_text_length{min_text_length},
+ .key_top_scale_x{swkbd_calc_arg.key_top_scale_x},
+ .key_top_scale_y{swkbd_calc_arg.key_top_scale_y},
+ .key_top_translate_x{swkbd_calc_arg.key_top_translate_x},
+ .key_top_translate_y{swkbd_calc_arg.key_top_translate_y},
+ .type{appear_arg.type},
+ .key_disable_flags{appear_arg.key_disable_flags},
+ .key_top_as_floating{swkbd_calc_arg.key_top_as_floating},
+ .enable_backspace_button{swkbd_calc_arg.enable_backspace_button},
+ .enable_return_button{appear_arg.enable_return_button},
+ .disable_cancel_button{appear_arg.disable_cancel_button},
+ };
+
+ frontend.ShowInlineKeyboard(std::move(appear_parameters));
+
+ ChangeState(SwkbdState::InitializedIsShown);
+}
+
+void SoftwareKeyboard::HideInlineKeyboard() {
+ if (swkbd_state != SwkbdState::InitializedIsShown) {
+ return;
+ }
+
+ ChangeState(SwkbdState::InitializedIsDisappearing);
+
+ frontend.HideInlineKeyboard();
+
+ ChangeState(SwkbdState::InitializedIsHidden);
+}
+
+void SoftwareKeyboard::InlineTextChanged() {
+ Core::Frontend::InlineTextParameters text_parameters{
+ .input_text{current_text},
+ .cursor_position{current_cursor_position},
+ };
+
+ frontend.InlineTextChanged(std::move(text_parameters));
+}
+
+void SoftwareKeyboard::ExitKeyboard() {
+ complete = true;
+ status = RESULT_SUCCESS;
+
+ frontend.ExitKeyboard();
+
+ broker.SignalStateChanged();
+}
+
+// Inline Software Keyboard Requests
+
+void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) {
+ LOG_DEBUG(Service_AM, "Processing Request: Finalize");
+
+ ChangeState(SwkbdState::NotInitialized);
+
+ ExitKeyboard();
+}
+
+void SoftwareKeyboard::RequestSetUserWordInfo(const std::vector<u8>& request_data) {
+ LOG_WARNING(Service_AM, "SetUserWordInfo is not implemented.");
+}
+
+void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_data) {
+ LOG_WARNING(Service_AM, "SetCustomizeDic is not implemented.");
+}
+
+void SoftwareKeyboard::RequestCalc(const std::vector<u8>& request_data) {
+ LOG_DEBUG(Service_AM, "Processing Request: Calc");
+
+ ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArg));
+
+ std::memcpy(&swkbd_calc_arg, request_data.data() + sizeof(SwkbdRequestCommand),
+ sizeof(SwkbdCalcArg));
+
+ if (swkbd_calc_arg.flags.set_input_text) {
+ current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
+ swkbd_calc_arg.input_text.data(), swkbd_calc_arg.input_text.size());
+ }
+
+ if (swkbd_calc_arg.flags.set_cursor_position) {
+ current_cursor_position = swkbd_calc_arg.cursor_position;
+ }
+
+ if (swkbd_calc_arg.flags.set_utf8_mode) {
+ inline_use_utf8 = swkbd_calc_arg.utf8_mode;
+ }
+
+ if (swkbd_state <= SwkbdState::InitializedIsHidden &&
+ swkbd_calc_arg.flags.unset_customize_dic) {
+ ReplyUnsetCustomizeDic();
}
+
+ if (swkbd_state <= SwkbdState::InitializedIsHidden &&
+ swkbd_calc_arg.flags.unset_user_word_info) {
+ ReplyReleasedUserWordInfo();
+ }
+
+ if (swkbd_state == SwkbdState::NotInitialized && swkbd_calc_arg.flags.set_initialize_arg) {
+ InitializeFrontendKeyboard();
+
+ ChangeState(SwkbdState::InitializedIsHidden);
+
+ ReplyFinishedInitialize();
+ }
+
+ if (!swkbd_calc_arg.flags.set_initialize_arg &&
+ (swkbd_calc_arg.flags.set_input_text || swkbd_calc_arg.flags.set_cursor_position)) {
+ InlineTextChanged();
+ }
+
+ if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg.flags.appear) {
+ ShowInlineKeyboard();
+ return;
+ }
+
+ if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg.flags.disappear) {
+ HideInlineKeyboard();
+ return;
+ }
+}
+
+void SoftwareKeyboard::RequestSetCustomizedDictionaries(const std::vector<u8>& request_data) {
+ LOG_WARNING(Service_AM, "SetCustomizedDictionaries is not implemented.");
+}
+
+void SoftwareKeyboard::RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data) {
+ LOG_WARNING(Service_AM, "(STUBBED) Processing Request: UnsetCustomizedDictionaries");
+
+ ReplyUnsetCustomizedDictionaries();
+}
+
+void SoftwareKeyboard::RequestSetChangedStringV2Flag(const std::vector<u8>& request_data) {
+ LOG_DEBUG(Service_AM, "Processing Request: SetChangedStringV2Flag");
+
+ ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1);
+
+ std::memcpy(&use_changed_string_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1);
+}
+
+void SoftwareKeyboard::RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data) {
+ LOG_DEBUG(Service_AM, "Processing Request: SetMovedCursorV2Flag");
+
+ ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1);
+
+ std::memcpy(&use_moved_cursor_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1);
+}
+
+// Inline Software Keyboard Replies
+
+void SoftwareKeyboard::ReplyFinishedInitialize() {
+ LOG_DEBUG(Service_AM, "Sending Reply: FinishedInitialize");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + 1);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyDefault() {
+ LOG_DEBUG(Service_AM, "Sending Reply: Default");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyChangedString() {
+ LOG_DEBUG(Service_AM, "Sending Reply: ChangedString");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedString);
+
+ const SwkbdChangedStringArg changed_string_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .dictionary_start_cursor_position{-1},
+ .dictionary_end_cursor_position{-1},
+ .cursor_position{current_cursor_position},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
+ sizeof(SwkbdChangedStringArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyMovedCursor() {
+ LOG_DEBUG(Service_AM, "Sending Reply: MovedCursor");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursor);
+
+ const SwkbdMovedCursorArg moved_cursor_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .cursor_position{current_cursor_position},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
+ sizeof(SwkbdMovedCursorArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyMovedTab() {
+ LOG_DEBUG(Service_AM, "Sending Reply: MovedTab");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedTabArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedTab);
+
+ const SwkbdMovedTabArg moved_tab_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .cursor_position{current_cursor_position},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg,
+ sizeof(SwkbdMovedTabArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyDecidedEnter() {
+ LOG_DEBUG(Service_AM, "Sending Reply: DecidedEnter");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdDecidedEnterArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedEnter);
+
+ const SwkbdDecidedEnterArg decided_enter_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg,
+ sizeof(SwkbdDecidedEnterArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+
+ HideInlineKeyboard();
+}
+
+void SoftwareKeyboard::ReplyDecidedCancel() {
+ LOG_DEBUG(Service_AM, "Sending Reply: DecidedCancel");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+
+ HideInlineKeyboard();
+}
+
+void SoftwareKeyboard::ReplyChangedStringUtf8() {
+ LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringUtf8");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringUtf8);
+
+ std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
+
+ const SwkbdChangedStringArg changed_string_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .dictionary_start_cursor_position{-1},
+ .dictionary_end_cursor_position{-1},
+ .cursor_position{current_cursor_position},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
+ sizeof(SwkbdChangedStringArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
}
+
+void SoftwareKeyboard::ReplyMovedCursorUtf8() {
+ LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorUtf8");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorUtf8);
+
+ std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
+
+ const SwkbdMovedCursorArg moved_cursor_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .cursor_position{current_cursor_position},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
+ sizeof(SwkbdMovedCursorArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
+ LOG_DEBUG(Service_AM, "Sending Reply: DecidedEnterUtf8");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdDecidedEnterArg));
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedEnterUtf8);
+
+ std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
+
+ const SwkbdDecidedEnterArg decided_enter_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ };
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg,
+ sizeof(SwkbdDecidedEnterArg));
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+
+ HideInlineKeyboard();
+}
+
+void SoftwareKeyboard::ReplyUnsetCustomizeDic() {
+ LOG_DEBUG(Service_AM, "Sending Reply: UnsetCustomizeDic");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
+ LOG_DEBUG(Service_AM, "Sending Reply: ReleasedUserWordInfo");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
+ LOG_DEBUG(Service_AM, "Sending Reply: UnsetCustomizedDictionaries");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyChangedStringV2() {
+ LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringV2");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg) + 1);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringV2);
+
+ const SwkbdChangedStringArg changed_string_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .dictionary_start_cursor_position{-1},
+ .dictionary_end_cursor_position{-1},
+ .cursor_position{current_cursor_position},
+ };
+
+ constexpr u8 flag = 0;
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
+ sizeof(SwkbdChangedStringArg));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg),
+ &flag, 1);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyMovedCursorV2() {
+ LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorV2");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg) + 1);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorV2);
+
+ const SwkbdMovedCursorArg moved_cursor_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .cursor_position{current_cursor_position},
+ };
+
+ constexpr u8 flag = 0;
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(),
+ current_text.size() * sizeof(char16_t));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
+ sizeof(SwkbdMovedCursorArg));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg),
+ &flag, 1);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
+ LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringUtf8V2");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg) + 1);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringUtf8V2);
+
+ std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
+
+ const SwkbdChangedStringArg changed_string_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .dictionary_start_cursor_position{-1},
+ .dictionary_end_cursor_position{-1},
+ .cursor_position{current_cursor_position},
+ };
+
+ constexpr u8 flag = 0;
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
+ sizeof(SwkbdChangedStringArg));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg),
+ &flag, 1);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
+void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
+ LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorUtf8V2");
+
+ std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg) + 1);
+
+ SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorUtf8V2);
+
+ std::string utf8_current_text = Common::UTF16ToUTF8(current_text);
+
+ const SwkbdMovedCursorArg moved_cursor_arg{
+ .text_length{static_cast<u32>(current_text.size())},
+ .cursor_position{current_cursor_position},
+ };
+
+ constexpr u8 flag = 0;
+
+ std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size());
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
+ sizeof(SwkbdMovedCursorArg));
+ std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg),
+ &flag, 1);
+
+ broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index 1d260fef8..85aeb4eb1 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -1,20 +1,14 @@
-// Copyright 2018 yuzu emulator team
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
-#include <array>
-#include <string>
-#include <vector>
-
#include "common/common_funcs.h"
#include "common/common_types.h"
-#include "common/swap.h"
-#include "core/hle/service/am/am.h"
+#include "core/hle/result.h"
#include "core/hle/service/am/applets/applets.h"
-
-union ResultCode;
+#include "core/hle/service/am/applets/software_keyboard_types.h"
namespace Core {
class System;
@@ -22,45 +16,10 @@ class System;
namespace Service::AM::Applets {
-enum class KeysetDisable : u32 {
- Space = 0x02,
- Address = 0x04,
- Percent = 0x08,
- Slashes = 0x10,
- Numbers = 0x40,
- DownloadCode = 0x80,
-};
-
-struct KeyboardConfig {
- INSERT_PADDING_BYTES(4);
- std::array<char16_t, 9> submit_text;
- u16_le left_symbol_key;
- u16_le right_symbol_key;
- INSERT_PADDING_BYTES(1);
- KeysetDisable keyset_disable_bitmask;
- u32_le initial_cursor_position;
- std::array<char16_t, 65> header_text;
- std::array<char16_t, 129> sub_text;
- std::array<char16_t, 257> guide_text;
- u32_le length_limit;
- INSERT_PADDING_BYTES(4);
- u32_le is_password;
- INSERT_PADDING_BYTES(5);
- bool utf_8;
- bool draw_background;
- u32_le initial_string_offset;
- u32_le initial_string_size;
- u32_le user_dictionary_offset;
- u32_le user_dictionary_size;
- bool text_check;
- u64_le text_check_callback;
-};
-static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect size.");
-
class SoftwareKeyboard final : public Applet {
public:
- explicit SoftwareKeyboard(Core::System& system_,
- const Core::Frontend::SoftwareKeyboardApplet& frontend_);
+ explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
+ Core::Frontend::SoftwareKeyboardApplet& frontend_);
~SoftwareKeyboard() override;
void Initialize() override;
@@ -70,17 +29,139 @@ public:
void ExecuteInteractive() override;
void Execute() override;
- void WriteText(std::optional<std::u16string> text);
+ /**
+ * Submits the input text to the application.
+ * If text checking is enabled, the application will verify the input text.
+ * If use_utf8 is enabled, the input text will be converted to UTF-8 prior to being submitted.
+ * This should only be used by the normal software keyboard.
+ *
+ * @param result SwkbdResult enum
+ * @param submitted_text UTF-16 encoded string
+ */
+ void SubmitTextNormal(SwkbdResult result, std::u16string submitted_text);
+
+ /**
+ * Submits the input text to the application.
+ * If utf8_mode is enabled, the input text will be converted to UTF-8 prior to being submitted.
+ * This should only be used by the inline software keyboard.
+ *
+ * @param reply_type SwkbdReplyType enum
+ * @param submitted_text UTF-16 encoded string
+ * @param cursor_position The current position of the text cursor
+ */
+ void SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text,
+ s32 cursor_position);
private:
- const Core::Frontend::SoftwareKeyboardApplet& frontend;
+ /// Initializes the normal software keyboard.
+ void InitializeForeground();
- KeyboardConfig config;
- std::u16string initial_text;
- bool complete = false;
- bool is_inline = false;
- std::vector<u8> final_data;
+ /// Initializes the inline software keyboard.
+ void InitializeBackground(LibraryAppletMode applet_mode);
+
+ /// Processes the text check sent by the application.
+ void ProcessTextCheck();
+
+ /// Processes the inline software keyboard request command sent by the application.
+ void ProcessInlineKeyboardRequest();
+
+ /// Submits the input text and exits the applet.
+ void SubmitNormalOutputAndExit(SwkbdResult result, std::u16string submitted_text);
+
+ /// Submits the input text for text checking.
+ void SubmitForTextCheck(std::u16string submitted_text);
+
+ /// Sends a reply to the application after processing a request command.
+ void SendReply(SwkbdReplyType reply_type);
+
+ /// Changes the inline keyboard state.
+ void ChangeState(SwkbdState state);
+
+ /**
+ * Signals the frontend to initialize the software keyboard with common parameters.
+ * This initializes either the normal software keyboard or the inline software keyboard
+ * depending on the state of is_background.
+ * Note that this does not cause the keyboard to appear.
+ * Use the respective Show*Keyboard() functions to cause the respective keyboards to appear.
+ */
+ void InitializeFrontendKeyboard();
+
+ /// Signals the frontend to show the normal software keyboard.
+ void ShowNormalKeyboard();
+
+ /// Signals the frontend to show the text check dialog.
+ void ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
+ std::u16string text_check_message);
+
+ /// Signals the frontend to show the inline software keyboard.
+ void ShowInlineKeyboard();
+
+ /// Signals the frontend to hide the inline software keyboard.
+ void HideInlineKeyboard();
+
+ /// Signals the frontend that the current inline keyboard text has changed.
+ void InlineTextChanged();
+
+ /// Signals both the frontend and application that the software keyboard is exiting.
+ void ExitKeyboard();
+
+ // Inline Software Keyboard Requests
+
+ void RequestFinalize(const std::vector<u8>& request_data);
+ void RequestSetUserWordInfo(const std::vector<u8>& request_data);
+ void RequestSetCustomizeDic(const std::vector<u8>& request_data);
+ void RequestCalc(const std::vector<u8>& request_data);
+ void RequestSetCustomizedDictionaries(const std::vector<u8>& request_data);
+ void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
+ void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
+ void RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data);
+
+ // Inline Software Keyboard Replies
+
+ void ReplyFinishedInitialize();
+ void ReplyDefault();
+ void ReplyChangedString();
+ void ReplyMovedCursor();
+ void ReplyMovedTab();
+ void ReplyDecidedEnter();
+ void ReplyDecidedCancel();
+ void ReplyChangedStringUtf8();
+ void ReplyMovedCursorUtf8();
+ void ReplyDecidedEnterUtf8();
+ void ReplyUnsetCustomizeDic();
+ void ReplyReleasedUserWordInfo();
+ void ReplyUnsetCustomizedDictionaries();
+ void ReplyChangedStringV2();
+ void ReplyMovedCursorV2();
+ void ReplyChangedStringUtf8V2();
+ void ReplyMovedCursorUtf8V2();
+
+ LibraryAppletMode applet_mode;
+ Core::Frontend::SoftwareKeyboardApplet& frontend;
Core::System& system;
+
+ SwkbdAppletVersion swkbd_applet_version;
+
+ SwkbdConfigCommon swkbd_config_common;
+ SwkbdConfigOld swkbd_config_old;
+ SwkbdConfigOld2 swkbd_config_old2;
+ SwkbdConfigNew swkbd_config_new;
+ std::u16string initial_text;
+
+ SwkbdState swkbd_state{SwkbdState::NotInitialized};
+ SwkbdInitializeArg swkbd_initialize_arg;
+ SwkbdCalcArg swkbd_calc_arg;
+ bool use_changed_string_v2{false};
+ bool use_moved_cursor_v2{false};
+ bool inline_use_utf8{false};
+ s32 current_cursor_position{};
+
+ std::u16string current_text;
+
+ bool is_background{false};
+
+ bool complete{false};
+ ResultCode status{RESULT_SUCCESS};
};
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/software_keyboard_types.h b/src/core/hle/service/am/applets/software_keyboard_types.h
new file mode 100644
index 000000000..21aa8e800
--- /dev/null
+++ b/src/core/hle/service/am/applets/software_keyboard_types.h
@@ -0,0 +1,295 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+
+#include "common/bit_field.h"
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+#include "common/swap.h"
+
+namespace Service::AM::Applets {
+
+constexpr std::size_t MAX_OK_TEXT_LENGTH = 8;
+constexpr std::size_t MAX_HEADER_TEXT_LENGTH = 64;
+constexpr std::size_t MAX_SUB_TEXT_LENGTH = 128;
+constexpr std::size_t MAX_GUIDE_TEXT_LENGTH = 256;
+constexpr std::size_t STRING_BUFFER_SIZE = 0x7D4;
+
+enum class SwkbdAppletVersion : u32_le {
+ Version5 = 0x5, // 1.0.0
+ Version65542 = 0x10006, // 2.0.0 - 2.3.0
+ Version196615 = 0x30007, // 3.0.0 - 3.0.2
+ Version262152 = 0x40008, // 4.0.0 - 4.1.0
+ Version327689 = 0x50009, // 5.0.0 - 5.1.0
+ Version393227 = 0x6000B, // 6.0.0 - 7.0.1
+ Version524301 = 0x8000D, // 8.0.0+
+};
+
+enum class SwkbdType : u32 {
+ Normal,
+ NumberPad,
+ Qwerty,
+ Unknown3,
+ Latin,
+ SimplifiedChinese,
+ TraditionalChinese,
+ Korean,
+};
+
+enum class SwkbdInitialCursorPosition : u32 {
+ Start,
+ End,
+};
+
+enum class SwkbdPasswordMode : u32 {
+ Disabled,
+ Enabled,
+};
+
+enum class SwkbdTextDrawType : u32 {
+ Line,
+ Box,
+ DownloadCode,
+};
+
+enum class SwkbdResult : u32 {
+ Ok,
+ Cancel,
+};
+
+enum class SwkbdTextCheckResult : u32 {
+ Success,
+ Failure,
+ Confirm,
+ Silent,
+};
+
+enum class SwkbdState : u32 {
+ NotInitialized = 0x0,
+ InitializedIsHidden = 0x1,
+ InitializedIsAppearing = 0x2,
+ InitializedIsShown = 0x3,
+ InitializedIsDisappearing = 0x4,
+};
+
+enum class SwkbdRequestCommand : u32 {
+ Finalize = 0x4,
+ SetUserWordInfo = 0x6,
+ SetCustomizeDic = 0x7,
+ Calc = 0xA,
+ SetCustomizedDictionaries = 0xB,
+ UnsetCustomizedDictionaries = 0xC,
+ SetChangedStringV2Flag = 0xD,
+ SetMovedCursorV2Flag = 0xE,
+};
+
+enum class SwkbdReplyType : u32 {
+ FinishedInitialize = 0x0,
+ Default = 0x1,
+ ChangedString = 0x2,
+ MovedCursor = 0x3,
+ MovedTab = 0x4,
+ DecidedEnter = 0x5,
+ DecidedCancel = 0x6,
+ ChangedStringUtf8 = 0x7,
+ MovedCursorUtf8 = 0x8,
+ DecidedEnterUtf8 = 0x9,
+ UnsetCustomizeDic = 0xA,
+ ReleasedUserWordInfo = 0xB,
+ UnsetCustomizedDictionaries = 0xC,
+ ChangedStringV2 = 0xD,
+ MovedCursorV2 = 0xE,
+ ChangedStringUtf8V2 = 0xF,
+ MovedCursorUtf8V2 = 0x10,
+};
+
+struct SwkbdKeyDisableFlags {
+ union {
+ u32 raw{};
+
+ BitField<1, 1, u32> space;
+ BitField<2, 1, u32> at;
+ BitField<3, 1, u32> percent;
+ BitField<4, 1, u32> slash;
+ BitField<5, 1, u32> backslash;
+ BitField<6, 1, u32> numbers;
+ BitField<7, 1, u32> download_code;
+ BitField<8, 1, u32> username;
+ };
+};
+static_assert(sizeof(SwkbdKeyDisableFlags) == 0x4, "SwkbdKeyDisableFlags has incorrect size.");
+
+struct SwkbdConfigCommon {
+ SwkbdType type{};
+ std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
+ char16_t left_optional_symbol_key{};
+ char16_t right_optional_symbol_key{};
+ bool use_prediction{};
+ INSERT_PADDING_BYTES(1);
+ SwkbdKeyDisableFlags key_disable_flags{};
+ SwkbdInitialCursorPosition initial_cursor_position{};
+ std::array<char16_t, MAX_HEADER_TEXT_LENGTH + 1> header_text{};
+ std::array<char16_t, MAX_SUB_TEXT_LENGTH + 1> sub_text{};
+ std::array<char16_t, MAX_GUIDE_TEXT_LENGTH + 1> guide_text{};
+ u32 max_text_length{};
+ u32 min_text_length{};
+ SwkbdPasswordMode password_mode{};
+ SwkbdTextDrawType text_draw_type{};
+ bool enable_return_button{};
+ bool use_utf8{};
+ bool use_blur_background{};
+ INSERT_PADDING_BYTES(1);
+ u32 initial_string_offset{};
+ u32 initial_string_length{};
+ u32 user_dictionary_offset{};
+ u32 user_dictionary_entries{};
+ bool use_text_check{};
+ INSERT_PADDING_BYTES(3);
+};
+static_assert(sizeof(SwkbdConfigCommon) == 0x3D4, "SwkbdConfigCommon has incorrect size.");
+
+#pragma pack(push, 4)
+// SwkbdAppletVersion 0x5, 0x10006
+struct SwkbdConfigOld {
+ INSERT_PADDING_WORDS(1);
+ VAddr text_check_callback{};
+};
+static_assert(sizeof(SwkbdConfigOld) == 0x3E0 - sizeof(SwkbdConfigCommon),
+ "SwkbdConfigOld has incorrect size.");
+
+// SwkbdAppletVersion 0x30007, 0x40008, 0x50009
+struct SwkbdConfigOld2 {
+ INSERT_PADDING_WORDS(1);
+ VAddr text_check_callback{};
+ std::array<u32, 8> text_grouping{};
+};
+static_assert(sizeof(SwkbdConfigOld2) == 0x400 - sizeof(SwkbdConfigCommon),
+ "SwkbdConfigOld2 has incorrect size.");
+
+// SwkbdAppletVersion 0x6000B, 0x8000D
+struct SwkbdConfigNew {
+ std::array<u32, 8> text_grouping{};
+ std::array<u64, 24> customized_dictionary_set_entries{};
+ u8 total_customized_dictionary_set_entries{};
+ bool disable_cancel_button{};
+ INSERT_PADDING_BYTES(18);
+};
+static_assert(sizeof(SwkbdConfigNew) == 0x4C8 - sizeof(SwkbdConfigCommon),
+ "SwkbdConfigNew has incorrect size.");
+#pragma pack(pop)
+
+struct SwkbdTextCheck {
+ SwkbdTextCheckResult text_check_result{};
+ std::array<char16_t, STRING_BUFFER_SIZE / 2> text_check_message{};
+};
+static_assert(sizeof(SwkbdTextCheck) == 0x7D8, "SwkbdTextCheck has incorrect size.");
+
+struct SwkbdCalcArgFlags {
+ union {
+ u64 raw{};
+
+ BitField<0, 1, u64> set_initialize_arg;
+ BitField<1, 1, u64> set_volume;
+ BitField<2, 1, u64> appear;
+ BitField<3, 1, u64> set_input_text;
+ BitField<4, 1, u64> set_cursor_position;
+ BitField<5, 1, u64> set_utf8_mode;
+ BitField<6, 1, u64> unset_customize_dic;
+ BitField<7, 1, u64> disappear;
+ BitField<8, 1, u64> unknown;
+ BitField<9, 1, u64> set_key_top_translate_scale;
+ BitField<10, 1, u64> unset_user_word_info;
+ BitField<11, 1, u64> set_disable_hardware_keyboard;
+ };
+};
+static_assert(sizeof(SwkbdCalcArgFlags) == 0x8, "SwkbdCalcArgFlags has incorrect size.");
+
+struct SwkbdInitializeArg {
+ u32 unknown{};
+ bool library_applet_mode_flag{};
+ bool is_above_hos_500{};
+ INSERT_PADDING_BYTES(2);
+};
+static_assert(sizeof(SwkbdInitializeArg) == 0x8, "SwkbdInitializeArg has incorrect size.");
+
+struct SwkbdAppearArg {
+ SwkbdType type{};
+ std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
+ char16_t left_optional_symbol_key{};
+ char16_t right_optional_symbol_key{};
+ bool use_prediction{};
+ bool disable_cancel_button{};
+ SwkbdKeyDisableFlags key_disable_flags{};
+ u32 max_text_length{};
+ u32 min_text_length{};
+ bool enable_return_button{};
+ INSERT_PADDING_BYTES(3);
+ u32 flags{};
+ INSERT_PADDING_WORDS(6);
+};
+static_assert(sizeof(SwkbdAppearArg) == 0x48, "SwkbdAppearArg has incorrect size.");
+
+struct SwkbdCalcArg {
+ u32 unknown{};
+ u16 calc_arg_size{};
+ INSERT_PADDING_BYTES(2);
+ SwkbdCalcArgFlags flags{};
+ SwkbdInitializeArg initialize_arg{};
+ f32 volume{};
+ s32 cursor_position{};
+ SwkbdAppearArg appear_arg{};
+ std::array<char16_t, 0x1FA> input_text{};
+ bool utf8_mode{};
+ INSERT_PADDING_BYTES(1);
+ bool enable_backspace_button{};
+ INSERT_PADDING_BYTES(3);
+ bool key_top_as_floating{};
+ bool footer_scalable{};
+ bool alpha_enabled_in_input_mode{};
+ u8 input_mode_fade_type{};
+ bool disable_touch{};
+ bool disable_hardware_keyboard{};
+ INSERT_PADDING_BYTES(8);
+ f32 key_top_scale_x{};
+ f32 key_top_scale_y{};
+ f32 key_top_translate_x{};
+ f32 key_top_translate_y{};
+ f32 key_top_bg_alpha{};
+ f32 footer_bg_alpha{};
+ f32 balloon_scale{};
+ INSERT_PADDING_WORDS(4);
+ u8 se_group{};
+ INSERT_PADDING_BYTES(3);
+};
+static_assert(sizeof(SwkbdCalcArg) == 0x4A0, "SwkbdCalcArg has incorrect size.");
+
+struct SwkbdChangedStringArg {
+ u32 text_length{};
+ s32 dictionary_start_cursor_position{};
+ s32 dictionary_end_cursor_position{};
+ s32 cursor_position{};
+};
+static_assert(sizeof(SwkbdChangedStringArg) == 0x10, "SwkbdChangedStringArg has incorrect size.");
+
+struct SwkbdMovedCursorArg {
+ u32 text_length{};
+ s32 cursor_position{};
+};
+static_assert(sizeof(SwkbdMovedCursorArg) == 0x8, "SwkbdMovedCursorArg has incorrect size.");
+
+struct SwkbdMovedTabArg {
+ u32 text_length{};
+ s32 cursor_position{};
+};
+static_assert(sizeof(SwkbdMovedTabArg) == 0x8, "SwkbdMovedTabArg has incorrect size.");
+
+struct SwkbdDecidedEnterArg {
+ u32 text_length{};
+};
+static_assert(sizeof(SwkbdDecidedEnterArg) == 0x4, "SwkbdDecidedEnterArg has incorrect size.");
+
+} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index 2ab420789..b28b849bc 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -208,8 +208,9 @@ void ExtractSharedFonts(Core::System& system) {
} // namespace
-WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_)
- : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
+WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::WebBrowserApplet& frontend_)
+ : Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend(frontend_), system{system_} {}
WebBrowser::~WebBrowser() = default;
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h
index 04c274754..5eafbae7b 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -25,7 +25,8 @@ namespace Service::AM::Applets {
class WebBrowser final : public Applet {
public:
- WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_);
+ WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
+ const Core::Frontend::WebBrowserApplet& frontend_);
~WebBrowser() override;
@@ -63,6 +64,7 @@ private:
void ExecuteWifi();
void ExecuteLobby();
+ LibraryAppletMode applet_mode;
const Core::Frontend::WebBrowserApplet& frontend;
bool complete{false};
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 8d657c0bf..75867e349 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -7,6 +7,7 @@
#include <vector>
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/common_funcs.h"
#include "core/file_sys/content_archive.h"
@@ -21,7 +22,6 @@
#include "core/hle/kernel/process.h"
#include "core/hle/service/aoc/aoc_u.h"
#include "core/loader/loader.h"
-#include "core/settings.h"
namespace Service::AOC {
@@ -118,8 +118,10 @@ AOC_U::AOC_U(Core::System& system_)
{7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"},
{8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"},
{9, nullptr, "GetAddOnContentLostErrorCode"},
+ {10, nullptr, "GetAddOnContentListChangedEventWithProcessId"},
{100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"},
{101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"},
+ {110, nullptr, "CreateContentsServiceManager"},
};
// clang-format on
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp
index 03636642b..00c174bb0 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/controller.cpp
@@ -7,9 +7,9 @@
#include <utility>
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core_timing.h"
#include "core/hle/service/apm/controller.h"
-#include "core/settings.h"
namespace Service::APM {
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp
index 79c3aa920..10acaad19 100644
--- a/src/core/hle/service/audio/audin_a.cpp
+++ b/src/core/hle/service/audio/audin_a.cpp
@@ -9,10 +9,10 @@ namespace Service::Audio {
AudInA::AudInA(Core::System& system_) : ServiceFramework{system_, "audin:a"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "RequestSuspendAudioIns"},
- {1, nullptr, "RequestResumeAudioIns"},
- {2, nullptr, "GetAudioInsProcessMasterVolume"},
- {3, nullptr, "SetAudioInsProcessMasterVolume"},
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ {2, nullptr, "GetProcessMasterVolume"},
+ {3, nullptr, "SetProcessMasterVolume"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 26a6deddf..ecd05e4a6 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -15,19 +15,19 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetAudioInState"},
- {1, nullptr, "StartAudioIn"},
- {2, nullptr, "StopAudioIn"},
+ {1, nullptr, "Start"},
+ {2, nullptr, "Stop"},
{3, nullptr, "AppendAudioInBuffer"},
{4, nullptr, "RegisterBufferEvent"},
{5, nullptr, "GetReleasedAudioInBuffer"},
{6, nullptr, "ContainsAudioInBuffer"},
- {7, nullptr, "AppendAudioInBufferWithUserEvent"},
+ {7, nullptr, "AppendUacInBuffer"},
{8, nullptr, "AppendAudioInBufferAuto"},
- {9, nullptr, "GetReleasedAudioInBufferAuto"},
- {10, nullptr, "AppendAudioInBufferWithUserEventAuto"},
+ {9, nullptr, "GetReleasedAudioInBuffersAuto"},
+ {10, nullptr, "AppendUacInBufferAuto"},
{11, nullptr, "GetAudioInBufferCount"},
- {12, nullptr, "SetAudioInDeviceGain"},
- {13, nullptr, "GetAudioInDeviceGain"},
+ {12, nullptr, "SetDeviceGain"},
+ {13, nullptr, "GetDeviceGain"},
{14, nullptr, "FlushAudioInBuffers"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp
index 19825fd5d..3ee522b50 100644
--- a/src/core/hle/service/audio/audout_a.cpp
+++ b/src/core/hle/service/audio/audout_a.cpp
@@ -9,12 +9,12 @@ namespace Service::Audio {
AudOutA::AudOutA(Core::System& system_) : ServiceFramework{system_, "audout:a"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "RequestSuspendAudioOuts"},
- {1, nullptr, "RequestResumeAudioOuts"},
- {2, nullptr, "GetAudioOutsProcessMasterVolume"},
- {3, nullptr, "SetAudioOutsProcessMasterVolume"},
- {4, nullptr, "GetAudioOutsProcessRecordVolume"},
- {5, nullptr, "SetAudioOutsProcessRecordVolume"},
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ {2, nullptr, "GetProcessMasterVolume"},
+ {3, nullptr, "SetProcessMasterVolume"},
+ {4, nullptr, "GetProcessRecordVolume"},
+ {5, nullptr, "SetProcessRecordVolume"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 5ed9cb20e..5f51fca9a 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -49,11 +49,11 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
- {1, &IAudioOut::StartAudioOut, "StartAudioOut"},
- {2, &IAudioOut::StopAudioOut, "StopAudioOut"},
+ {1, &IAudioOut::StartAudioOut, "Start"},
+ {2, &IAudioOut::StopAudioOut, "Stop"},
{3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"},
{4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
- {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"},
+ {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffers"},
{6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
{7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"},
{8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp
index c5ab7cad4..70fc17ae2 100644
--- a/src/core/hle/service/audio/audrec_a.cpp
+++ b/src/core/hle/service/audio/audrec_a.cpp
@@ -9,8 +9,8 @@ namespace Service::Audio {
AudRecA::AudRecA(Core::System& system_) : ServiceFramework{system_, "audrec:a"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "RequestSuspendFinalOutputRecorders"},
- {1, nullptr, "RequestResumeFinalOutputRecorders"},
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audrec_u.cpp b/src/core/hle/service/audio/audrec_u.cpp
index eb5c63c62..74a65ccff 100644
--- a/src/core/hle/service/audio/audrec_u.cpp
+++ b/src/core/hle/service/audio/audrec_u.cpp
@@ -13,16 +13,17 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetFinalOutputRecorderState"},
- {1, nullptr, "StartFinalOutputRecorder"},
- {2, nullptr, "StopFinalOutputRecorder"},
+ {1, nullptr, "Start"},
+ {2, nullptr, "Stop"},
{3, nullptr, "AppendFinalOutputRecorderBuffer"},
{4, nullptr, "RegisterBufferEvent"},
- {5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
+ {5, nullptr, "GetReleasedFinalOutputRecorderBuffers"},
{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
{7, nullptr, "GetFinalOutputRecorderBufferEndTime"},
{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
{10, nullptr, "FlushFinalOutputRecorderBuffers"},
+ {11, nullptr, "AttachWorkBuffer"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp
index 5e9f866f0..cf8c34a15 100644
--- a/src/core/hle/service/audio/audren_a.cpp
+++ b/src/core/hle/service/audio/audren_a.cpp
@@ -9,14 +9,14 @@ namespace Service::Audio {
AudRenA::AudRenA(Core::System& system_) : ServiceFramework{system_, "audren:a"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "RequestSuspendAudioRenderers"},
- {1, nullptr, "RequestResumeAudioRenderers"},
- {2, nullptr, "GetAudioRenderersProcessMasterVolume"},
- {3, nullptr, "SetAudioRenderersProcessMasterVolume"},
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ {2, nullptr, "GetProcessMasterVolume"},
+ {3, nullptr, "SetProcessMasterVolume"},
{4, nullptr, "RegisterAppletResourceUserId"},
{5, nullptr, "UnregisterAppletResourceUserId"},
- {6, nullptr, "GetAudioRenderersProcessRecordVolume"},
- {7, nullptr, "SetAudioRenderersProcessRecordVolume"},
+ {6, nullptr, "GetProcessRecordVolume"},
+ {7, nullptr, "SetProcessRecordVolume"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index b2b2ffc5a..572be8e00 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -332,9 +332,9 @@ AudRenU::AudRenU(Core::System& system_) : ServiceFramework{system_, "audren:u"}
// clang-format off
static const FunctionInfo functions[] = {
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
- {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
+ {1, &AudRenU::GetAudioRendererWorkBufferSize, "GetWorkBufferSize"},
{2, &AudRenU::GetAudioDeviceService, "GetAudioDeviceService"},
- {3, &AudRenU::OpenAudioRendererAuto, "OpenAudioRendererAuto"},
+ {3, &AudRenU::OpenAudioRendererForManualExecution, "OpenAudioRendererForManualExecution"},
{4, &AudRenU::GetAudioDeviceServiceWithRevisionInfo, "GetAudioDeviceServiceWithRevisionInfo"},
};
// clang-format on
@@ -665,7 +665,7 @@ void AudRenU::GetAudioDeviceService(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IAudioDevice>(system, Common::MakeMagic('R', 'E', 'V', '1'));
}
-void AudRenU::OpenAudioRendererAuto(Kernel::HLERequestContext& ctx) {
+void AudRenU::OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
OpenAudioRendererImpl(ctx);
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index d693dc406..37e8b4716 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -25,7 +25,7 @@ private:
void OpenAudioRenderer(Kernel::HLERequestContext& ctx);
void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
void GetAudioDeviceService(Kernel::HLERequestContext& ctx);
- void OpenAudioRendererAuto(Kernel::HLERequestContext& ctx);
+ void OpenAudioRendererForManualExecution(Kernel::HLERequestContext& ctx);
void GetAudioDeviceServiceWithRevisionInfo(Kernel::HLERequestContext& ctx);
void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/audio/codecctl.cpp b/src/core/hle/service/audio/codecctl.cpp
index 94afec1b6..42961d908 100644
--- a/src/core/hle/service/audio/codecctl.cpp
+++ b/src/core/hle/service/audio/codecctl.cpp
@@ -8,19 +8,19 @@ namespace Service::Audio {
CodecCtl::CodecCtl(Core::System& system_) : ServiceFramework{system_, "codecctl"} {
static const FunctionInfo functions[] = {
- {0, nullptr, "InitializeCodecController"},
- {1, nullptr, "FinalizeCodecController"},
- {2, nullptr, "SleepCodecController"},
- {3, nullptr, "WakeCodecController"},
- {4, nullptr, "SetCodecVolume"},
- {5, nullptr, "GetCodecVolumeMax"},
- {6, nullptr, "GetCodecVolumeMin"},
- {7, nullptr, "SetCodecActiveTarget"},
- {8, nullptr, "GetCodecActiveTarget"},
- {9, nullptr, "BindCodecHeadphoneMicJackInterrupt"},
- {10, nullptr, "IsCodecHeadphoneMicJackInserted"},
- {11, nullptr, "ClearCodecHeadphoneMicJackInterrupt"},
- {12, nullptr, "IsCodecDeviceRequested"},
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Finalize"},
+ {2, nullptr, "Sleep"},
+ {3, nullptr, "Wake"},
+ {4, nullptr, "SetVolume"},
+ {5, nullptr, "GetVolumeMax"},
+ {6, nullptr, "GetVolumeMin"},
+ {7, nullptr, "SetActiveTarget"},
+ {8, nullptr, "GetActiveTarget"},
+ {9, nullptr, "BindHeadphoneMicJackInterrupt"},
+ {10, nullptr, "IsHeadphoneMicJackInserted"},
+ {11, nullptr, "ClearHeadphoneMicJackInterrupt"},
+ {12, nullptr, "IsRequested"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index ea3414fd2..19c578b3a 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -297,6 +297,10 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
{2, nullptr, "OpenOpusDecoderForMultiStream"},
{3, nullptr, "GetWorkBufferSizeForMultiStream"},
+ {4, nullptr, "OpenHardwareOpusDecoderEx"},
+ {5, nullptr, "GetWorkBufferSizeEx"},
+ {6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"},
+ {7, nullptr, "GetWorkBufferSizeForMultiStreamEx"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index e43f3f47f..78c047bd2 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -9,6 +9,7 @@
#include "common/hex_util.h"
#include "common/logging/backend.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_libzip.h"
@@ -16,7 +17,6 @@
#include "core/frontend/applets/error.h"
#include "core/hle/service/am/applets/applets.h"
#include "core/hle/service/bcat/backend/boxcat.h"
-#include "core/settings.h"
namespace Service::BCAT {
namespace {
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 503109fdd..c7dd04a6e 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -7,6 +7,7 @@
#include "backend/boxcat.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/vfs.h"
@@ -18,7 +19,6 @@
#include "core/hle/service/bcat/bcat.h"
#include "core/hle/service/bcat/module.h"
#include "core/hle/service/filesystem/filesystem.h"
-#include "core/settings.h"
namespace Service::BCAT {
@@ -155,10 +155,12 @@ public:
{30210, nullptr, "SetDeliveryTaskTimer"},
{30300, nullptr, "RegisterSystemApplicationDeliveryTasks"},
{90100, nullptr, "EnumerateBackgroundDeliveryTask"},
+ {90101, nullptr, "Unknown90101"},
{90200, nullptr, "GetDeliveryList"},
{90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"},
{90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"},
{90300, nullptr, "GetPushNotificationLog"},
+ {90301, nullptr, "Unknown90301"},
};
// clang-format on
RegisterHandlers(functions);
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp
index e4630320e..78e01d8d8 100644
--- a/src/core/hle/service/bpc/bpc.cpp
+++ b/src/core/hle/service/bpc/bpc.cpp
@@ -29,8 +29,8 @@ public:
{11, nullptr, "CreateWakeupTimerEx"},
{12, nullptr, "GetLastEnabledWakeupTimerType"},
{13, nullptr, "CleanAllWakeupTimers"},
- {14, nullptr, "Unknown"},
- {15, nullptr, "Unknown2"},
+ {14, nullptr, "GetPowerButton"},
+ {15, nullptr, "SetEnableWakeupTimer"},
};
// clang-format on
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index 17a2ac899..af3a5842d 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -156,6 +156,25 @@ public:
{97, nullptr, "RegisterBleHidEvent"},
{98, nullptr, "SetBleScanParameter"},
{99, nullptr, "MoveToSecondaryPiconet"},
+ {100, nullptr, "IsBluetoothEnabled"},
+ {128, nullptr, "AcquireAudioEvent"},
+ {129, nullptr, "GetAudioEventInfo"},
+ {130, nullptr, "OpenAudioConnection"},
+ {131, nullptr, "CloseAudioConnection"},
+ {132, nullptr, "OpenAudioOut"},
+ {133, nullptr, "CloseAudioOut"},
+ {134, nullptr, "AcquireAudioOutStateChangedEvent"},
+ {135, nullptr, "StartAudioOut"},
+ {136, nullptr, "StopAudioOut"},
+ {137, nullptr, "GetAudioOutState"},
+ {138, nullptr, "GetAudioOutFeedingCodec"},
+ {139, nullptr, "GetAudioOutFeedingParameter"},
+ {140, nullptr, "AcquireAudioOutBufferAvailableEvent"},
+ {141, nullptr, "SendAudioData"},
+ {142, nullptr, "AcquireAudioControlInputStateChangedEvent"},
+ {143, nullptr, "GetAudioControlInputState"},
+ {144, nullptr, "AcquireAudioConnectionStateChangedEvent"},
+ {145, nullptr, "GetConnectedAudioDevice"},
{256, nullptr, "IsManufacturingMode"},
{257, nullptr, "EmulateBluetoothCrash"},
{258, nullptr, "GetBleChannelMap"},
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 9cf2ee92a..d1ebc2388 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -223,6 +223,7 @@ public:
{10, nullptr, "GetGattClientDisconnectionReason"},
{11, nullptr, "GetBleConnectionParameter"},
{12, nullptr, "GetBleConnectionParameterRequest"},
+ {13, nullptr, "Unknown13"},
};
// clang-format on
diff --git a/src/core/hle/service/caps/caps_a.cpp b/src/core/hle/service/caps/caps_a.cpp
index 1fe4f0e14..6220e9f77 100644
--- a/src/core/hle/service/caps/caps_a.cpp
+++ b/src/core/hle/service/caps/caps_a.cpp
@@ -49,6 +49,7 @@ CAPS_A::CAPS_A(Core::System& system_) : ServiceFramework{system_, "caps:a"} {
{16, nullptr, "GetAlbumMountResult"},
{17, nullptr, "GetAlbumUsage16"},
{18, nullptr, "Unknown18"},
+ {19, nullptr, "Unknown19"},
{100, nullptr, "GetAlbumFileCountEx0"},
{101, nullptr, "GetAlbumFileListEx0"},
{202, nullptr, "SaveEditedScreenShot"},
diff --git a/src/core/hle/service/caps/caps_u.cpp b/src/core/hle/service/caps/caps_u.cpp
index 842316a2e..10b8d54b1 100644
--- a/src/core/hle/service/caps/caps_u.cpp
+++ b/src/core/hle/service/caps/caps_u.cpp
@@ -43,6 +43,7 @@ CAPS_U::CAPS_U(Core::System& system_) : ServiceFramework{system_, "caps:u"} {
{141, nullptr, "GetAlbumFileList2AafeUidAruidDeprecated"},
{142, &CAPS_U::GetAlbumFileList3AaeAruid, "GetAlbumFileList3AaeAruid"},
{143, nullptr, "GetAlbumFileList4AaeUidAruid"},
+ {144, nullptr, "GetAllAlbumFileList3AaeAruid"},
{60002, nullptr, "OpenAccessorSessionForApplication"},
};
// clang-format on
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp
index 4924c61c3..c767926a4 100644
--- a/src/core/hle/service/erpt/erpt.cpp
+++ b/src/core/hle/service/erpt/erpt.cpp
@@ -16,7 +16,7 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SubmitContext"},
- {1, nullptr, "CreateReport"},
+ {1, nullptr, "CreateReportV0"},
{2, nullptr, "SetInitialLaunchSettingsCompletionTime"},
{3, nullptr, "ClearInitialLaunchSettingsCompletionTime"},
{4, nullptr, "UpdatePowerOnTime"},
@@ -26,6 +26,11 @@ public:
{8, nullptr, "ClearApplicationLaunchTime"},
{9, nullptr, "SubmitAttachment"},
{10, nullptr, "CreateReportWithAttachments"},
+ {11, nullptr, "CreateReport"},
+ {20, nullptr, "RegisterRunningApplet"},
+ {21, nullptr, "UnregisterRunningApplet"},
+ {22, nullptr, "UpdateAppletSuspendedDuration"},
+ {30, nullptr, "InvalidateForcedShutdownDetection"},
};
// clang-format on
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index b15c737e1..72ad273b2 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/file_util.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/bis_factory.h"
#include "core/file_sys/card_image.h"
@@ -26,7 +27,6 @@
#include "core/hle/service/filesystem/fsp_pr.h"
#include "core/hle/service/filesystem/fsp_srv.h"
#include "core/loader/loader.h"
-#include "core/settings.h"
namespace Service::FileSystem {
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 9cc260515..a0215c4d7 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -118,9 +118,13 @@ public:
explicit IFile(Core::System& system_, FileSys::VirtualFile backend_)
: ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {
static const FunctionInfo functions[] = {
- {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
- {2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
- {4, &IFile::GetSize, "GetSize"}, {5, nullptr, "OperateRange"},
+ {0, &IFile::Read, "Read"},
+ {1, &IFile::Write, "Write"},
+ {2, &IFile::Flush, "Flush"},
+ {3, &IFile::SetSize, "SetSize"},
+ {4, &IFile::GetSize, "GetSize"},
+ {5, nullptr, "OperateRange"},
+ {6, nullptr, "OperateRangeWithBuffer"},
};
RegisterHandlers(functions);
}
@@ -708,7 +712,10 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
{85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"},
{86, nullptr, "OpenSaveDataMover"},
+ {87, nullptr, "OpenSaveDataTransferManagerForRepair"},
{100, nullptr, "OpenImageDirectoryFileSystem"},
+ {101, nullptr, "OpenBaseFileSystem"},
+ {102, nullptr, "FormatBaseFileSystem"},
{110, nullptr, "OpenContentStorageFileSystem"},
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
{130, nullptr, "OpenCustomStorageFileSystem"},
@@ -764,10 +771,12 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{1008, nullptr, "OpenRegisteredUpdatePartition"},
{1009, nullptr, "GetAndClearMemoryReportInfo"},
{1010, nullptr, "SetDataStorageRedirectTarget"},
- {1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
+ {1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"},
{1012, nullptr, "GetFsStackUsage"},
{1013, nullptr, "UnsetSaveDataRootPath"},
{1014, nullptr, "OutputMultiProgramTagAccessLog"},
+ {1016, nullptr, "FlushAccessLogOnSdCard"},
+ {1017, nullptr, "OutputApplicationInfoAccessLog"},
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
{1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"},
@@ -1051,7 +1060,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
-void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
+void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 4};
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index 8ed933279..b01b924eb 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -53,7 +53,7 @@ private:
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
- void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
+ void GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx);
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
FileSystemController& fsc;
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 0a6621ef2..a35979053 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -38,7 +38,7 @@ public:
{10600, nullptr, "DeclareOpenOnlinePlaySession"},
{10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"},
{10610, &IFriendService::UpdateUserPresence, "UpdateUserPresence"},
- {10700, nullptr, "GetPlayHistoryRegistrationKey"},
+ {10700, &IFriendService::GetPlayHistoryRegistrationKey, "GetPlayHistoryRegistrationKey"},
{10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"},
{10702, nullptr, "AddPlayHistory"},
{11000, nullptr, "GetProfileImageUrl"},
@@ -153,6 +153,18 @@ private:
rb.Push(RESULT_SUCCESS);
}
+ void GetPlayHistoryRegistrationKey(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto local_play = rp.Pop<bool>();
+ const auto uuid = rp.PopRaw<Common::UUID>();
+
+ LOG_WARNING(Service_Friend, "(STUBBED) called local_play={} uuid={}", local_play,
+ uuid.Format());
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
void GetFriendList(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto friend_offset = rp.Pop<u32>();
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
index fc77e7286..322125135 100644
--- a/src/core/hle/service/glue/arp.cpp
+++ b/src/core/hle/service/glue/arp.cpp
@@ -41,6 +41,12 @@ ARP_R::ARP_R(Core::System& system_, const ARPManager& manager_)
{1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"},
{2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"},
{3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"},
+ {4, nullptr, "GetApplicationInstanceUnregistrationNotifier"},
+ {5, nullptr, "ListApplicationInstanceId"},
+ {6, nullptr, "GetMicroApplicationInstanceId"},
+ {7, nullptr, "GetApplicationCertificate"},
+ {9998, nullptr, "GetPreomiaApplicationLaunchProperty"},
+ {9999, nullptr, "GetPreomiaApplicationControlProperty"},
};
// clang-format on
@@ -243,7 +249,8 @@ ARP_W::ARP_W(Core::System& system_, ARPManager& manager_)
// clang-format off
static const FunctionInfo functions[] = {
{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
- {1, &ARP_W::DeleteProperties, "DeleteProperties"},
+ {1, &ARP_W::UnregisterApplicationInstance , "UnregisterApplicationInstance "},
+ {2, nullptr, "AcquireUpdater"},
};
// clang-format on
@@ -270,7 +277,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface(registrar);
}
-void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) {
+void ARP_W::UnregisterApplicationInstance(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto process_id = rp.PopRaw<u64>();
diff --git a/src/core/hle/service/glue/arp.h b/src/core/hle/service/glue/arp.h
index 34b412e26..0df3c5e1f 100644
--- a/src/core/hle/service/glue/arp.h
+++ b/src/core/hle/service/glue/arp.h
@@ -32,7 +32,7 @@ public:
private:
void AcquireRegistrar(Kernel::HLERequestContext& ctx);
- void DeleteProperties(Kernel::HLERequestContext& ctx);
+ void UnregisterApplicationInstance(Kernel::HLERequestContext& ctx);
ARPManager& manager;
std::shared_ptr<IRegistrar> registrar;
diff --git a/src/core/hle/service/glue/bgtc.cpp b/src/core/hle/service/glue/bgtc.cpp
index a478b68e1..daecfff15 100644
--- a/src/core/hle/service/glue/bgtc.cpp
+++ b/src/core/hle/service/glue/bgtc.cpp
@@ -2,6 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/hle/ipc_helpers.h"
#include "core/hle/service/glue/bgtc.h"
namespace Service::Glue {
@@ -9,6 +12,26 @@ namespace Service::Glue {
BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} {
// clang-format off
static const FunctionInfo functions[] = {
+ {100, &BGTC_T::OpenTaskService, "OpenTaskService"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+}
+
+BGTC_T::~BGTC_T() = default;
+
+void BGTC_T::OpenTaskService(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_BGTC, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<ITaskService>(system);
+}
+
+ITaskService::ITaskService(Core::System& system_) : ServiceFramework{system_, "ITaskService"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
{1, nullptr, "NotifyTaskStarting"},
{2, nullptr, "NotifyTaskFinished"},
{3, nullptr, "GetTriggerEvent"},
@@ -20,16 +43,18 @@ BGTC_T::BGTC_T(Core::System& system_) : ServiceFramework{system_, "bgtc:t"} {
{13, nullptr, "UnscheduleTask"},
{14, nullptr, "GetScheduleEvent"},
{15, nullptr, "SchedulePeriodicTask"},
+ {16, nullptr, "Unknown16"},
{101, nullptr, "GetOperationMode"},
{102, nullptr, "WillDisconnectNetworkWhenEnteringSleep"},
{103, nullptr, "WillStayHalfAwakeInsteadSleep"},
+ {200, nullptr, "Unknown200"},
};
// clang-format on
RegisterHandlers(functions);
}
-BGTC_T::~BGTC_T() = default;
+ITaskService::~ITaskService() = default;
BGTC_SC::BGTC_SC(Core::System& system_) : ServiceFramework{system_, "bgtc:sc"} {
// clang-format off
diff --git a/src/core/hle/service/glue/bgtc.h b/src/core/hle/service/glue/bgtc.h
index 906116ba6..4c0142fd5 100644
--- a/src/core/hle/service/glue/bgtc.h
+++ b/src/core/hle/service/glue/bgtc.h
@@ -16,6 +16,14 @@ class BGTC_T final : public ServiceFramework<BGTC_T> {
public:
explicit BGTC_T(Core::System& system_);
~BGTC_T() override;
+
+ void OpenTaskService(Kernel::HLERequestContext& ctx);
+};
+
+class ITaskService final : public ServiceFramework<ITaskService> {
+public:
+ explicit ITaskService(Core::System& system_);
+ ~ITaskService() override;
};
class BGTC_SC final : public ServiceFramework<BGTC_SC> {
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index ad251ed4a..a460f2f79 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -4,9 +4,9 @@
#include <cstring>
#include "common/common_types.h"
+#include "common/settings.h"
#include "core/core_timing.h"
#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/settings.h"
namespace Service::HID {
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index 555b29d76..0593d7d39 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -8,10 +8,10 @@
#include "common/bit_field.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "common/settings.h"
#include "common/swap.h"
#include "core/frontend/input.h"
#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/settings.h"
namespace Service::HID {
class Controller_DebugPad final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index 93c43a203..155808f6a 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -5,10 +5,10 @@
#include <cstring>
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core_timing.h"
#include "core/frontend/emu_window.h"
#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/settings.h"
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index c4a59147d..18b76038f 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -4,9 +4,9 @@
#include <cstring>
#include "common/common_types.h"
+#include "common/settings.h"
#include "core/core_timing.h"
#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/settings.h"
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index b5b281752..e72948591 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -8,10 +8,10 @@
#include "common/bit_field.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "common/settings.h"
#include "common/swap.h"
#include "core/frontend/input.h"
#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/settings.h"
namespace Service::HID {
class Controller_Keyboard final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 3b432a36e..0ec0c2b94 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -7,10 +7,10 @@
#include <array>
#include "common/bit_field.h"
#include "common/common_types.h"
+#include "common/settings.h"
#include "common/swap.h"
#include "core/frontend/input.h"
#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/settings.h"
namespace Service::HID {
class Controller_Mouse final : public ControllerBase {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 70b9f3824..783386fcf 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -9,6 +9,7 @@
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/frontend/input.h"
@@ -17,7 +18,6 @@
#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hid/controllers/npad.h"
-#include "core/settings.h"
namespace Service::HID {
constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
@@ -413,12 +413,16 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
}
- if (controller_type == NPadControllerType::JoyLeft ||
- controller_type == NPadControllerType::JoyRight) {
+ if (controller_type == NPadControllerType::JoyLeft) {
pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
}
+ if (controller_type == NPadControllerType::JoyRight) {
+ pad_state.right_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus());
+ pad_state.right_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus());
+ }
+
if (controller_type == NPadControllerType::GameCube) {
trigger_entry.l_analog = static_cast<s32>(
button_state[ZL - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0);
@@ -1134,6 +1138,10 @@ void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_prot
unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled;
}
+void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
+ analog_stick_use_center_clamp = use_center_clamp;
+}
+
void Controller_NPad::ClearAllConnectedControllers() {
for (auto& controller : connected_controllers) {
if (controller.is_connected && controller.type != NPadControllerType::None) {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index bc2e6779d..14d0ac067 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -8,10 +8,10 @@
#include <atomic>
#include "common/bit_field.h"
#include "common/common_types.h"
+#include "common/settings.h"
#include "core/frontend/input.h"
#include "core/hle/kernel/object.h"
#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/settings.h"
namespace Kernel {
class KEvent;
@@ -219,6 +219,7 @@ public:
LedPattern GetLedPattern(u32 npad_id);
bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
+ void SetAnalogStickUseCenterClamp(bool use_center_clamp);
void ClearAllConnectedControllers();
void DisconnectAllConnectedControllers();
void ConnectAllDisconnectedControllers();
@@ -577,6 +578,7 @@ private:
std::array<std::array<bool, 2>, 10> vibration_devices_mounted{};
std::array<ControllerHolder, 10> connected_controllers{};
std::array<bool, 10> unintended_home_button_input_protection{};
+ bool analog_stick_use_center_clamp{};
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
bool sixaxis_sensors_enabled{true};
f32 sixaxis_fusion_parameter1{};
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index be60492a4..b5f8077be 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -6,11 +6,11 @@
#include <cstring>
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core_timing.h"
#include "core/frontend/emu_window.h"
#include "core/frontend/input.h"
#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/settings.h"
namespace Service::HID {
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index ba27bbb05..4c1c0ac68 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -5,6 +5,7 @@
#include <array>
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
@@ -23,7 +24,6 @@
#include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/xcd.h"
#include "core/hle/service/service.h"
-#include "core/settings.h"
#include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/controllers/debug_pad.h"
@@ -263,7 +263,7 @@ Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} {
{131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
{133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
- {134, nullptr, "SetNpadAnalogStickUseCenterClamp"},
+ {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"},
{135, nullptr, "SetNpadCaptureButtonAssignment"},
{136, nullptr, "ClearNpadCaptureButtonAssignment"},
{200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
@@ -278,6 +278,7 @@ Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} {
{209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
{210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
{211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
+ {212, nullptr, "SendVibrationValueInBool"},
{300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
{301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
{302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
@@ -1087,6 +1088,27 @@ void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& c
rb.Push(RESULT_SUCCESS);
}
+void Hid::SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool analog_stick_use_center_clamp;
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp);
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
+ parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()};
@@ -1553,6 +1575,7 @@ public:
{11, nullptr, "SetTouchScreenAutoPilotState"},
{12, nullptr, "UnsetTouchScreenAutoPilotState"},
{13, nullptr, "GetTouchScreenConfiguration"},
+ {14, nullptr, "ProcessTouchScreenAutoTune"},
{20, nullptr, "DeactivateMouse"},
{21, nullptr, "SetMouseAutoPilotState"},
{22, nullptr, "UnsetMouseAutoPilotState"},
@@ -1562,6 +1585,7 @@ public:
{50, nullptr, "DeactivateXpad"},
{51, nullptr, "SetXpadAutoPilotState"},
{52, nullptr, "UnsetXpadAutoPilotState"},
+ {53, nullptr, "DeactivateJoyXpad"},
{60, nullptr, "ClearNpadSystemCommonPolicy"},
{61, nullptr, "DeactivateNpad"},
{62, nullptr, "ForceDisconnectNpad"},
@@ -1632,6 +1656,11 @@ public:
{244, nullptr, "RequestKuinaFirmwareVersion"},
{245, nullptr, "GetKuinaFirmwareVersion"},
{246, nullptr, "GetVidPid"},
+ {247, nullptr, "GetAnalogStickCalibrationValue"},
+ {248, nullptr, "GetUniquePadIdsFull"},
+ {249, nullptr, "ConnectUniquePad"},
+ {250, nullptr, "IsVirtual"},
+ {251, nullptr, "GetAnalogStickModuleParam"},
{301, nullptr, "GetAbstractedPadHandles"},
{302, nullptr, "GetAbstractedPadState"},
{303, nullptr, "GetAbstractedPadsState"},
@@ -1652,12 +1681,16 @@ public:
{401, nullptr, "DisableRailDeviceFiltering"},
{402, nullptr, "EnableWiredPairing"},
{403, nullptr, "EnableShipmentModeAutoClear"},
+ {404, nullptr, "SetRailEnabled"},
{500, nullptr, "SetFactoryInt"},
{501, nullptr, "IsFactoryBootEnabled"},
{550, nullptr, "SetAnalogStickModelDataTemporarily"},
{551, nullptr, "GetAnalogStickModelData"},
{552, nullptr, "ResetAnalogStickModelData"},
{600, nullptr, "ConvertPadState"},
+ {650, nullptr, "AddButtonPlayData"},
+ {651, nullptr, "StartButtonPlayData"},
+ {652, nullptr, "StopButtonPlayData"},
{2000, nullptr, "DeactivateDigitizer"},
{2001, nullptr, "SetDigitizerAutoPilotState"},
{2002, nullptr, "UnsetDigitizerAutoPilotState"},
@@ -1689,6 +1722,8 @@ public:
{215, nullptr, "IsNfcActivated"},
{230, nullptr, "AcquireIrSensorEventHandle"},
{231, nullptr, "ActivateIrSensor"},
+ {232, nullptr, "GetIrSensorState"},
+ {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{301, nullptr, "ActivateNpadSystem"},
{303, nullptr, "ApplyNpadSystemCommonPolicy"},
{304, nullptr, "EnableAssigningSingleOnSlSrPress"},
@@ -1703,9 +1738,16 @@ public:
{313, nullptr, "GetNpadCaptureButtonAssignment"},
{314, nullptr, "GetAppletFooterUiType"},
{315, nullptr, "GetAppletDetailedUiType"},
+ {316, nullptr, "GetNpadInterfaceType"},
+ {317, nullptr, "GetNpadLeftRightInterfaceType"},
+ {318, nullptr, "HasBattery"},
+ {319, nullptr, "HasLeftRightBattery"},
{321, nullptr, "GetUniquePadsFromNpad"},
{322, nullptr, "GetIrSensorState"},
{323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
+ {324, nullptr, "GetUniquePadButtonSet"},
+ {325, nullptr, "GetUniquePadColor"},
+ {326, nullptr, "GetUniquePadAppletDetailedUiType"},
{500, nullptr, "SetAppletResourceUserId"},
{501, nullptr, "RegisterAppletResourceUserId"},
{502, nullptr, "UnregisterAppletResourceUserId"},
@@ -1716,10 +1758,13 @@ public:
{511, nullptr, "GetVibrationMasterVolume"},
{512, nullptr, "BeginPermitVibrationSession"},
{513, nullptr, "EndPermitVibrationSession"},
+ {514, nullptr, "Unknown514"},
{520, nullptr, "EnableHandheldHids"},
{521, nullptr, "DisableHandheldHids"},
{522, nullptr, "SetJoyConRailEnabled"},
{523, nullptr, "IsJoyConRailEnabled"},
+ {524, nullptr, "IsHandheldHidsEnabled"},
+ {525, nullptr, "IsJoyConAttachedOnAllRail"},
{540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
{541, nullptr, "GetPlayReportControllerUsages"},
{542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
@@ -1795,6 +1840,65 @@ public:
{1154, nullptr, "IsFirmwareAvailableForNotification"},
{1155, nullptr, "SetForceHandheldStyleVibration"},
{1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
+ {1157, nullptr, "CancelConnectionTrigger"},
+ {1200, nullptr, "IsButtonConfigSupported"},
+ {1201, nullptr, "IsButtonConfigEmbeddedSupported"},
+ {1202, nullptr, "DeleteButtonConfig"},
+ {1203, nullptr, "DeleteButtonConfigEmbedded"},
+ {1204, nullptr, "SetButtonConfigEnabled"},
+ {1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
+ {1206, nullptr, "IsButtonConfigEnabled"},
+ {1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
+ {1208, nullptr, "SetButtonConfigEmbedded"},
+ {1209, nullptr, "SetButtonConfigFull"},
+ {1210, nullptr, "SetButtonConfigLeft"},
+ {1211, nullptr, "SetButtonConfigRight"},
+ {1212, nullptr, "GetButtonConfigEmbedded"},
+ {1213, nullptr, "GetButtonConfigFull"},
+ {1214, nullptr, "GetButtonConfigLeft"},
+ {1215, nullptr, "GetButtonConfigRight"},
+ {1250, nullptr, "IsCustomButtonConfigSupported"},
+ {1251, nullptr, "IsDefaultButtonConfigEmbedded"},
+ {1252, nullptr, "IsDefaultButtonConfigFull"},
+ {1253, nullptr, "IsDefaultButtonConfigLeft"},
+ {1254, nullptr, "IsDefaultButtonConfigRight"},
+ {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
+ {1256, nullptr, "IsButtonConfigStorageFullEmpty"},
+ {1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
+ {1258, nullptr, "IsButtonConfigStorageRightEmpty"},
+ {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
+ {1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
+ {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
+ {1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
+ {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
+ {1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
+ {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
+ {1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
+ {1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
+ {1268, nullptr, "DeleteButtonConfigStorageFull"},
+ {1269, nullptr, "DeleteButtonConfigStorageLeft"},
+ {1270, nullptr, "DeleteButtonConfigStorageRight"},
+ {1271, nullptr, "IsUsingCustomButtonConfig"},
+ {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
+ {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
+ {1274, nullptr, "SetDefaultButtonConfig"},
+ {1275, nullptr, "SetAllDefaultButtonConfig"},
+ {1276, nullptr, "SetHidButtonConfigEmbedded"},
+ {1277, nullptr, "SetHidButtonConfigFull"},
+ {1278, nullptr, "SetHidButtonConfigLeft"},
+ {1279, nullptr, "SetHidButtonConfigRight"},
+ {1280, nullptr, "GetHidButtonConfigEmbedded"},
+ {1281, nullptr, "GetHidButtonConfigFull"},
+ {1282, nullptr, "GetHidButtonConfigLeft"},
+ {1283, nullptr, "GetHidButtonConfigRight"},
+ {1284, nullptr, "GetButtonConfigStorageEmbedded"},
+ {1285, nullptr, "GetButtonConfigStorageFull"},
+ {1286, nullptr, "GetButtonConfigStorageLeft"},
+ {1287, nullptr, "GetButtonConfigStorageRight"},
+ {1288, nullptr, "SetButtonConfigStorageEmbedded"},
+ {1289, nullptr, "SetButtonConfigStorageFull"},
+ {1290, nullptr, "DeleteButtonConfigStorageRight"},
+ {1291, nullptr, "DeleteButtonConfigStorageRight"},
};
// clang-format on
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 36ed228c8..c2bdd39a3 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -129,6 +129,7 @@ private:
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx);
void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx);
+ void SetNpadAnalogStickUseCenterClamp(Kernel::HLERequestContext& ctx);
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
void SendVibrationValue(Kernel::HLERequestContext& ctx);
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/hid/xcd.cpp b/src/core/hle/service/hid/xcd.cpp
index 43a8840d0..b1efa3d05 100644
--- a/src/core/hle/service/hid/xcd.cpp
+++ b/src/core/hle/service/hid/xcd.cpp
@@ -28,6 +28,8 @@ XCD_SYS::XCD_SYS(Core::System& system_) : ServiceFramework{system_, "xcd:sys"} {
{20, nullptr, "StartMifareWrite"},
{101, nullptr, "GetAwakeTriggerReasonForLeftRail"},
{102, nullptr, "GetAwakeTriggerReasonForRightRail"},
+ {103, nullptr, "GetAwakeTriggerBatteryLevelTransitionForLeftRail"},
+ {104, nullptr, "GetAwakeTriggerBatteryLevelTransitionForRightRail"},
};
// clang-format on
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index d111c1357..c8bc60ad1 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -118,9 +118,9 @@ public:
explicit DebugMonitor(Core::System& system_) : ServiceFramework{system_, "ldr:dmnt"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "AddProcessToDebugLaunchQueue"},
- {1, nullptr, "ClearDebugLaunchQueue"},
- {2, nullptr, "GetNsoInfos"},
+ {0, nullptr, "SetProgramArgument"},
+ {1, nullptr, "FlushArguments"},
+ {2, nullptr, "GetProcessModuleInfo"},
};
// clang-format on
@@ -135,8 +135,8 @@ public:
static const FunctionInfo functions[] = {
{0, nullptr, "CreateProcess"},
{1, nullptr, "GetProgramInfo"},
- {2, nullptr, "RegisterTitle"},
- {3, nullptr, "UnregisterTitle"},
+ {2, nullptr, "PinProgram"},
+ {3, nullptr, "UnpinProgram"},
{4, nullptr, "SetEnabledProgramVerification"},
};
// clang-format on
@@ -150,8 +150,8 @@ public:
explicit Shell(Core::System& system_) : ServiceFramework{system_, "ldr:shel"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "AddProcessToLaunchQueue"},
- {1, nullptr, "ClearLaunchQueue"},
+ {0, nullptr, "SetProgramArgument"},
+ {1, nullptr, "FlushArguments"},
};
// clang-format on
@@ -164,19 +164,19 @@ public:
explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &RelocatableObject::LoadNro, "LoadNro"},
- {1, &RelocatableObject::UnloadNro, "UnloadNro"},
- {2, &RelocatableObject::LoadNrr, "LoadNrr"},
- {3, &RelocatableObject::UnloadNrr, "UnloadNrr"},
+ {0, &RelocatableObject::LoadModule, "LoadModule"},
+ {1, &RelocatableObject::UnloadModule, "UnloadModule"},
+ {2, &RelocatableObject::RegisterModuleInfo, "RegisterModuleInfo"},
+ {3, &RelocatableObject::UnregisterModuleInfo, "UnregisterModuleInfo"},
{4, &RelocatableObject::Initialize, "Initialize"},
- {10, nullptr, "LoadNrrEx"},
+ {10, nullptr, "RegisterModuleInfo2"},
};
// clang-format on
RegisterHandlers(functions);
}
- void LoadNrr(Kernel::HLERequestContext& ctx) {
+ void RegisterModuleInfo(Kernel::HLERequestContext& ctx) {
struct Parameters {
u64_le process_id;
u64_le nrr_address;
@@ -273,7 +273,7 @@ public:
rb.Push(RESULT_SUCCESS);
}
- void UnloadNrr(Kernel::HLERequestContext& ctx) {
+ void UnregisterModuleInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto pid = rp.Pop<u64>();
const auto nrr_address = rp.Pop<VAddr>();
@@ -408,7 +408,7 @@ public:
data_start, bss_end_addr - data_start, Kernel::KMemoryPermission::ReadAndWrite);
}
- void LoadNro(Kernel::HLERequestContext& ctx) {
+ void LoadModule(Kernel::HLERequestContext& ctx) {
struct Parameters {
u64_le process_id;
u64_le image_address;
@@ -546,7 +546,7 @@ public:
return RESULT_SUCCESS;
}
- void UnloadNro(Kernel::HLERequestContext& ctx) {
+ void UnloadModule(Kernel::HLERequestContext& ctx) {
if (!initialized) {
LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!");
IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index 6ab35de47..44a5d5789 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -5,12 +5,12 @@
#include <memory>
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
-#include "core/settings.h"
namespace Service::NFC {
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index afb3342d6..9f110df8e 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/settings.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
@@ -10,7 +11,6 @@
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/service.h"
#include "core/network/network.h"
-#include "core/settings.h"
namespace Service::NIFM {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index f3be0b878..fee360ab9 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -125,51 +125,51 @@ public:
{39, nullptr, "PrepareShutdown"},
{40, nullptr, "ListApplyDeltaTask"},
{41, nullptr, "ClearNotEnoughSpaceStateOfApplyDeltaTask"},
- {42, nullptr, "Unknown42"},
- {43, nullptr, "Unknown43"},
- {44, nullptr, "Unknown44"},
- {45, nullptr, "Unknown45"},
- {46, nullptr, "Unknown46"},
- {47, nullptr, "Unknown47"},
- {48, nullptr, "Unknown48"},
- {49, nullptr, "Unknown49"},
- {50, nullptr, "Unknown50"},
- {51, nullptr, "Unknown51"},
- {52, nullptr, "Unknown52"},
- {53, nullptr, "Unknown53"},
- {54, nullptr, "Unknown54"},
- {55, nullptr, "Unknown55"},
- {56, nullptr, "Unknown56"},
- {57, nullptr, "Unknown57"},
- {58, nullptr, "Unknown58"},
- {59, nullptr, "Unknown59"},
- {60, nullptr, "Unknown60"},
- {61, nullptr, "Unknown61"},
- {62, nullptr, "Unknown62"},
- {63, nullptr, "Unknown63"},
- {64, nullptr, "Unknown64"},
- {65, nullptr, "Unknown65"},
- {66, nullptr, "Unknown66"},
- {67, nullptr, "Unknown67"},
- {68, nullptr, "Unknown68"},
- {69, nullptr, "Unknown69"},
- {70, nullptr, "Unknown70"},
- {71, nullptr, "Unknown71"},
- {72, nullptr, "Unknown72"},
- {73, nullptr, "Unknown73"},
- {74, nullptr, "Unknown74"},
- {75, nullptr, "Unknown75"},
- {76, nullptr, "Unknown76"},
- {77, nullptr, "Unknown77"},
- {78, nullptr, "Unknown78"},
- {79, nullptr, "Unknown79"},
- {80, nullptr, "Unknown80"},
- {81, nullptr, "Unknown81"},
- {82, nullptr, "Unknown82"},
- {83, nullptr, "Unknown83"},
+ {42, nullptr, "CreateApplyDeltaTaskFromDownloadTask"},
+ {43, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"},
+ {44, nullptr, "GetApplyDeltaTaskRequiredStorage"},
+ {45, nullptr, "CalculateNetworkInstallTaskContentsSize"},
+ {46, nullptr, "PrepareShutdownForSystemUpdate"},
+ {47, nullptr, "FindMaxRequiredApplicationVersionOfTask"},
+ {48, nullptr, "CommitNetworkInstallTaskPartially"},
+ {49, nullptr, "ListNetworkInstallTaskCommittedContentMeta"},
+ {50, nullptr, "ListNetworkInstallTaskNotCommittedContentMeta"},
+ {51, nullptr, "FindMaxRequiredSystemVersionOfTask"},
+ {52, nullptr, "GetNetworkInstallTaskErrorContext"},
+ {53, nullptr, "CreateLocalCommunicationReceiveApplicationTask"},
+ {54, nullptr, "DestroyLocalCommunicationReceiveApplicationTask"},
+ {55, nullptr, "ListLocalCommunicationReceiveApplicationTask"},
+ {56, nullptr, "RequestLocalCommunicationReceiveApplicationTaskRun"},
+ {57, nullptr, "GetLocalCommunicationReceiveApplicationTaskInfo"},
+ {58, nullptr, "CommitLocalCommunicationReceiveApplicationTask"},
+ {59, nullptr, "ListLocalCommunicationReceiveApplicationTaskContentMeta"},
+ {60, nullptr, "CreateLocalCommunicationSendApplicationTask"},
+ {61, nullptr, "RequestLocalCommunicationSendApplicationTaskRun"},
+ {62, nullptr, "GetLocalCommunicationReceiveApplicationTaskErrorContext"},
+ {63, nullptr, "GetLocalCommunicationSendApplicationTaskInfo"},
+ {64, nullptr, "DestroyLocalCommunicationSendApplicationTask"},
+ {65, nullptr, "GetLocalCommunicationSendApplicationTaskErrorContext"},
+ {66, nullptr, "CalculateLocalCommunicationReceiveApplicationTaskRequiredSize"},
+ {67, nullptr, "ListApplicationLocalCommunicationReceiveApplicationTask"},
+ {68, nullptr, "ListApplicationLocalCommunicationSendApplicationTask"},
+ {69, nullptr, "CreateLocalCommunicationReceiveSystemUpdateTask"},
+ {70, nullptr, "DestroyLocalCommunicationReceiveSystemUpdateTask"},
+ {71, nullptr, "ListLocalCommunicationReceiveSystemUpdateTask"},
+ {72, nullptr, "RequestLocalCommunicationReceiveSystemUpdateTaskRun"},
+ {73, nullptr, "GetLocalCommunicationReceiveSystemUpdateTaskInfo"},
+ {74, nullptr, "CommitLocalCommunicationReceiveSystemUpdateTask"},
+ {75, nullptr, "GetLocalCommunicationReceiveSystemUpdateTaskErrorContext"},
+ {76, nullptr, "CreateLocalCommunicationSendSystemUpdateTask"},
+ {77, nullptr, "RequestLocalCommunicationSendSystemUpdateTaskRun"},
+ {78, nullptr, "GetLocalCommunicationSendSystemUpdateTaskInfo"},
+ {79, nullptr, "DestroyLocalCommunicationSendSystemUpdateTask"},
+ {80, nullptr, "GetLocalCommunicationSendSystemUpdateTaskErrorContext"},
+ {81, nullptr, "ListLocalCommunicationSendSystemUpdateTask"},
+ {82, nullptr, "GetReceivedSystemDataPath"},
+ {83, nullptr, "CalculateApplyDeltaTaskOccupiedSize"},
{84, nullptr, "Unknown84"},
- {85, nullptr, "Unknown85"},
- {86, nullptr, "Unknown86"},
+ {85, nullptr, "ListNetworkInstallTaskContentMetaFromInstallMeta"},
+ {86, nullptr, "ListNetworkInstallTaskOccupiedSize"},
{87, nullptr, "Unknown87"},
{88, nullptr, "Unknown88"},
{89, nullptr, "Unknown89"},
@@ -202,6 +202,17 @@ public:
{116, nullptr, "Unknown116"},
{117, nullptr, "Unknown117"},
{118, nullptr, "Unknown118"},
+ {119, nullptr, "Unknown119"},
+ {120, nullptr, "Unknown120"},
+ {121, nullptr, "Unknown121"},
+ {122, nullptr, "Unknown122"},
+ {123, nullptr, "Unknown123"},
+ {124, nullptr, "Unknown124"},
+ {125, nullptr, "Unknown125"},
+ {126, nullptr, "Unknown126"},
+ {127, nullptr, "Unknown127"},
+ {128, nullptr, "Unknown128"},
+ {129, nullptr, "Unknown129"},
};
// clang-format on
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp
index f7a58f659..e4c703da4 100644
--- a/src/core/hle/service/npns/npns.cpp
+++ b/src/core/hle/service/npns/npns.cpp
@@ -49,6 +49,8 @@ public:
{151, nullptr, "GetStateWithHandover"},
{152, nullptr, "GetStateChangeEventWithHandover"},
{153, nullptr, "GetDropEventWithHandover"},
+ {154, nullptr, "CreateTokenAsync"},
+ {155, nullptr, "CreateTokenAsyncWithApplicationId"},
{161, nullptr, "GetRequestChangeStateCancelEvent"},
{162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"},
{201, nullptr, "RequestChangeStateForceTimed"},
@@ -84,6 +86,7 @@ public:
{151, nullptr, "GetStateWithHandover"},
{152, nullptr, "GetStateChangeEventWithHandover"},
{153, nullptr, "GetDropEventWithHandover"},
+ {154, nullptr, "CreateTokenAsync"},
};
// clang-format on
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 6ccf8995c..e373609a1 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
@@ -14,7 +15,6 @@
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/ns/pl_u.h"
#include "core/hle/service/set/set.h"
-#include "core/settings.h"
namespace Service::NS {
@@ -55,6 +55,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{26, nullptr, "BeginInstallApplication"},
{27, nullptr, "DeleteApplicationRecord"},
{30, nullptr, "RequestApplicationUpdateInfo"},
+ {31, nullptr, "Unknown31"},
{32, nullptr, "CancelApplicationDownload"},
{33, nullptr, "ResumeApplicationDownload"},
{35, nullptr, "UpdateVersionList"},
@@ -182,6 +183,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{913, nullptr, "ListAllApplicationRecord"},
{914, nullptr, "HideApplicationRecord"},
{915, nullptr, "ShowApplicationRecord"},
+ {916, nullptr, "IsApplicationAutoDeleteDisabled"},
{1000, nullptr, "RequestVerifyApplicationDeprecated"},
{1001, nullptr, "CorruptApplicationForDebug"},
{1002, nullptr, "RequestVerifyAddOnContentsRights"},
@@ -201,6 +203,8 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{1310, nullptr, "RequestMoveApplicationEntity"},
{1311, nullptr, "EstimateSizeToMove"},
{1312, nullptr, "HasMovableEntity"},
+ {1313, nullptr, "CleanupOrphanContents"},
+ {1314, nullptr, "CheckPreconditionSatisfiedToMove"},
{1400, nullptr, "PrepareShutdown"},
{1500, nullptr, "FormatSdCard"},
{1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
@@ -215,6 +219,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
{1704, nullptr, "GetApplicationViewWithPromotionInfo"},
+ {1705, nullptr, "IsPatchAutoDeletableApplication"},
{1800, nullptr, "IsNotificationSetupCompleted"},
{1801, nullptr, "GetLastNotificationInfoCount"},
{1802, nullptr, "ListLastNotificationInfo"},
@@ -269,6 +274,9 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{2351, nullptr, "RequestNoDownloadRightsErrorResolution"},
{2352, nullptr, "RequestResolveNoDownloadRightsError"},
{2353, nullptr, "GetApplicationDownloadTaskInfo"},
+ {2354, nullptr, "PrioritizeApplicationBackgroundTask"},
+ {2355, nullptr, "Unknown2355"},
+ {2356, nullptr, "Unknown2356"},
{2400, nullptr, "GetPromotionInfo"},
{2401, nullptr, "CountPromotionInfo"},
{2402, nullptr, "ListPromotionInfo"},
@@ -282,6 +290,21 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"},
{2516, nullptr, "EnsureApplicationCertificate"},
{2800, nullptr, "GetApplicationIdOfPreomia"},
+ {3000, nullptr, "RegisterDeviceLockKey"},
+ {3001, nullptr, "UnregisterDeviceLockKey"},
+ {3002, nullptr, "VerifyDeviceLockKey"},
+ {3003, nullptr, "HideApplicationIcon"},
+ {3004, nullptr, "ShowApplicationIcon"},
+ {3005, nullptr, "HideApplicationTitle"},
+ {3006, nullptr, "ShowApplicationTitle"},
+ {3007, nullptr, "EnableGameCard"},
+ {3008, nullptr, "DisableGameCard"},
+ {3009, nullptr, "EnableLocalContentShare"},
+ {3010, nullptr, "DisableLocalContentShare"},
+ {3011, nullptr, "IsApplicationIconHidden"},
+ {3012, nullptr, "IsApplicationTitleHidden"},
+ {3013, nullptr, "IsGameCardEnabled"},
+ {3014, nullptr, "IsLocalContentShareEnabled"},
{9999, nullptr, "GetApplicationCertificate"},
};
// clang-format on
@@ -441,7 +464,11 @@ IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_
{800, nullptr, "RequestVersionList"},
{801, nullptr, "ListVersionList"},
{802, nullptr, "RequestVersionListData"},
+ {900, nullptr, "ImportAutoUpdatePolicyJsonForDebug"},
+ {901, nullptr, "ListDefaultAutoUpdatePolicy"},
+ {902, nullptr, "ListAutoUpdatePolicyForSpecificApplication"},
{1000, nullptr, "PerformAutoUpdate"},
+ {1001, nullptr, "ListAutoUpdateSchedule"},
};
// clang-format on
@@ -547,6 +574,9 @@ IFactoryResetInterface::~IFactoryResetInterface() = default;
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
+ {7988, nullptr, "GetDynamicRightsInterface"},
+ {7989, nullptr, "GetReadOnlyApplicationControlDataInterface"},
+ {7991, nullptr, "GetReadOnlyApplicationRecordInterface"},
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
@@ -575,18 +605,22 @@ public:
{0, nullptr, "LaunchProgram"},
{1, nullptr, "TerminateProcess"},
{2, nullptr, "TerminateProgram"},
- {4, nullptr, "GetShellEventHandle"},
+ {4, nullptr, "GetShellEvent"},
{5, nullptr, "GetShellEventInfo"},
{6, nullptr, "TerminateApplication"},
{7, nullptr, "PrepareLaunchProgramFromHost"},
- {8, nullptr, "LaunchApplication"},
+ {8, nullptr, "LaunchApplicationFromHost"},
{9, nullptr, "LaunchApplicationWithStorageIdForDevelop"},
{10, nullptr, "IsSystemMemoryResourceLimitBoosted"},
{11, nullptr, "GetRunningApplicationProcessIdForDevelop"},
- {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"},
+ {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"},
{13, nullptr, "CreateApplicationResourceForDevelop"},
{14, nullptr, "IsPreomiaForDevelop"},
{15, nullptr, "GetApplicationProgramIdFromHost"},
+ {16, nullptr, "RefreshCachedDebugValues"},
+ {17, nullptr, "PrepareLaunchApplicationFromHost"},
+ {18, nullptr, "GetLaunchEvent"},
+ {19, nullptr, "GetLaunchResult"},
};
// clang-format on
@@ -699,6 +733,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system
std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager);
std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager);
std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager);
+ std::make_shared<NS>("ns:ro", system)->InstallAsService(service_manager);
std::make_shared<NS_DEV>(system)->InstallAsService(service_manager);
std::make_shared<NS_SU>(system)->InstallAsService(service_manager);
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index fcd15d81f..da139fdc4 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -154,6 +154,10 @@ PL_U::PL_U(Core::System& system_)
{100, nullptr, "RequestApplicationFunctionAuthorization"},
{101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"},
{102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"},
+ {103, nullptr, "RefreshApplicationFunctionBlackListDebugRecord"},
+ {104, nullptr, "RequestApplicationFunctionAuthorizationByProgramId"},
+ {105, nullptr, "GetFunctionBlackListSystemVersionToAuthorize"},
+ {106, nullptr, "GetFunctionBlackListVersion"},
{1000, nullptr, "LoadNgWordDataForPlatformRegionChina"},
{1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"},
};
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 933d42f3f..2edd803f3 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -248,7 +248,13 @@ NvResult nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<
IoctlZbcSetTable params{};
std::memcpy(&params, input.data(), input.size());
// TODO(ogniK): What does this even actually do?
- std::memcpy(output.data(), &params, output.size());
+
+ // Prevent null pointer being passed as arg 1
+ if (output.empty()) {
+ LOG_WARNING(Service_NVDRV, "Avoiding passing null pointer to memcpy");
+ } else {
+ std::memcpy(output.data(), &params, output.size());
+ }
return NvResult::Success;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 4898dc27a..c2f152190 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -23,17 +23,22 @@ namespace {
template <typename T>
std::size_t SpliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count,
std::size_t offset) {
- std::memcpy(dst.data(), input.data() + offset, count * sizeof(T));
- offset += count * sizeof(T);
- return offset;
+ if (!dst.empty()) {
+ std::memcpy(dst.data(), input.data() + offset, count * sizeof(T));
+ }
+ return 0;
}
// Write vectors will write data to the output buffer
template <typename T>
std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) {
- std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T));
- offset += src.size() * sizeof(T);
- return offset;
+ if (src.empty()) {
+ return 0;
+ } else {
+ std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T));
+ offset += src.size() * sizeof(T);
+ return offset;
+ }
}
} // Anonymous namespace
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index ac2906e5b..539b02bc4 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -9,6 +9,7 @@
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/scope_exit.h"
+#include "common/settings.h"
#include "common/thread.h"
#include "core/core.h"
#include "core/core_timing.h"
@@ -23,7 +24,6 @@
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
#include "core/perf_stats.h"
-#include "core/settings.h"
#include "video_core/renderer_base.h"
namespace Service::NVFlinger {
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index e2ac71fa1..b066c3417 100644
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -26,6 +26,7 @@ public:
{22, nullptr, "DeleteSaveDataBackupAsync"},
{25, nullptr, "ListDownloadableSaveDataBackupInfoAsync"},
{26, nullptr, "DownloadSaveDataBackupAsync"},
+ {27, nullptr, "UploadSaveDataBackupAsync"},
{9010, nullptr, "VerifySaveDataBackupLicenseAsyncForDebug"},
{9013, nullptr, "GetSaveDataBackupSettingForDebug"},
{9014, nullptr, "SetSaveDataBackupSettingEnabledForDebug"},
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp
index f6686fc4d..9bc851591 100644
--- a/src/core/hle/service/pcie/pcie.cpp
+++ b/src/core/hle/service/pcie/pcie.cpp
@@ -37,7 +37,7 @@ public:
{19, nullptr, "SetIrqEnable"},
{20, nullptr, "SetAspmEnable"},
{21, nullptr, "SetResetUponResumeEnable"},
- {22, nullptr, "Unknown22"},
+ {22, nullptr, "ResetFunction"},
{23, nullptr, "Unknown23"},
};
// clang-format on
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp
index f9089bf2f..dc59702f1 100644
--- a/src/core/hle/service/pctl/module.cpp
+++ b/src/core/hle/service/pctl/module.cpp
@@ -3,16 +3,30 @@
// Refer to the license.txt file included.
#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/service/pctl/module.h"
#include "core/hle/service/pctl/pctl.h"
namespace Service::PCTL {
+namespace Error {
+
+constexpr ResultCode ResultNoFreeCommunication{ErrorModule::PCTL, 101};
+constexpr ResultCode ResultStereoVisionRestricted{ErrorModule::PCTL, 104};
+constexpr ResultCode ResultNoCapability{ErrorModule::PCTL, 131};
+constexpr ResultCode ResultNoRestrictionEnabled{ErrorModule::PCTL, 181};
+
+} // namespace Error
+
class IParentalControlService final : public ServiceFramework<IParentalControlService> {
public:
- explicit IParentalControlService(Core::System& system_)
- : ServiceFramework{system_, "IParentalControlService"} {
+ explicit IParentalControlService(Core::System& system_, Capability capability)
+ : ServiceFramework{system_, "IParentalControlService"}, system(system_),
+ capability(capability) {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IParentalControlService::Initialize, "Initialize"},
@@ -28,13 +42,13 @@ public:
{1010, nullptr, "IsRestrictedSystemSettingsEntered"},
{1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
{1012, nullptr, "GetRestrictedFeatures"},
- {1013, nullptr, "ConfirmStereoVisionPermission"},
+ {1013, &IParentalControlService::ConfirmStereoVisionPermission, "ConfirmStereoVisionPermission"},
{1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
{1015, nullptr, "ConfirmPlayableApplicationVideo"},
{1016, nullptr, "ConfirmShowNewsPermission"},
{1017, nullptr, "EndFreeCommunication"},
- {1018, nullptr, "IsFreeCommunicationAvailable"},
- {1031, nullptr, "IsRestrictionEnabled"},
+ {1018, &IParentalControlService::IsFreeCommunicationAvailable, "IsFreeCommunicationAvailable"},
+ {1031, &IParentalControlService::IsRestrictionEnabled, "IsRestrictionEnabled"},
{1032, nullptr, "GetSafetyLevel"},
{1033, nullptr, "SetSafetyLevel"},
{1034, nullptr, "GetSafetyLevelSettings"},
@@ -50,6 +64,7 @@ public:
{1046, nullptr, "DisableFeaturesForReset"},
{1047, nullptr, "NotifyApplicationDownloadStarted"},
{1048, nullptr, "NotifyNetworkProfileCreated"},
+ {1049, nullptr, "ResetFreeCommunicationApplicationList"},
{1061, &IParentalControlService::ConfirmStereoVisionRestrictionConfigurable, "ConfirmStereoVisionRestrictionConfigurable"},
{1062, &IParentalControlService::GetStereoVisionRestriction, "GetStereoVisionRestriction"},
{1063, &IParentalControlService::SetStereoVisionRestriction, "SetStereoVisionRestriction"},
@@ -69,6 +84,8 @@ public:
{1421, nullptr, "GetAccountNickname"},
{1424, nullptr, "GetAccountState"},
{1425, nullptr, "RequestPostEvents"},
+ {1426, nullptr, "GetPostEventInterval"},
+ {1427, nullptr, "SetPostEventInterval"},
{1432, nullptr, "GetSynchronizationEvent"},
{1451, nullptr, "StartPlayTimer"},
{1452, nullptr, "StopPlayTimer"},
@@ -119,62 +136,235 @@ public:
}
private:
+ bool CheckFreeCommunicationPermissionImpl() const {
+ if (states.temporary_unlocked) {
+ return true;
+ }
+ if ((states.application_info.parental_control_flag & 1) == 0) {
+ return true;
+ }
+ if (pin_code[0] == '\0') {
+ return true;
+ }
+ if (!settings.is_free_communication_default_on) {
+ return true;
+ }
+ // TODO(ogniK): Check for blacklisted/exempted applications. Return false can happen here
+ // but as we don't have multiproceses support yet, we can just assume our application is
+ // valid for the time being
+ return true;
+ }
+
+ bool ConfirmStereoVisionPermissionImpl() const {
+ if (states.temporary_unlocked) {
+ return true;
+ }
+ if (pin_code[0] == '\0') {
+ return true;
+ }
+ if (!settings.is_stero_vision_restricted) {
+ return false;
+ }
+ return true;
+ }
+
+ void SetStereoVisionRestrictionImpl(bool is_restricted) {
+ if (settings.disabled) {
+ return;
+ }
+
+ if (pin_code[0] == '\0') {
+ return;
+ }
+ settings.is_stero_vision_restricted = is_restricted;
+ }
+
void Initialize(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_PCTL, "(STUBBED) called");
+ LOG_DEBUG(Service_PCTL, "called");
+ IPC::ResponseBuilder rb{ctx, 2};
+
+ if (False(capability & (Capability::Application | Capability::System))) {
+ LOG_ERROR(Service_PCTL, "Invalid capability! capability={:X}", capability);
+ return;
+ }
+
+ // TODO(ogniK): Recovery flag initialization for pctl:r
+
+ const auto tid = system.CurrentProcess()->GetTitleID();
+ if (tid != 0) {
+ const FileSys::PatchManager pm{tid, system.GetFileSystemController(),
+ system.GetContentProvider()};
+ const auto control = pm.GetControlMetadata();
+ if (control.first) {
+ states.tid_from_event = 0;
+ states.launch_time_valid = false;
+ states.is_suspended = false;
+ states.free_communication = false;
+ states.stereo_vision = false;
+ states.application_info = ApplicationInfo{
+ .tid = tid,
+ .age_rating = control.first->GetRatingAge(),
+ .parental_control_flag = control.first->GetParentalControlFlag(),
+ .capability = capability,
+ };
+
+ if (False(capability & (Capability::System | Capability::Recovery))) {
+ // TODO(ogniK): Signal application launch event
+ }
+ }
+ }
- IPC::ResponseBuilder rb{ctx, 2, 0, 0};
rb.Push(RESULT_SUCCESS);
}
void CheckFreeCommunicationPermission(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_PCTL, "(STUBBED) called");
+ LOG_DEBUG(Service_PCTL, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ if (!CheckFreeCommunicationPermissionImpl()) {
+ rb.Push(Error::ResultNoFreeCommunication);
+ } else {
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ states.free_communication = true;
+ }
+
+ void ConfirmStereoVisionPermission(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_PCTL, "called");
+ states.stereo_vision = true;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
- void ConfirmStereoVisionRestrictionConfigurable(Kernel::HLERequestContext& ctx) {
+ void IsFreeCommunicationAvailable(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_PCTL, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
+ if (!CheckFreeCommunicationPermissionImpl()) {
+ rb.Push(Error::ResultNoFreeCommunication);
+ } else {
+ rb.Push(RESULT_SUCCESS);
+ }
+ }
+
+ void IsRestrictionEnabled(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_PCTL, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ if (False(capability & (Capability::Status | Capability::Recovery))) {
+ LOG_ERROR(Service_PCTL, "Application does not have Status or Recovery capabilities!");
+ rb.Push(Error::ResultNoCapability);
+ rb.Push(false);
+ return;
+ }
+
+ rb.Push(pin_code[0] != '\0');
+ }
+
+ void ConfirmStereoVisionRestrictionConfigurable(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_PCTL, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+
+ if (False(capability & Capability::StereoVision)) {
+ LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
+ rb.Push(Error::ResultNoCapability);
+ return;
+ }
+
+ if (pin_code[0] == '\0') {
+ rb.Push(Error::ResultNoRestrictionEnabled);
+ return;
+ }
+
rb.Push(RESULT_SUCCESS);
}
void IsStereoVisionPermitted(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_PCTL, "(STUBBED) called");
+ LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(true);
+ if (!ConfirmStereoVisionPermissionImpl()) {
+ rb.Push(Error::ResultStereoVisionRestricted);
+ rb.Push(false);
+ } else {
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(true);
+ }
}
void SetStereoVisionRestriction(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_use = rp.Pop<bool>();
- LOG_WARNING(Service_PCTL, "(STUBBED) called, can_use={}", can_use);
-
- can_use_stereo_vision = can_use;
+ LOG_DEBUG(Service_PCTL, "called, can_use={}", can_use);
IPC::ResponseBuilder rb{ctx, 2};
+ if (False(capability & Capability::StereoVision)) {
+ LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
+ rb.Push(Error::ResultNoCapability);
+ return;
+ }
+
+ SetStereoVisionRestrictionImpl(can_use);
rb.Push(RESULT_SUCCESS);
}
void GetStereoVisionRestriction(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_PCTL, "(STUBBED) called");
+ LOG_DEBUG(Service_PCTL, "called");
IPC::ResponseBuilder rb{ctx, 3};
+ if (False(capability & Capability::StereoVision)) {
+ LOG_ERROR(Service_PCTL, "Application does not have StereoVision capability!");
+ rb.Push(Error::ResultNoCapability);
+ rb.Push(false);
+ return;
+ }
+
rb.Push(RESULT_SUCCESS);
- rb.Push(can_use_stereo_vision);
+ rb.Push(settings.is_stero_vision_restricted);
}
void ResetConfirmedStereoVisionPermission(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_PCTL, "(STUBBED) called");
+ LOG_DEBUG(Service_PCTL, "called");
+
+ states.stereo_vision = false;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
+ struct ApplicationInfo {
+ u64 tid{};
+ std::array<u8, 32> age_rating{};
+ u32 parental_control_flag{};
+ Capability capability{};
+ };
+
+ struct States {
+ u64 current_tid{};
+ ApplicationInfo application_info{};
+ u64 tid_from_event{};
+ bool launch_time_valid{};
+ bool is_suspended{};
+ bool temporary_unlocked{};
+ bool free_communication{};
+ bool stereo_vision{};
+ };
+
+ struct ParentalControlSettings {
+ bool is_stero_vision_restricted{};
+ bool is_free_communication_default_on{};
+ bool disabled{};
+ };
+
+ States states{};
+ ParentalControlSettings settings{};
+ std::array<char, 8> pin_code{};
bool can_use_stereo_vision = true;
+ Core::System& system;
+ Capability capability{};
};
void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
@@ -182,7 +372,9 @@ void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IParentalControlService>(system);
+ // TODO(ogniK): Get TID from process
+
+ rb.PushIpcInterface<IParentalControlService>(system, capability);
}
void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) {
@@ -190,21 +382,28 @@ void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IParentalControlService>(system);
+ rb.PushIpcInterface<IParentalControlService>(system, capability);
}
Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
- const char* name)
- : ServiceFramework{system_, name}, module{std::move(module_)} {}
+ const char* name, Capability capability)
+ : ServiceFramework{system_, name}, module{std::move(module_)}, capability(capability) {}
Module::Interface::~Interface() = default;
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
auto module = std::make_shared<Module>();
- std::make_shared<PCTL>(system, module, "pctl")->InstallAsService(service_manager);
- std::make_shared<PCTL>(system, module, "pctl:a")->InstallAsService(service_manager);
- std::make_shared<PCTL>(system, module, "pctl:r")->InstallAsService(service_manager);
- std::make_shared<PCTL>(system, module, "pctl:s")->InstallAsService(service_manager);
+ std::make_shared<PCTL>(system, module, "pctl",
+ Capability::Application | Capability::SnsPost | Capability::Status |
+ Capability::StereoVision)
+ ->InstallAsService(service_manager);
+ // TODO(ogniK): Implement remaining capabilities
+ std::make_shared<PCTL>(system, module, "pctl:a", Capability::None)
+ ->InstallAsService(service_manager);
+ std::make_shared<PCTL>(system, module, "pctl:r", Capability::None)
+ ->InstallAsService(service_manager);
+ std::make_shared<PCTL>(system, module, "pctl:s", Capability::None)
+ ->InstallAsService(service_manager);
}
} // namespace Service::PCTL
diff --git a/src/core/hle/service/pctl/module.h b/src/core/hle/service/pctl/module.h
index 4c7e09a3b..032481b00 100644
--- a/src/core/hle/service/pctl/module.h
+++ b/src/core/hle/service/pctl/module.h
@@ -4,6 +4,7 @@
#pragma once
+#include "common/common_funcs.h"
#include "core/hle/service/service.h"
namespace Core {
@@ -12,12 +13,23 @@ class System;
namespace Service::PCTL {
+enum class Capability : u32 {
+ None = 0,
+ Application = 1 << 0,
+ SnsPost = 1 << 1,
+ Recovery = 1 << 6,
+ Status = 1 << 8,
+ StereoVision = 1 << 9,
+ System = 1 << 15,
+};
+DECLARE_ENUM_FLAG_OPERATORS(Capability);
+
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
- explicit Interface(Core::System& system_, std::shared_ptr<Module> module_,
- const char* name);
+ explicit Interface(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
+ Capability capability);
~Interface() override;
void CreateService(Kernel::HLERequestContext& ctx);
@@ -25,6 +37,9 @@ public:
protected:
std::shared_ptr<Module> module;
+
+ private:
+ Capability capability{};
};
};
diff --git a/src/core/hle/service/pctl/pctl.cpp b/src/core/hle/service/pctl/pctl.cpp
index 16dd34f90..e4d155c86 100644
--- a/src/core/hle/service/pctl/pctl.cpp
+++ b/src/core/hle/service/pctl/pctl.cpp
@@ -6,8 +6,9 @@
namespace Service::PCTL {
-PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name)
- : Interface{system_, std::move(module_), name} {
+PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
+ Capability capability)
+ : Interface{system_, std::move(module_), name, capability} {
static const FunctionInfo functions[] = {
{0, &PCTL::CreateService, "CreateService"},
{1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"},
diff --git a/src/core/hle/service/pctl/pctl.h b/src/core/hle/service/pctl/pctl.h
index 275d23007..fd0a1e486 100644
--- a/src/core/hle/service/pctl/pctl.h
+++ b/src/core/hle/service/pctl/pctl.h
@@ -14,7 +14,8 @@ namespace Service::PCTL {
class PCTL final : public Module::Interface {
public:
- explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name);
+ explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
+ Capability capability);
~PCTL() override;
};
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 1da56bc27..41a502d8d 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -6,6 +6,7 @@
#include <fmt/format.h>
#include "common/assert.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/ipc.h"
@@ -146,6 +147,11 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
system.GetReporter().SaveUnimplementedFunctionReport(ctx, ctx.GetCommand(), function_name,
service_name);
UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf));
+ if (Settings::values.use_auto_stub) {
+ LOG_WARNING(Service, "Using auto stub fallback!");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
}
void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index d953b4303..bc7dc776f 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -6,9 +6,9 @@
#include <array>
#include <chrono>
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/set/set.h"
-#include "core/settings.h"
namespace Service::Set {
namespace {
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index b58b2c8c5..5909fdd85 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -261,6 +261,10 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{155, nullptr, "SetAccountOnlineStorageSettings"},
{156, nullptr, "GetPctlReadyFlag"},
{157, nullptr, "SetPctlReadyFlag"},
+ {158, nullptr, "GetAnalogStickUserCalibrationL"},
+ {159, nullptr, "SetAnalogStickUserCalibrationL"},
+ {160, nullptr, "GetAnalogStickUserCalibrationR"},
+ {161, nullptr, "SetAnalogStickUserCalibrationR"},
{162, nullptr, "GetPtmBatteryVersion"},
{163, nullptr, "SetPtmBatteryVersion"},
{164, nullptr, "GetUsb30HostEnableFlag"},
@@ -302,6 +306,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{200, nullptr, "SetButtonConfigRegisteredSettings"},
{201, nullptr, "GetFieldTestingFlag"},
{202, nullptr, "SetFieldTestingFlag"},
+ {203, nullptr, "GetPanelCrcMode"},
+ {204, nullptr, "SetPanelCrcMode"},
};
// clang-format on
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 2b91a89d1..94608d529 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -190,10 +190,11 @@ SM::SM(std::shared_ptr<ServiceManager> service_manager_, Core::System& system_)
: ServiceFramework{system_, "sm:", 4},
service_manager{std::move(service_manager_)}, kernel{system_.Kernel()} {
static const FunctionInfo functions[] = {
- {0x00000000, &SM::Initialize, "Initialize"},
- {0x00000001, &SM::GetService, "GetService"},
- {0x00000002, &SM::RegisterService, "RegisterService"},
- {0x00000003, &SM::UnregisterService, "UnregisterService"},
+ {0, &SM::Initialize, "Initialize"},
+ {1, &SM::GetService, "GetService"},
+ {2, &SM::RegisterService, "RegisterService"},
+ {3, &SM::UnregisterService, "UnregisterService"},
+ {4, nullptr, "DetachClient"},
};
RegisterHandlers(functions);
}
diff --git a/src/core/hle/service/sockets/ethc.cpp b/src/core/hle/service/sockets/ethc.cpp
index 05681ca2d..899a64c2f 100644
--- a/src/core/hle/service/sockets/ethc.cpp
+++ b/src/core/hle/service/sockets/ethc.cpp
@@ -15,6 +15,7 @@ ETHC_C::ETHC_C(Core::System& system_) : ServiceFramework{system_, "ethc:c"} {
{3, nullptr, "GetMediaList"},
{4, nullptr, "SetMediaType"},
{5, nullptr, "GetMediaType"},
+ {6, nullptr, "Unknown6"},
};
// clang-format on
diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp
index 51c3739bb..1159debc5 100644
--- a/src/core/hle/service/sockets/nsd.cpp
+++ b/src/core/hle/service/sockets/nsd.cpp
@@ -9,6 +9,7 @@ namespace Service::Sockets {
NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
+ {5, nullptr, "GetSettingUrl"},
{10, nullptr, "GetSettingName"},
{11, nullptr, "GetEnvironmentIdentifier"},
{12, nullptr, "GetDeviceId"},
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp
index 3a6329f56..5c71f423c 100644
--- a/src/core/hle/service/sockets/sfdnsres.cpp
+++ b/src/core/hle/service/sockets/sfdnsres.cpp
@@ -9,8 +9,8 @@ namespace Service::Sockets {
SFDNSRES::SFDNSRES(Core::System& system_) : ServiceFramework{system_, "sfdnsres"} {
static const FunctionInfo functions[] = {
- {0, nullptr, "SetDnsAddressesPrivate"},
- {1, nullptr, "GetDnsAddressPrivate"},
+ {0, nullptr, "SetDnsAddressesPrivateRequest"},
+ {1, nullptr, "GetDnsAddressPrivateRequest"},
{2, nullptr, "GetHostByNameRequest"},
{3, nullptr, "GetHostByAddrRequest"},
{4, nullptr, "GetHostStringErrorRequest"},
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
index 6903dd534..b1552c3f0 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/module.cpp
@@ -9,11 +9,11 @@
#include <functional>
#include <vector>
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/spl/csrng.h"
#include "core/hle/service/spl/module.h"
#include "core/hle/service/spl/spl.h"
-#include "core/settings.h"
namespace Service::SPL {
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp
index 4e212610f..fff3f3c42 100644
--- a/src/core/hle/service/spl/spl.cpp
+++ b/src/core/hle/service/spl/spl.cpp
@@ -60,6 +60,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
{4, nullptr, "GenerateAesKey"},
{5, nullptr, "SetConfig"},
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
+ {9, nullptr, "ImportLotusKey"},
+ {10, nullptr, "DecryptLotusMessage"},
{11, nullptr, "IsDevelopment"},
{12, nullptr, "GenerateSpecificAesKey"},
{14, nullptr, "DecryptAesKey"},
@@ -123,6 +125,7 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
{14, nullptr, "DecryptAesKey"},
{15, nullptr, "CryptAesCtr"},
{16, nullptr, "ComputeCmac"},
+ {17, nullptr, "ImportEsKey"},
{18, nullptr, "UnwrapTitleKey"},
{20, nullptr, "PrepareEsCommonKey"},
{21, nullptr, "AllocateAesKeyslot"},
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h
index b78892223..a9cfe3eb0 100644
--- a/src/core/hle/service/time/clock_types.h
+++ b/src/core/hle/service/time/clock_types.h
@@ -12,6 +12,12 @@
namespace Service::Time::Clock {
+enum class TimeType : u8 {
+ UserSystemClock,
+ NetworkSystemClock,
+ LocalSystemClock,
+};
+
/// https://switchbrew.org/wiki/Glue_services#SteadyClockTimePoint
struct SteadyClockTimePoint {
s64 time_point;
@@ -84,7 +90,7 @@ struct ClockSnapshot {
SteadyClockTimePoint steady_clock_time_point;
TimeZone::LocationName location_name;
u8 is_automatic_correction_enabled;
- u8 type;
+ TimeType type;
INSERT_PADDING_BYTES_NOINIT(0x2);
static ResultCode GetCurrentTime(s64& current_time,
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 78543688f..63e0247de 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -122,14 +122,16 @@ private:
ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
Kernel::KThread* thread, Clock::SystemClockContext user_context,
- Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) {
+ Clock::SystemClockContext network_context, Clock::TimeType type,
+ Clock::ClockSnapshot& clock_snapshot) {
auto& time_manager{system.GetTimeManager()};
+ clock_snapshot.steady_clock_time_point =
+ time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system);
clock_snapshot.is_automatic_correction_enabled =
time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled();
- clock_snapshot.user_context = user_context;
- clock_snapshot.network_context = network_context;
+ clock_snapshot.type = type;
if (const ResultCode result{
time_manager.GetTimeZoneContentManager().GetTimeZoneManager().GetDeviceLocationName(
@@ -138,12 +140,11 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
return result;
}
- const auto current_time_point{
- time_manager.GetStandardSteadyClockCore().GetCurrentTimePoint(system)};
- clock_snapshot.steady_clock_time_point = current_time_point;
+ clock_snapshot.user_context = user_context;
if (const ResultCode result{Clock::ClockSnapshot::GetCurrentTime(
- clock_snapshot.user_time, current_time_point, clock_snapshot.user_context)};
+ clock_snapshot.user_time, clock_snapshot.steady_clock_time_point,
+ clock_snapshot.user_context)};
result != RESULT_SUCCESS) {
return result;
}
@@ -157,9 +158,12 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
}
clock_snapshot.user_calendar_time = userCalendarInfo.time;
- clock_snapshot.user_calendar_additional_time = userCalendarInfo.additiona_info;
+ clock_snapshot.user_calendar_additional_time = userCalendarInfo.additional_info;
+
+ clock_snapshot.network_context = network_context;
- if (Clock::ClockSnapshot::GetCurrentTime(clock_snapshot.network_time, current_time_point,
+ if (Clock::ClockSnapshot::GetCurrentTime(clock_snapshot.network_time,
+ clock_snapshot.steady_clock_time_point,
clock_snapshot.network_context) != RESULT_SUCCESS) {
clock_snapshot.network_time = 0;
}
@@ -173,8 +177,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
}
clock_snapshot.network_calendar_time = networkCalendarInfo.time;
- clock_snapshot.network_calendar_additional_time = networkCalendarInfo.additiona_info;
- clock_snapshot.type = type;
+ clock_snapshot.network_calendar_additional_time = networkCalendarInfo.additional_info;
return RESULT_SUCCESS;
}
@@ -257,9 +260,10 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERe
}
void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called");
IPC::RequestParser rp{ctx};
- const auto type{rp.PopRaw<u8>()};
+ const auto type{rp.PopEnum<Clock::TimeType>()};
+
+ LOG_DEBUG(Service_Time, "called, type={}", type);
Clock::SystemClockContext user_context{};
if (const ResultCode result{
@@ -270,6 +274,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
rb.Push(result);
return;
}
+
Clock::SystemClockContext network_context{};
if (const ResultCode result{
system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext(
@@ -295,14 +300,16 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
}
void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_Time, "called");
IPC::RequestParser rp{ctx};
- const auto type{rp.PopRaw<u8>()};
+ const auto type{rp.PopEnum<Clock::TimeType>()};
+
rp.AlignWithPadding();
const Clock::SystemClockContext user_context{rp.PopRaw<Clock::SystemClockContext>()};
const Clock::SystemClockContext network_context{rp.PopRaw<Clock::SystemClockContext>()};
+ LOG_DEBUG(Service_Time, "called, type={}", type);
+
Clock::ClockSnapshot clock_snapshot{};
if (const ResultCode result{GetClockSnapshotFromSystemClockContextInternal(
&ctx.GetThread(), user_context, network_context, type, clock_snapshot)};
@@ -321,9 +328,14 @@ void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser(
Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Time, "called");
- IPC::RequestParser rp{ctx};
- const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>();
- const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>();
+ Clock::ClockSnapshot snapshot_a;
+ Clock::ClockSnapshot snapshot_b;
+
+ const auto snapshot_a_data = ctx.ReadBuffer(0);
+ const auto snapshot_b_data = ctx.ReadBuffer(1);
+
+ std::memcpy(&snapshot_a, snapshot_a_data.data(), sizeof(Clock::ClockSnapshot));
+ std::memcpy(&snapshot_b, snapshot_b_data.data(), sizeof(Clock::ClockSnapshot));
auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset -
snapshot_a.user_context.offset)};
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 4154c7ee9..ce9c479c6 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -40,7 +40,7 @@ public:
private:
ResultCode GetClockSnapshotFromSystemClockContextInternal(
Kernel::KThread* thread, Clock::SystemClockContext user_context,
- Clock::SystemClockContext network_context, u8 type,
+ Clock::SystemClockContext network_context, Clock::TimeType type,
Clock::ClockSnapshot& cloc_snapshot);
protected:
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index 1f7309f6b..f89c5aaad 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -5,12 +5,12 @@
#include <chrono>
#include <ctime>
+#include "common/settings.h"
#include "common/time_zone.h"
#include "core/hle/service/time/ephemeral_network_system_clock_context_writer.h"
#include "core/hle/service/time/local_system_clock_context_writer.h"
#include "core/hle/service/time/network_system_clock_context_writer.h"
#include "core/hle/service/time/time_manager.h"
-#include "core/settings.h"
namespace Service::Time {
@@ -44,7 +44,11 @@ struct TimeManager::Impl final {
const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
- SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
+
+ Clock::SystemClockContext clock_context{};
+ standard_local_system_clock_core.GetClockContext(system, clock_context);
+
+ SetupStandardNetworkSystemClock(clock_context, standard_network_clock_accuracy);
SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
SetupEphemeralNetworkSystemClock();
}
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp
index 4177d0a41..3c8e71a3c 100644
--- a/src/core/hle/service/time/time_zone_content_manager.cpp
+++ b/src/core/hle/service/time/time_zone_content_manager.cpp
@@ -5,6 +5,7 @@
#include <sstream>
#include "common/logging/log.h"
+#include "common/settings.h"
#include "common/time_zone.h"
#include "core/core.h"
#include "core/file_sys/content_archive.h"
@@ -15,7 +16,6 @@
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/time/time_manager.h"
#include "core/hle/service/time/time_zone_content_manager.h"
-#include "core/settings.h"
namespace Service::Time::TimeZone {
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index bdf0439f2..3032ca193 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -818,7 +818,7 @@ static ResultCode ToCalendarTimeInternal(const TimeZoneRule& rules, s64 time,
static ResultCode ToCalendarTimeImpl(const TimeZoneRule& rules, s64 time, CalendarInfo& calendar) {
CalendarTimeInternal calendar_time{};
const ResultCode result{
- ToCalendarTimeInternal(rules, time, calendar_time, calendar.additiona_info)};
+ ToCalendarTimeInternal(rules, time, calendar_time, calendar.additional_info)};
calendar.time.year = static_cast<s16>(calendar_time.year);
// Internal impl. uses 0-indexed month
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp
index 25cecbc83..3117627cf 100644
--- a/src/core/hle/service/time/time_zone_service.cpp
+++ b/src/core/hle/service/time/time_zone_service.cpp
@@ -20,6 +20,7 @@ ITimeZoneService ::ITimeZoneService(Core::System& system_,
{3, nullptr, "LoadLocationNameList"},
{4, &ITimeZoneService::LoadTimeZoneRule, "LoadTimeZoneRule"},
{5, nullptr, "GetTimeZoneRuleVersion"},
+ {6, nullptr, "GetDeviceLocationNameAndUpdatedTime"},
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
{201, &ITimeZoneService::ToPosixTime, "ToPosixTime"},
diff --git a/src/core/hle/service/time/time_zone_types.h b/src/core/hle/service/time/time_zone_types.h
index 4a57e036d..d39103253 100644
--- a/src/core/hle/service/time/time_zone_types.h
+++ b/src/core/hle/service/time/time_zone_types.h
@@ -66,8 +66,8 @@ struct CalendarTime {
static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime is incorrect size");
struct CalendarInfo {
- CalendarTime time{};
- CalendarAdditionalInfo additiona_info{};
+ CalendarTime time;
+ CalendarAdditionalInfo additional_info;
};
static_assert(sizeof(CalendarInfo) == 0x20, "CalendarInfo is incorrect size");
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index 579de83e4..b3b230a8c 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -69,15 +69,15 @@ public:
: ServiceFramework{system_, "IClientEpSession"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Open"},
+ {0, nullptr, "ReOpen"},
{1, nullptr, "Close"},
- {2, nullptr, "Unknown2"},
- {3, nullptr, "Populate"},
+ {2, nullptr, "GetCompletionEvent"},
+ {3, nullptr, "PopulateRing"},
{4, nullptr, "PostBufferAsync"},
{5, nullptr, "GetXferReport"},
{6, nullptr, "PostBufferMultiAsync"},
- {7, nullptr, "Unknown7"},
- {8, nullptr, "Unknown8"},
+ {7, nullptr, "CreateSmmuSpace"},
+ {8, nullptr, "ShareReportRing"},
};
// clang-format on
@@ -91,7 +91,7 @@ public:
: ServiceFramework{system_, "IClientIfSession"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Unknown0"},
+ {0, nullptr, "GetStateChangeEvent"},
{1, nullptr, "SetInterface"},
{2, nullptr, "GetInterface"},
{3, nullptr, "GetAlternateInterface"},
@@ -176,15 +176,15 @@ public:
: ServiceFramework{system_, "IPdCradleSession"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "VdmUserWrite"},
- {1, nullptr, "VdmUserRead"},
- {2, nullptr, "Vdm20Init"},
- {3, nullptr, "GetFwType"},
- {4, nullptr, "GetFwRevision"},
- {5, nullptr, "GetManufacturerId"},
- {6, nullptr, "GetDeviceId"},
- {7, nullptr, "Unknown7"},
- {8, nullptr, "Unknown8"},
+ {0, nullptr, "SetCradleVdo"},
+ {1, nullptr, "GetCradleVdo"},
+ {2, nullptr, "ResetCradleUsbHub"},
+ {3, nullptr, "GetHostPdcFirmwareType"},
+ {4, nullptr, "GetHostPdcFirmwareRevision"},
+ {5, nullptr, "GetHostPdcManufactureId"},
+ {6, nullptr, "GetHostPdcDeviceId"},
+ {7, nullptr, "AwakeCradle"},
+ {8, nullptr, "SleepCradle"},
};
// clang-format on
@@ -219,12 +219,12 @@ public:
explicit USB_PM(Core::System& system_) : ServiceFramework{system_, "usb:pm"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "Unknown0"},
- {1, nullptr, "Unknown1"},
- {2, nullptr, "Unknown2"},
- {3, nullptr, "Unknown3"},
- {4, nullptr, "Unknown4"},
- {5, nullptr, "Unknown5"},
+ {0, nullptr, "GetPowerEvent"},
+ {1, nullptr, "GetPowerState"},
+ {2, nullptr, "GetDataEvent"},
+ {3, nullptr, "GetDataRole"},
+ {4, nullptr, "SetDiagData"},
+ {5, nullptr, "GetDiagData"},
};
// clang-format on
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 7423287ea..348360b51 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -15,6 +15,7 @@
#include "common/common_funcs.h"
#include "common/logging/log.h"
#include "common/math_util.h"
+#include "common/settings.h"
#include "common/swap.h"
#include "core/core_timing.h"
#include "core/hle/ipc_helpers.h"
@@ -30,7 +31,6 @@
#include "core/hle/service/vi/vi_m.h"
#include "core/hle/service/vi/vi_s.h"
#include "core/hle/service/vi/vi_u.h"
-#include "core/settings.h"
namespace Service::VI {
@@ -695,6 +695,7 @@ public:
{2205, &ISystemDisplayService::SetLayerZ, "SetLayerZ"},
{2207, &ISystemDisplayService::SetLayerVisibility, "SetLayerVisibility"},
{2209, nullptr, "SetLayerAlpha"},
+ {2210, nullptr, "SetLayerPositionAndSize"},
{2312, nullptr, "CreateStrayLayer"},
{2400, nullptr, "OpenIndirectLayer"},
{2401, nullptr, "CloseIndirectLayer"},
@@ -718,6 +719,7 @@ public:
{3215, nullptr, "SetDisplayGamma"},
{3216, nullptr, "GetDisplayCmuLuma"},
{3217, nullptr, "SetDisplayCmuLuma"},
+ {3218, nullptr, "SetDisplayCrcMode"},
{6013, nullptr, "GetLayerPresentationSubmissionTimestamps"},
{8225, nullptr, "GetSharedBufferMemoryHandleId"},
{8250, nullptr, "OpenSharedLayer"},
@@ -729,6 +731,7 @@ public:
{8256, nullptr, "GetSharedFrameBufferAcquirableEvent"},
{8257, nullptr, "FillSharedFrameBufferColor"},
{8258, nullptr, "CancelSharedFrameBuffer"},
+ {9000, nullptr, "GetDp2hdmiController"},
};
RegisterHandlers(functions);
}
@@ -808,10 +811,15 @@ public:
{2402, nullptr, "GetDisplayHotplugState"},
{2501, nullptr, "GetCompositorErrorInfo"},
{2601, nullptr, "GetDisplayErrorEvent"},
+ {2701, nullptr, "GetDisplayFatalErrorEvent"},
{4201, nullptr, "SetDisplayAlpha"},
{4203, nullptr, "SetDisplayLayerStack"},
{4205, nullptr, "SetDisplayPowerState"},
{4206, nullptr, "SetDefaultDisplay"},
+ {4207, nullptr, "ResetDisplayPanel"},
+ {4208, nullptr, "SetDisplayFatalErrorEnabled"},
+ {4209, nullptr, "IsDisplayPanelOn"},
+ {4300, nullptr, "GetInternalPanelId"},
{6000, &IManagerDisplayService::AddToLayerStack, "AddToLayerStack"},
{6001, nullptr, "RemoveFromLayerStack"},
{6002, &IManagerDisplayService::SetLayerVisibility, "SetLayerVisibility"},
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp
index ddbf04069..44957e01d 100644
--- a/src/core/hle/service/wlan/wlan.cpp
+++ b/src/core/hle/service/wlan/wlan.cpp
@@ -46,6 +46,13 @@ public:
{28, nullptr, "Unknown28"},
{29, nullptr, "Unknown29"},
{30, nullptr, "Unknown30"},
+ {31, nullptr, "Unknown31"},
+ {32, nullptr, "Unknown32"},
+ {33, nullptr, "Unknown33"},
+ {34, nullptr, "Unknown34"},
+ {35, nullptr, "Unknown35"},
+ {36, nullptr, "Unknown36"},
+ {37, nullptr, "Unknown37"},
};
// clang-format on