aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorFrozenAra <[email protected]>2023-11-01 01:09:33 +0100
committerFrozenAra <[email protected]>2023-11-19 18:38:58 +0100
commitcb004d1ba1bde740ba10418ac3f3cfd2db8ffac7 (patch)
treedfcff7952ed84cea825e1144284d82505ec09731 /src
parent4c16a1a26f3d35c5d3a57a6b1e988d3c3e07a932 (diff)
downloadyuzu-mainline-cb004d1ba1bde740ba10418ac3f3cfd2db8ffac7.tar.gz
yuzu-mainline-cb004d1ba1bde740ba10418ac3f3cfd2db8ffac7.zip
Implemented qlaunch version of the controller applet
Diffstat (limited to 'src')
-rw-r--r--src/core/hid/hid_types.h7
-rw-r--r--src/core/hle/service/am/am.cpp91
-rw-r--r--src/core/hle/service/am/am.h3
-rw-r--r--src/core/hle/service/am/applets/applet_controller.h2
-rw-r--r--src/core/hle/service/btm/btm.cpp56
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp16
-rw-r--r--src/core/hle/service/hid/controllers/npad.h72
-rw-r--r--src/core/hle/service/hid/hid_server.cpp4
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp293
-rw-r--r--src/core/hle/service/hid/hid_system_server.h23
-rw-r--r--src/core/hle/service/ldn/ldn.cpp10
-rw-r--r--src/core/hle/service/set/set_sys.cpp30
-rw-r--r--src/core/hle/service/set/set_sys.h12
-rw-r--r--src/yuzu/main.cpp41
-rw-r--r--src/yuzu/main.h1
-rw-r--r--src/yuzu/main.ui22
16 files changed, 594 insertions, 89 deletions
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 9d48cd90e..70fcc6b69 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -218,6 +218,13 @@ enum class NpadIdType : u32 {
Invalid = 0xFFFFFFFF,
};
+enum class NpadInterfaceType : u8 {
+ Bluetooth = 1,
+ Rail = 2,
+ Usb = 3,
+ Embedded = 4,
+};
+
// This is nn::hid::NpadStyleIndex
enum class NpadStyleIndex : u8 {
None = 0,
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index cc643ea09..a266d7c21 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -13,6 +13,7 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/savedata_factory.h"
+#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
@@ -21,6 +22,7 @@
#include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/am/applets/applet_cabinet.h"
+#include "core/hle/service/am/applets/applet_controller.h"
#include "core/hle/service/am/applets/applet_mii_edit_types.h"
#include "core/hle/service/am/applets/applet_profile_select.h"
#include "core/hle/service/am/applets/applet_software_keyboard_types.h"
@@ -35,6 +37,7 @@
#include "core/hle/service/caps/caps_su.h"
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/filesystem/filesystem.h"
+#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
@@ -73,7 +76,7 @@ IWindowController::IWindowController(Core::System& system_)
static const FunctionInfo functions[] = {
{0, nullptr, "CreateWindow"},
{1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
- {2, nullptr, "GetAppletResourceUserIdOfCallerApplet"},
+ {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"},
{10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
{11, nullptr, "ReleaseForegroundRights"},
{12, nullptr, "RejectToChangeIntoBackground"},
@@ -97,6 +100,16 @@ void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) {
rb.Push<u64>(process_id);
}
+void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) {
+ const u64 process_id = 0;
+
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u64>(process_id);
+}
+
void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
@@ -1565,7 +1578,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
{6, nullptr, "GetPopInteractiveInDataEvent"},
{10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
{11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
- {12, nullptr, "GetMainAppletIdentityInfo"},
+ {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
{13, nullptr, "CanUseApplicationCore"},
{14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
{15, nullptr, "GetMainAppletApplicationControlProperty"},
@@ -1609,6 +1622,9 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
case Applets::AppletId::SoftwareKeyboard:
PushInShowSoftwareKeyboard();
break;
+ case Applets::AppletId::Controller:
+ PushInShowController();
+ break;
default:
break;
}
@@ -1666,13 +1682,33 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
rb.PushRaw(applet_info);
}
-void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
+void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) {
struct AppletIdentityInfo {
Applets::AppletId applet_id;
INSERT_PADDING_BYTES(0x4);
u64 application_id;
};
+ static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
+
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ const AppletIdentityInfo applet_info{
+ .applet_id = Applets::AppletId::QLaunch,
+ .application_id = 0x0100000000001000ull,
+ };
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(applet_info);
+}
+void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
+ struct AppletIdentityInfo {
+ Applets::AppletId applet_id;
+ INSERT_PADDING_BYTES(0x4);
+ u64 application_id;
+ };
+ static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
LOG_WARNING(Service_AM, "(STUBBED) called");
const AppletIdentityInfo applet_info{
@@ -1737,6 +1773,55 @@ void ILibraryAppletSelfAccessor::PushInShowAlbum() {
queue_data.emplace_back(std::move(settings_data));
}
+void ILibraryAppletSelfAccessor::PushInShowController() {
+ const Applets::CommonArguments common_args = {
+ .arguments_version = Applets::CommonArgumentVersion::Version3,
+ .size = Applets::CommonArgumentSize::Version3,
+ .library_version = static_cast<u32>(Applets::ControllerAppletVersion::Version8),
+ .theme_color = Applets::ThemeColor::BasicBlack,
+ .play_startup_sound = true,
+ .system_tick = system.CoreTiming().GetClockTicks(),
+ };
+
+ Applets::ControllerSupportArgNew user_args = {
+ .header = {.player_count_min = 1,
+ .player_count_max = 4,
+ .enable_take_over_connection = true,
+ .enable_left_justify = false,
+ .enable_permit_joy_dual = true,
+ .enable_single_mode = false,
+ .enable_identification_color = false},
+ .identification_colors = {},
+ .enable_explain_text = false,
+ .explain_text = {},
+ };
+
+ Applets::ControllerSupportArgPrivate private_args = {
+ .arg_private_size = sizeof(Applets::ControllerSupportArgPrivate),
+ .arg_size = sizeof(Applets::ControllerSupportArgNew),
+ .is_home_menu = true,
+ .flag_1 = true,
+ .mode = Applets::ControllerSupportMode::ShowControllerSupport,
+ .caller = Applets::ControllerSupportCaller::
+ Application, // switchbrew: Always zero except with
+ // ShowControllerFirmwareUpdateForSystem/ShowControllerKeyRemappingForSystem,
+ // which sets this to the input param
+ .style_set = Core::HID::NpadStyleSet::None,
+ .joy_hold_type = 0,
+ };
+ std::vector<u8> common_args_data(sizeof(common_args));
+ std::vector<u8> private_args_data(sizeof(private_args));
+ std::vector<u8> user_args_data(sizeof(user_args));
+
+ std::memcpy(common_args_data.data(), &common_args, sizeof(common_args));
+ std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
+ std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
+
+ queue_data.emplace_back(std::move(common_args_data));
+ queue_data.emplace_back(std::move(private_args_data));
+ queue_data.emplace_back(std::move(user_args_data));
+}
+
void ILibraryAppletSelfAccessor::PushInShowCabinetData() {
const Applets::CommonArguments arguments{
.arguments_version = Applets::CommonArgumentVersion::Version3,
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 8f8cb8a9e..905a71b9f 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -87,6 +87,7 @@ public:
private:
void GetAppletResourceUserId(HLERequestContext& ctx);
+ void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx);
void AcquireForegroundRights(HLERequestContext& ctx);
};
@@ -345,6 +346,7 @@ private:
void PopInData(HLERequestContext& ctx);
void PushOutData(HLERequestContext& ctx);
void GetLibraryAppletInfo(HLERequestContext& ctx);
+ void GetMainAppletIdentityInfo(HLERequestContext& ctx);
void ExitProcessAndReturn(HLERequestContext& ctx);
void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
void GetDesirableKeyboardLayout(HLERequestContext& ctx);
@@ -355,6 +357,7 @@ private:
void PushInShowCabinetData();
void PushInShowMiiEditData();
void PushInShowSoftwareKeyboard();
+ void PushInShowController();
std::deque<std::vector<u8>> queue_data;
};
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h
index f6c64f633..9f839f3d7 100644
--- a/src/core/hle/service/am/applets/applet_controller.h
+++ b/src/core/hle/service/am/applets/applet_controller.h
@@ -56,7 +56,7 @@ enum class ControllerSupportResult : u32 {
struct ControllerSupportArgPrivate {
u32 arg_private_size{};
u32 arg_size{};
- bool flag_0{};
+ bool is_home_menu{};
bool flag_1{};
ControllerSupportMode mode{};
ControllerSupportCaller caller{};
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 8069f75b7..c65e32489 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -127,7 +127,7 @@ public:
private:
void GetCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_BTM, "called");
+ LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
@@ -263,13 +263,13 @@ public:
explicit IBtmSystemCore(Core::System& system_) : ServiceFramework{system_, "IBtmSystemCore"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "StartGamepadPairing"},
- {1, nullptr, "CancelGamepadPairing"},
+ {0, &IBtmSystemCore::StartGamepadPairing, "StartGamepadPairing"},
+ {1, &IBtmSystemCore::CancelGamepadPairing, "CancelGamepadPairing"},
{2, nullptr, "ClearGamepadPairingDatabase"},
{3, nullptr, "GetPairedGamepadCount"},
{4, nullptr, "EnableRadio"},
{5, nullptr, "DisableRadio"},
- {6, nullptr, "GetRadioOnOff"},
+ {6, &IBtmSystemCore::IsRadioEnabled, "IsRadioEnabled"},
{7, nullptr, "AcquireRadioEvent"},
{8, nullptr, "AcquireGamepadPairingEvent"},
{9, nullptr, "IsGamepadPairingStarted"},
@@ -280,18 +280,58 @@ public:
{14, nullptr, "AcquireAudioDeviceConnectionEvent"},
{15, nullptr, "ConnectAudioDevice"},
{16, nullptr, "IsConnectingAudioDevice"},
- {17, nullptr, "GetConnectedAudioDevices"},
+ {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
{18, nullptr, "DisconnectAudioDevice"},
{19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
{20, nullptr, "GetPairedAudioDevices"},
{21, nullptr, "RemoveAudioDevicePairing"},
- {22, nullptr, "RequestAudioDeviceConnectionRejection"},
- {23, nullptr, "CancelAudioDeviceConnectionRejection"}
+ {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
+ {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
};
// clang-format on
RegisterHandlers(functions);
}
+
+private:
+ void IsRadioEnabled(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_BTM, "(STUBBED) called"); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(true);
+ }
+
+ void StartGamepadPairing(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void CancelGamepadPairing(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void CancelAudioDeviceConnectionRejection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void GetConnectedAudioDevices(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push<u32>(0);
+ }
+
+ void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
+ LOG_WARNING(Service_BTM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
};
class BTM_SYS final : public ServiceFramework<BTM_SYS> {
@@ -308,7 +348,7 @@ public:
private:
void GetCore(HLERequestContext& ctx) {
- LOG_DEBUG(Service_BTM, "called");
+ LOG_WARNING(Service_BTM, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index d46bf917e..127af2b82 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -344,6 +344,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
Common::Input::PollingMode::Active);
}
+
SignalStyleSetChangedEvent(npad_id);
WriteEmptyEntry(controller.shared_memory);
hid_core.SetLastActiveController(npad_id);
@@ -1726,4 +1727,19 @@ const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
}
}
+Controller_NPad::AppletDetailedUiType Controller_NPad::GetAppletDetailedUiType(
+ Core::HID::NpadIdType npad_id) {
+
+ auto controller = GetControllerFromNpadIdType(npad_id);
+ auto shared_memory = controller.shared_memory;
+ Service::HID::Controller_NPad::AppletFooterUiType applet_footer_type =
+ shared_memory->applet_footer_type;
+
+ Controller_NPad::AppletDetailedUiType detailed_ui_type{
+ .ui_variant = 0,
+ .footer = applet_footer_type,
+ };
+ return detailed_ui_type;
+}
+
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index e23b4986c..cd93abdd1 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -78,6 +78,46 @@ public:
MaxActivationMode = 3,
};
+ // This is nn::hid::system::AppletFooterUiAttributesSet
+ struct AppletFooterUiAttributes {
+ INSERT_PADDING_BYTES(0x4);
+ };
+
+ // This is nn::hid::system::AppletFooterUiType
+ enum class AppletFooterUiType : u8 {
+ None = 0,
+ HandheldNone = 1,
+ HandheldJoyConLeftOnly = 2,
+ HandheldJoyConRightOnly = 3,
+ HandheldJoyConLeftJoyConRight = 4,
+ JoyDual = 5,
+ JoyDualLeftOnly = 6,
+ JoyDualRightOnly = 7,
+ JoyLeftHorizontal = 8,
+ JoyLeftVertical = 9,
+ JoyRightHorizontal = 10,
+ JoyRightVertical = 11,
+ SwitchProController = 12,
+ CompatibleProController = 13,
+ CompatibleJoyCon = 14,
+ LarkHvc1 = 15,
+ LarkHvc2 = 16,
+ LarkNesLeft = 17,
+ LarkNesRight = 18,
+ Lucia = 19,
+ Verification = 20,
+ Lagon = 21,
+ };
+
+ using AppletFooterUiVariant = u8;
+
+ // This is "nn::hid::system::AppletDetailedUiType".
+ struct AppletDetailedUiType {
+ AppletFooterUiVariant ui_variant;
+ INSERT_PADDING_BYTES(0x2);
+ AppletFooterUiType footer;
+ };
+ static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
// This is nn::hid::NpadCommunicationMode
enum class NpadCommunicationMode : u64 {
Mode_5ms = 0,
@@ -203,6 +243,7 @@ public:
static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
static Result VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle);
+ AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
private:
static constexpr std::size_t NPAD_COUNT = 10;
@@ -360,37 +401,6 @@ private:
static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
"NfcXcdDeviceHandleStateImpl is an invalid size");
- // This is nn::hid::system::AppletFooterUiAttributesSet
- struct AppletFooterUiAttributes {
- INSERT_PADDING_BYTES(0x4);
- };
-
- // This is nn::hid::system::AppletFooterUiType
- enum class AppletFooterUiType : u8 {
- None = 0,
- HandheldNone = 1,
- HandheldJoyConLeftOnly = 2,
- HandheldJoyConRightOnly = 3,
- HandheldJoyConLeftJoyConRight = 4,
- JoyDual = 5,
- JoyDualLeftOnly = 6,
- JoyDualRightOnly = 7,
- JoyLeftHorizontal = 8,
- JoyLeftVertical = 9,
- JoyRightHorizontal = 10,
- JoyRightVertical = 11,
- SwitchProController = 12,
- CompatibleProController = 13,
- CompatibleJoyCon = 14,
- LarkHvc1 = 15,
- LarkHvc2 = 16,
- LarkNesLeft = 17,
- LarkNesRight = 18,
- Lucia = 19,
- Verification = 20,
- Lagon = 21,
- };
-
// This is nn::hid::NpadLarkType
enum class NpadLarkType : u32 {
Invalid,
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 0be6a7186..56f26a14a 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -1222,8 +1222,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
controller.SetNpadMode(new_npad_id, parameters.npad_id, {},
Controller_NPad::NpadJoyAssignmentMode::Dual);
- LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
- parameters.applet_resource_user_id);
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id); // Spams a lot when controller applet is open
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 83cfadada..6f1902ee5 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -36,24 +36,24 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{301, nullptr, "ActivateNpadSystem"},
{303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
- {304, nullptr, "EnableAssigningSingleOnSlSrPress"},
- {305, nullptr, "DisableAssigningSingleOnSlSrPress"},
+ {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"},
+ {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"},
{306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"},
{307, nullptr, "GetNpadSystemExtStyle"},
- {308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
- {309, nullptr, "GetNpadFullKeyGripColor"},
- {310, nullptr, "GetMaskedSupportedNpadStyleSet"},
+ {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"},
+ {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"},
+ {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"},
{311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
- {312, nullptr, "SetSupportedNpadStyleSetAll"},
+ {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"},
{313, nullptr, "GetNpadCaptureButtonAssignment"},
{314, nullptr, "GetAppletFooterUiType"},
- {315, nullptr, "GetAppletDetailedUiType"},
- {316, nullptr, "GetNpadInterfaceType"},
- {317, nullptr, "GetNpadLeftRightInterfaceType"},
- {318, nullptr, "HasBattery"},
- {319, nullptr, "HasLeftRightBattery"},
+ {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"},
+ {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"},
+ {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"},
+ {318, &IHidSystemServer::HasBattery, "HasBattery"},
+ {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"},
{321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
- {322, nullptr, "GetIrSensorState"},
+ {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"},
{323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{324, nullptr, "GetUniquePadButtonSet"},
{325, nullptr, "GetUniquePadColor"},
@@ -85,15 +85,15 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{541, nullptr, "GetPlayReportControllerUsages"},
{542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
{543, nullptr, "GetRegisteredDevicesOld"},
- {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
+ {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"},
{545, nullptr, "SendConnectionTrigger"},
- {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
+ {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"},
{547, nullptr, "GetAllowedBluetoothLinksCount"},
- {548, nullptr, "GetRegisteredDevices"},
+ {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"},
{549, nullptr, "GetConnectableRegisteredDevices"},
{700, nullptr, "ActivateUniquePad"},
- {702, nullptr, "AcquireUniquePadConnectionEventHandle"},
- {703, nullptr, "GetUniquePadIds"},
+ {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"},
+ {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"},
{751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
{800, nullptr, "ListSixAxisSensorHandles"},
{801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
@@ -123,10 +123,10 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
{851, nullptr, "EnableUsbFullKeyController"},
{852, nullptr, "IsUsbConnected"},
- {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"},
+ {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"},
{900, nullptr, "ActivateInputDetector"},
{901, nullptr, "NotifyInputDetector"},
- {1000, nullptr, "InitializeFirmwareUpdate"},
+ {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"},
{1001, nullptr, "GetFirmwareVersion"},
{1002, nullptr, "GetAvailableFirmwareVersion"},
{1003, nullptr, "IsFirmwareUpdateAvailable"},
@@ -149,6 +149,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
{1133, nullptr, "StartUsbFirmwareUpdate"},
{1134, nullptr, "GetUsbFirmwareUpdateState"},
+ {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"},
{1150, nullptr, "SetTouchScreenMagnification"},
{1151, nullptr, "GetTouchScreenFirmwareVersion"},
{1152, nullptr, "SetTouchScreenDefaultConfiguration"},
@@ -220,11 +221,20 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
RegisterHandlers(functions);
- joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
+ joy_detach_event = service_context.CreateEvent("IHidSystemServer::JoyDetachEvent");
+ acquire_device_registered_event =
+ service_context.CreateEvent("IHidSystemServer::AcquireDeviceRegisteredEvent");
+ acquire_connection_trigger_timeout_event =
+ service_context.CreateEvent("IHidSystemServer::AcquireConnectionTriggerTimeoutEvent");
+ unique_pad_connection_event =
+ service_context.CreateEvent("IHidSystemServer::AcquireUniquePadConnectionEventHandle");
}
IHidSystemServer::~IHidSystemServer() {
service_context.CloseEvent(joy_detach_event);
+ service_context.CloseEvent(acquire_device_registered_event);
+ service_context.CloseEvent(acquire_connection_trigger_timeout_event);
+ service_context.CloseEvent(unique_pad_connection_event);
};
void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
@@ -238,29 +248,241 @@ void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "(STUBBED) called");
+ LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.PushEnum(system.HIDCore().GetLastActiveController());
}
+void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "called");
+
+ GetResourceManager()
+ ->GetController<Controller_NPad>(HidController::NPad)
+ .ApplyNpadSystemCommonPolicy();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ Core::HID::NpadColor left_color{};
+ Core::HID::NpadColor right_color{};
+ // TODO: Get colors from Npad
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(left_color);
+ rb.PushRaw(right_color);
+}
+
+void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_INFO(Service_HID, "(STUBBED) called");
+
+ Core::HID::NpadStyleSet supported_styleset =
+ GetResourceManager()
+ ->GetController<Controller_NPad>(HidController::NPad)
+ .GetSupportedStyleSet()
+ .raw;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(supported_styleset);
+}
+
+void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_INFO(Service_HID, "(STUBBED) called");
+
+ Core::HID::NpadStyleSet supported_styleset =
+ GetResourceManager()
+ ->GetController<Controller_NPad>(HidController::NPad)
+ .GetSupportedStyleSet()
+ .raw;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(supported_styleset);
+}
+
+void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ const Service::HID::Controller_NPad::AppletDetailedUiType detailed_ui_type =
+ GetResourceManager()
+ ->GetController<Controller_NPad>(HidController::NPad)
+ .GetAppletDetailedUiType(npad_id_type);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(detailed_ui_type);
+}
+
+void IHidSystemServer::GetNpadInterfaceType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
+}
+
+void IHidSystemServer::GetNpadLeftRightInterfaceType(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
+ rb.PushEnum(Core::HID::NpadInterfaceType::Bluetooth);
+}
+
+void IHidSystemServer::HasBattery(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(false);
+}
+
+void IHidSystemServer::HasLeftRightBattery(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
+
+ struct LeftRightBattery {
+ bool left;
+ bool right;
+ };
+
+ LeftRightBattery left_right_battery{
+ .left = false,
+ .right = false,
+ };
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(left_right_battery);
+}
+
void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type);
+ LOG_DEBUG(Service_HID, "(STUBBED) called, npad_id_type={}",
+ npad_id_type); // Spams a lot when controller applet is running
const std::vector<Core::HID::UniquePadId> unique_pads{};
- ctx.WriteBuffer(unique_pads);
+ if (!unique_pads.empty()) {
+ ctx.WriteBuffer(unique_pads);
+ }
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(static_cast<u32>(unique_pads.size()));
}
+void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
+ LOG_INFO(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
+}
+
+void IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx) {
+ LOG_INFO(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(acquire_device_registered_event->GetReadableEvent());
+}
+
+void IHidSystemServer::GetRegisteredDevices(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ struct RegisterData {
+ std::array<u8, 0x68> data;
+ };
+ static_assert(sizeof(RegisterData) == 0x68, "RegisterData is an invalid size");
+ std::vector<RegisterData> registered_devices{};
+
+ if (!registered_devices.empty()) {
+ ctx.WriteBuffer(registered_devices);
+ }
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u64>(registered_devices.size());
+}
+
+void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.PushCopyObjects(unique_pad_connection_event->GetReadableEvent());
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u64>(0);
+}
+
void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
LOG_INFO(Service_AM, "called");
@@ -279,6 +501,31 @@ void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
rb.Push(is_enabled);
}
+void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) {
+ const bool button_pressed = false;
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}",
+ button_pressed); // Spams a lot when controller applet is open
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(button_pressed);
+}
+
+void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
index d4b3910fa..822d5e5b9 100644
--- a/src/core/hle/service/hid/hid_system_server.h
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -24,15 +24,38 @@ public:
private:
void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx);
+ void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
+ void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
void GetLastActiveNpad(HLERequestContext& ctx);
+ void ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx);
+ void GetNpadFullKeyGripColor(HLERequestContext& ctx);
+ void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx);
+ void SetSupportedNpadStyleSetAll(HLERequestContext& ctx);
+ void GetAppletDetailedUiType(HLERequestContext& ctx);
+ void GetNpadInterfaceType(HLERequestContext& ctx);
+ void GetNpadLeftRightInterfaceType(HLERequestContext& ctx);
+ void HasBattery(HLERequestContext& ctx);
+ void HasLeftRightBattery(HLERequestContext& ctx);
void GetUniquePadsFromNpad(HLERequestContext& ctx);
+ void GetIrSensorState(HLERequestContext& ctx);
+ void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
+ void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
+ void GetRegisteredDevices(HLERequestContext& ctx);
+ void AcquireUniquePadConnectionEventHandle(HLERequestContext& ctx);
+ void GetUniquePadIds(HLERequestContext& ctx);
void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx);
void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
+ void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
+ void InitializeFirmwareUpdate(HLERequestContext& ctx);
+ void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> GetResourceManager();
+ Kernel::KEvent* acquire_connection_trigger_timeout_event;
+ Kernel::KEvent* acquire_device_registered_event;
Kernel::KEvent* joy_detach_event;
+ Kernel::KEvent* unique_pad_connection_event;
KernelHelpers::ServiceContext service_context;
std::shared_ptr<ResourceManager> resource_manager;
};
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index 7927f8264..961f89a14 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -115,12 +115,20 @@ public:
{400, nullptr, "InitializeSystem"},
{401, nullptr, "FinalizeSystem"},
{402, nullptr, "SetOperationMode"},
- {403, nullptr, "InitializeSystem2"},
+ {403, &ISystemLocalCommunicationService::InitializeSystem2, "InitializeSystem2"},
};
// clang-format on
RegisterHandlers(functions);
}
+
+private:
+ void InitializeSystem2(HLERequestContext& ctx) {
+ LOG_WARNING(Service_LDN, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
};
class IUserLocalCommunicationService final
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index ec3af80af..19c667b42 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -431,8 +431,7 @@ void SET_SYS::GetAutoUpdateEnableFlag(HLERequestContext& ctx) {
void SET_SYS::GetBatteryPercentageFlag(HLERequestContext& ctx) {
u8 battery_percentage_flag{1};
- LOG_WARNING(Service_SET, "(STUBBED) called, battery_percentage_flag={}",
- battery_percentage_flag);
+ LOG_DEBUG(Service_SET, "(STUBBED) called, battery_percentage_flag={}", battery_percentage_flag);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
@@ -492,6 +491,29 @@ void SET_SYS::GetChineseTraditionalInputMethod(HLERequestContext& ctx) {
rb.PushEnum(ChineseTraditionalInputMethod::Unknown0);
}
+void SET_SYS::GetHomeMenuScheme(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_SET, "(STUBBED) called");
+
+ const HomeMenuScheme default_color = {
+ .main = 0xFF323232,
+ .back = 0xFF323232,
+ .sub = 0xFFFFFFFF,
+ .bezel = 0xFFFFFFFF,
+ .extra = 0xFF000000,
+ };
+
+ IPC::ResponseBuilder rb{ctx, 7};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(default_color);
+}
+
+void SET_SYS::GetHomeMenuSchemeModel(HLERequestContext& ctx) {
+ LOG_WARNING(Service_SET, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(0);
+}
void SET_SYS::GetFieldTestingFlag(HLERequestContext& ctx) {
LOG_WARNING(Service_SET, "(STUBBED) called");
@@ -674,7 +696,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{171, nullptr, "SetChineseTraditionalInputMethod"},
{172, nullptr, "GetPtmCycleCountReliability"},
{173, nullptr, "SetPtmCycleCountReliability"},
- {174, nullptr, "GetHomeMenuScheme"},
+ {174, &SET_SYS::GetHomeMenuScheme, "GetHomeMenuScheme"},
{175, nullptr, "GetThemeSettings"},
{176, nullptr, "SetThemeSettings"},
{177, nullptr, "GetThemeKey"},
@@ -685,7 +707,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{182, nullptr, "SetT"},
{183, nullptr, "GetPlatformRegion"},
{184, nullptr, "SetPlatformRegion"},
- {185, nullptr, "GetHomeMenuSchemeModel"},
+ {185, &SET_SYS::GetHomeMenuSchemeModel, "GetHomeMenuSchemeModel"},
{186, nullptr, "GetMemoryUsageRateFlag"},
{187, nullptr, "GetTouchScreenMode"},
{188, nullptr, "SetTouchScreenMode"},
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index c7dba2a9e..93023c6dd 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -269,6 +269,16 @@ private:
};
static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size");
+ /// This is nn::settings::system::HomeMenuScheme
+ struct HomeMenuScheme {
+ u32 main;
+ u32 back;
+ u32 sub;
+ u32 bezel;
+ u32 extra;
+ };
+ static_assert(sizeof(HomeMenuScheme) == 0x14, "HomeMenuScheme is incorrect size");
+
void SetLanguageCode(HLERequestContext& ctx);
void GetFirmwareVersion(HLERequestContext& ctx);
void GetFirmwareVersion2(HLERequestContext& ctx);
@@ -305,6 +315,8 @@ private:
void GetKeyboardLayout(HLERequestContext& ctx);
void GetChineseTraditionalInputMethod(HLERequestContext& ctx);
void GetFieldTestingFlag(HLERequestContext& ctx);
+ void GetHomeMenuScheme(HLERequestContext& ctx);
+ void GetHomeMenuSchemeModel(HLERequestContext& ctx);
AccountSettings account_settings{
.flags = {},
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f077d7f9c..b0e995c52 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1574,6 +1574,7 @@ void GMainWindow::ConnectMenuEvents() {
connect_menu(ui->action_Load_Cabinet_Formatter,
[this]() { OnCabinet(Service::NFP::CabinetMode::StartFormatter); });
connect_menu(ui->action_Load_Mii_Edit, &GMainWindow::OnMiiEdit);
+ connect_menu(ui->action_Open_Controller_Menu, &GMainWindow::OnOpenControllerMenu);
connect_menu(ui->action_Capture_Screenshot, &GMainWindow::OnCaptureScreenshot);
// TAS
@@ -1601,14 +1602,13 @@ void GMainWindow::UpdateMenuState() {
ui->action_Pause,
};
- const std::array applet_actions{
- ui->action_Load_Album,
- ui->action_Load_Cabinet_Nickname_Owner,
- ui->action_Load_Cabinet_Eraser,
- ui->action_Load_Cabinet_Restorer,
- ui->action_Load_Cabinet_Formatter,
- ui->action_Load_Mii_Edit,
- };
+ const std::array applet_actions{ui->action_Load_Album,
+ ui->action_Load_Cabinet_Nickname_Owner,
+ ui->action_Load_Cabinet_Eraser,
+ ui->action_Load_Cabinet_Restorer,
+ ui->action_Load_Cabinet_Formatter,
+ ui->action_Load_Mii_Edit,
+ ui->action_Open_Controller_Menu};
for (QAction* action : running_actions) {
action->setEnabled(emulation_running);
@@ -4346,6 +4346,31 @@ void GMainWindow::OnMiiEdit() {
BootGame(filename, MiiEditId);
}
+void GMainWindow::OnOpenControllerMenu() {
+ constexpr u64 ControllerAppletId =
+ static_cast<u64>(Service::AM::Applets::AppletProgramId::Controller);
+ auto bis_system = system->GetFileSystemController().GetSystemNANDContents();
+ if (!bis_system) {
+ QMessageBox::warning(this, tr("No firmware available"),
+ tr("Please install the firmware to use the Controller Menu."));
+ return;
+ }
+
+ auto controller_applet_nca =
+ bis_system->GetEntry(ControllerAppletId, FileSys::ContentRecordType::Program);
+ if (!controller_applet_nca) {
+ QMessageBox::warning(this, tr("Controller Applet"),
+ tr("Controller Menu is not available. Please reinstall firmware."));
+ return;
+ }
+
+ system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Controller);
+
+ const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath()));
+ UISettings::values.roms_path = QFileInfo(filename).path();
+ BootGame(filename, ControllerAppletId);
+}
+
void GMainWindow::OnCaptureScreenshot() {
if (emu_thread == nullptr || !emu_thread->IsRunning()) {
return;
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index f9c6efe4f..19740cc52 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -402,6 +402,7 @@ private slots:
void OnAlbum();
void OnCabinet(Service::NFP::CabinetMode mode);
void OnMiiEdit();
+ void OnOpenControllerMenu();
void OnCaptureScreenshot();
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
void OnLanguageChanged(const QString& locale);
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index 88684ffb5..e53f9951e 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -25,7 +25,7 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
- <property name="margin">
+ <property name="margin" stdset="0">
<number>0</number>
</property>
</layout>
@@ -36,7 +36,7 @@
<x>0</x>
<y>0</y>
<width>1280</width>
- <height>26</height>
+ <height>21</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@@ -162,6 +162,7 @@
<addaction name="menu_cabinet_applet"/>
<addaction name="action_Load_Album"/>
<addaction name="action_Load_Mii_Edit"/>
+ <addaction name="action_Open_Controller_Menu"/>
<addaction name="separator"/>
<addaction name="action_Capture_Screenshot"/>
<addaction name="menuTAS"/>
@@ -382,9 +383,9 @@
</property>
</action>
<action name="action_Load_Album">
- <property name="text">
- <string>Open &amp;Album</string>
- </property>
+ <property name="text">
+ <string>Open &amp;Album</string>
+ </property>
</action>
<action name="action_Load_Cabinet_Nickname_Owner">
<property name="text">
@@ -407,9 +408,9 @@
</property>
</action>
<action name="action_Load_Mii_Edit">
- <property name="text">
- <string>Open &amp;Mii Editor</string>
- </property>
+ <property name="text">
+ <string>Open &amp;Mii Editor</string>
+ </property>
</action>
<action name="action_Configure_Tas">
<property name="text">
@@ -454,6 +455,11 @@
<string>R&amp;ecord</string>
</property>
</action>
+ <action name="action_Open_Controller_Menu">
+ <property name="text">
+ <string>Open &amp;Controller Menu</string>
+ </property>
+ </action>
</widget>
<resources>
<include location="yuzu.qrc"/>