summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt9
-rw-r--r--src/core/hid/emulated_controller.cpp17
-rw-r--r--src/core/hid/hid_core.cpp5
-rw-r--r--src/core/hid/hid_types.h80
-rw-r--r--src/core/hid/input_interpreter.cpp4
-rw-r--r--src/core/hid/input_interpreter.h4
-rw-r--r--src/core/hle/service/friend/friend.cpp13
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.cpp42
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.h43
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp10
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h6
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp54
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h6
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp10
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h6
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h6
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp586
-rw-r--r--src/core/hle/service/hid/controllers/npad.h126
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp86
-rw-r--r--src/core/hle/service/hid/controllers/palma.h8
-rw-r--r--src/core/hle/service/hid/controllers/seven_six_axis.cpp (renamed from src/core/hle/service/hid/controllers/console_sixaxis.cpp)38
-rw-r--r--src/core/hle/service/hid/controllers/seven_six_axis.h (renamed from src/core/hle/service/hid/controllers/console_sixaxis.h)31
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.cpp413
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.h111
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h6
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h6
-rw-r--r--src/core/hle/service/hid/hid_server.cpp437
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp424
-rw-r--r--src/core/hle/service/hid/hid_util.h146
-rw-r--r--src/core/hle/service/hid/irs.cpp5
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp155
-rw-r--r--src/core/hle/service/hid/resource_manager.h119
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp3
-rw-r--r--src/core/memory/cheat_engine.cpp5
-rw-r--r--src/video_core/CMakeLists.txt4
-rw-r--r--src/video_core/host1x/codecs/codec.cpp329
-rw-r--r--src/video_core/host1x/codecs/codec.h39
-rw-r--r--src/video_core/host1x/codecs/h264.cpp4
-rw-r--r--src/video_core/host1x/codecs/h264.h1
-rw-r--r--src/video_core/host1x/ffmpeg/ffmpeg.cpp419
-rw-r--r--src/video_core/host1x/ffmpeg/ffmpeg.h213
-rw-r--r--src/video_core/host1x/nvdec.cpp2
-rw-r--r--src/video_core/host1x/nvdec.h2
-rw-r--r--src/video_core/host1x/vic.cpp62
-rw-r--r--src/video_core/host1x/vic.h4
-rw-r--r--src/video_core/query_cache/query_cache.h2
-rw-r--r--src/yuzu/CMakeLists.txt51
-rw-r--r--src/yuzu/configuration/shared_translation.cpp517
-rw-r--r--src/yuzu/configuration/shared_widget.cpp4
-rw-r--r--src/yuzu/game_list_worker.cpp2
53 files changed, 2656 insertions, 2052 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 597890655..66c10fc3f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -529,6 +529,7 @@ add_library(core STATIC
529 hle/service/hid/hid_server.h 529 hle/service/hid/hid_server.h
530 hle/service/hid/hid_system_server.cpp 530 hle/service/hid/hid_system_server.cpp
531 hle/service/hid/hid_system_server.h 531 hle/service/hid/hid_system_server.h
532 hle/service/hid/hid_util.h
532 hle/service/hid/hidbus.cpp 533 hle/service/hid/hidbus.cpp
533 hle/service/hid/hidbus.h 534 hle/service/hid/hidbus.h
534 hle/service/hid/irs.cpp 535 hle/service/hid/irs.cpp
@@ -540,8 +541,8 @@ add_library(core STATIC
540 hle/service/hid/xcd.cpp 541 hle/service/hid/xcd.cpp
541 hle/service/hid/xcd.h 542 hle/service/hid/xcd.h
542 hle/service/hid/errors.h 543 hle/service/hid/errors.h
543 hle/service/hid/controllers/console_sixaxis.cpp 544 hle/service/hid/controllers/console_six_axis.cpp
544 hle/service/hid/controllers/console_sixaxis.h 545 hle/service/hid/controllers/console_six_axis.h
545 hle/service/hid/controllers/controller_base.cpp 546 hle/service/hid/controllers/controller_base.cpp
546 hle/service/hid/controllers/controller_base.h 547 hle/service/hid/controllers/controller_base.h
547 hle/service/hid/controllers/debug_pad.cpp 548 hle/service/hid/controllers/debug_pad.cpp
@@ -556,6 +557,10 @@ add_library(core STATIC
556 hle/service/hid/controllers/npad.h 557 hle/service/hid/controllers/npad.h
557 hle/service/hid/controllers/palma.cpp 558 hle/service/hid/controllers/palma.cpp
558 hle/service/hid/controllers/palma.h 559 hle/service/hid/controllers/palma.h
560 hle/service/hid/controllers/seven_six_axis.cpp
561 hle/service/hid/controllers/seven_six_axis.h
562 hle/service/hid/controllers/six_axis.cpp
563 hle/service/hid/controllers/six_axis.h
559 hle/service/hid/controllers/stubbed.cpp 564 hle/service/hid/controllers/stubbed.cpp
560 hle/service/hid/controllers/stubbed.h 565 hle/service/hid/controllers/stubbed.h
561 hle/service/hid/controllers/touchscreen.cpp 566 hle/service/hid/controllers/touchscreen.cpp
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 34927cddd..a22015ada 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -8,6 +8,7 @@
8#include "common/thread.h" 8#include "common/thread.h"
9#include "core/hid/emulated_controller.h" 9#include "core/hid/emulated_controller.h"
10#include "core/hid/input_converter.h" 10#include "core/hid/input_converter.h"
11#include "core/hle/service/hid/hid_util.h"
11 12
12namespace Core::HID { 13namespace Core::HID {
13constexpr s32 HID_JOYSTICK_MAX = 0x7fff; 14constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
@@ -82,7 +83,7 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleInde
82} 83}
83 84
84void EmulatedController::ReloadFromSettings() { 85void EmulatedController::ReloadFromSettings() {
85 const auto player_index = NpadIdTypeToIndex(npad_id_type); 86 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
86 const auto& player = Settings::values.players.GetValue()[player_index]; 87 const auto& player = Settings::values.players.GetValue()[player_index];
87 88
88 for (std::size_t index = 0; index < player.buttons.size(); ++index) { 89 for (std::size_t index = 0; index < player.buttons.size(); ++index) {
@@ -118,7 +119,7 @@ void EmulatedController::ReloadFromSettings() {
118} 119}
119 120
120void EmulatedController::ReloadColorsFromSettings() { 121void EmulatedController::ReloadColorsFromSettings() {
121 const auto player_index = NpadIdTypeToIndex(npad_id_type); 122 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
122 const auto& player = Settings::values.players.GetValue()[player_index]; 123 const auto& player = Settings::values.players.GetValue()[player_index];
123 124
124 // Avoid updating colors if overridden by physical controller 125 // Avoid updating colors if overridden by physical controller
@@ -215,7 +216,7 @@ void EmulatedController::LoadDevices() {
215} 216}
216 217
217void EmulatedController::LoadTASParams() { 218void EmulatedController::LoadTASParams() {
218 const auto player_index = NpadIdTypeToIndex(npad_id_type); 219 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
219 Common::ParamPackage common_params{}; 220 Common::ParamPackage common_params{};
220 common_params.Set("engine", "tas"); 221 common_params.Set("engine", "tas");
221 common_params.Set("port", static_cast<int>(player_index)); 222 common_params.Set("port", static_cast<int>(player_index));
@@ -264,7 +265,7 @@ void EmulatedController::LoadTASParams() {
264} 265}
265 266
266void EmulatedController::LoadVirtualGamepadParams() { 267void EmulatedController::LoadVirtualGamepadParams() {
267 const auto player_index = NpadIdTypeToIndex(npad_id_type); 268 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
268 Common::ParamPackage common_params{}; 269 Common::ParamPackage common_params{};
269 common_params.Set("engine", "virtual_gamepad"); 270 common_params.Set("engine", "virtual_gamepad");
270 common_params.Set("port", static_cast<int>(player_index)); 271 common_params.Set("port", static_cast<int>(player_index));
@@ -615,7 +616,7 @@ bool EmulatedController::IsConfiguring() const {
615} 616}
616 617
617void EmulatedController::SaveCurrentConfig() { 618void EmulatedController::SaveCurrentConfig() {
618 const auto player_index = NpadIdTypeToIndex(npad_id_type); 619 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
619 auto& player = Settings::values.players.GetValue()[player_index]; 620 auto& player = Settings::values.players.GetValue()[player_index];
620 player.connected = is_connected; 621 player.connected = is_connected;
621 player.controller_type = MapNPadToSettingsType(npad_type); 622 player.controller_type = MapNPadToSettingsType(npad_type);
@@ -1212,7 +1213,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
1212 if (!output_devices[device_index]) { 1213 if (!output_devices[device_index]) {
1213 return false; 1214 return false;
1214 } 1215 }
1215 const auto player_index = NpadIdTypeToIndex(npad_id_type); 1216 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
1216 const auto& player = Settings::values.players.GetValue()[player_index]; 1217 const auto& player = Settings::values.players.GetValue()[player_index];
1217 const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f; 1218 const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f;
1218 1219
@@ -1238,7 +1239,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
1238} 1239}
1239 1240
1240bool EmulatedController::IsVibrationEnabled(std::size_t device_index) { 1241bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
1241 const auto player_index = NpadIdTypeToIndex(npad_id_type); 1242 const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
1242 const auto& player = Settings::values.players.GetValue()[player_index]; 1243 const auto& player = Settings::values.players.GetValue()[player_index];
1243 1244
1244 if (!player.vibration_enabled) { 1245 if (!player.vibration_enabled) {
@@ -1648,7 +1649,7 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
1648 } 1649 }
1649 if (is_connected) { 1650 if (is_connected) {
1650 LOG_WARNING(Service_HID, "Controller {} type changed while it's connected", 1651 LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
1651 NpadIdTypeToIndex(npad_id_type)); 1652 Service::HID::NpadIdTypeToIndex(npad_id_type));
1652 } 1653 }
1653 npad_type = npad_type_; 1654 npad_type = npad_type_;
1654} 1655}
diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp
index cf53c04d9..2cf25a870 100644
--- a/src/core/hid/hid_core.cpp
+++ b/src/core/hid/hid_core.cpp
@@ -6,6 +6,7 @@
6#include "core/hid/emulated_controller.h" 6#include "core/hid/emulated_controller.h"
7#include "core/hid/emulated_devices.h" 7#include "core/hid/emulated_devices.h"
8#include "core/hid/hid_core.h" 8#include "core/hid/hid_core.h"
9#include "core/hle/service/hid/hid_util.h"
9 10
10namespace Core::HID { 11namespace Core::HID {
11 12
@@ -98,11 +99,11 @@ const EmulatedDevices* HIDCore::GetEmulatedDevices() const {
98} 99}
99 100
100EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) { 101EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) {
101 return GetEmulatedController(IndexToNpadIdType(index)); 102 return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
102} 103}
103 104
104const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) const { 105const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) const {
105 return GetEmulatedController(IndexToNpadIdType(index)); 106 return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
106} 107}
107 108
108void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) { 109void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) {
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 70fcc6b69..4bf285f36 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -8,6 +8,7 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/point.h" 9#include "common/point.h"
10#include "common/uuid.h" 10#include "common/uuid.h"
11#include "common/vector_math.h"
11 12
12namespace Core::HID { 13namespace Core::HID {
13 14
@@ -598,6 +599,29 @@ struct SixAxisSensorIcInformation {
598static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8, 599static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
599 "SixAxisSensorIcInformation is an invalid size"); 600 "SixAxisSensorIcInformation is an invalid size");
600 601
602// This is nn::hid::SixAxisSensorAttribute
603struct SixAxisSensorAttribute {
604 union {
605 u32 raw{};
606 BitField<0, 1, u32> is_connected;
607 BitField<1, 1, u32> is_interpolated;
608 };
609};
610static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
611
612// This is nn::hid::SixAxisSensorState
613struct SixAxisSensorState {
614 s64 delta_time{};
615 s64 sampling_number{};
616 Common::Vec3f accel{};
617 Common::Vec3f gyro{};
618 Common::Vec3f rotation{};
619 std::array<Common::Vec3f, 3> orientation{};
620 SixAxisSensorAttribute attribute{};
621 INSERT_PADDING_BYTES(4); // Reserved
622};
623static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
624
601// This is nn::hid::VibrationDeviceHandle 625// This is nn::hid::VibrationDeviceHandle
602struct VibrationDeviceHandle { 626struct VibrationDeviceHandle {
603 NpadStyleIndex npad_type{NpadStyleIndex::None}; 627 NpadStyleIndex npad_type{NpadStyleIndex::None};
@@ -708,60 +732,4 @@ struct UniquePadId {
708}; 732};
709static_assert(sizeof(UniquePadId) == 0x8, "UniquePadId is an invalid size"); 733static_assert(sizeof(UniquePadId) == 0x8, "UniquePadId is an invalid size");
710 734
711/// Converts a NpadIdType to an array index.
712constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
713 switch (npad_id_type) {
714 case NpadIdType::Player1:
715 return 0;
716 case NpadIdType::Player2:
717 return 1;
718 case NpadIdType::Player3:
719 return 2;
720 case NpadIdType::Player4:
721 return 3;
722 case NpadIdType::Player5:
723 return 4;
724 case NpadIdType::Player6:
725 return 5;
726 case NpadIdType::Player7:
727 return 6;
728 case NpadIdType::Player8:
729 return 7;
730 case NpadIdType::Handheld:
731 return 8;
732 case NpadIdType::Other:
733 return 9;
734 default:
735 return 0;
736 }
737}
738
739/// Converts an array index to a NpadIdType
740constexpr NpadIdType IndexToNpadIdType(size_t index) {
741 switch (index) {
742 case 0:
743 return NpadIdType::Player1;
744 case 1:
745 return NpadIdType::Player2;
746 case 2:
747 return NpadIdType::Player3;
748 case 3:
749 return NpadIdType::Player4;
750 case 4:
751 return NpadIdType::Player5;
752 case 5:
753 return NpadIdType::Player6;
754 case 6:
755 return NpadIdType::Player7;
756 case 7:
757 return NpadIdType::Player8;
758 case 8:
759 return NpadIdType::Handheld;
760 case 9:
761 return NpadIdType::Other;
762 default:
763 return NpadIdType::Invalid;
764 }
765}
766
767} // namespace Core::HID 735} // namespace Core::HID
diff --git a/src/core/hid/input_interpreter.cpp b/src/core/hid/input_interpreter.cpp
index 11359f318..a6bdd28f2 100644
--- a/src/core/hid/input_interpreter.cpp
+++ b/src/core/hid/input_interpreter.cpp
@@ -13,14 +13,14 @@ InputInterpreter::InputInterpreter(Core::System& system)
13 : npad{system.ServiceManager() 13 : npad{system.ServiceManager()
14 .GetService<Service::HID::IHidServer>("hid") 14 .GetService<Service::HID::IHidServer>("hid")
15 ->GetResourceManager() 15 ->GetResourceManager()
16 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} { 16 ->GetNpad()} {
17 ResetButtonStates(); 17 ResetButtonStates();
18} 18}
19 19
20InputInterpreter::~InputInterpreter() = default; 20InputInterpreter::~InputInterpreter() = default;
21 21
22void InputInterpreter::PollInput() { 22void InputInterpreter::PollInput() {
23 const auto button_state = npad.GetAndResetPressState(); 23 const auto button_state = npad->GetAndResetPressState();
24 24
25 previous_index = current_index; 25 previous_index = current_index;
26 current_index = (current_index + 1) % button_states.size(); 26 current_index = (current_index + 1) % button_states.size();
diff --git a/src/core/hid/input_interpreter.h b/src/core/hid/input_interpreter.h
index 8c521b381..3569aac93 100644
--- a/src/core/hid/input_interpreter.h
+++ b/src/core/hid/input_interpreter.h
@@ -16,7 +16,7 @@ enum class NpadButton : u64;
16} 16}
17 17
18namespace Service::HID { 18namespace Service::HID {
19class Controller_NPad; 19class NPad;
20} 20}
21 21
22/** 22/**
@@ -101,7 +101,7 @@ public:
101 } 101 }
102 102
103private: 103private:
104 Service::HID::Controller_NPad& npad; 104 std::shared_ptr<Service::HID::NPad> npad;
105 105
106 /// Stores 9 consecutive button states polled from HID. 106 /// Stores 9 consecutive button states polled from HID.
107 std::array<Core::HID::NpadButton, 9> button_states{}; 107 std::array<Core::HID::NpadButton, 9> button_states{};
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 9d05f9801..0507b14e7 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -32,7 +32,7 @@ public:
32 {10200, nullptr, "SendFriendRequestForApplication"}, 32 {10200, nullptr, "SendFriendRequestForApplication"},
33 {10211, nullptr, "AddFacedFriendRequestForApplication"}, 33 {10211, nullptr, "AddFacedFriendRequestForApplication"},
34 {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"}, 34 {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"},
35 {10420, nullptr, "IsBlockedUserListCacheAvailable"}, 35 {10420, &IFriendService::CheckBlockedUserListAvailability, "CheckBlockedUserListAvailability"},
36 {10421, nullptr, "EnsureBlockedUserListAvailable"}, 36 {10421, nullptr, "EnsureBlockedUserListAvailable"},
37 {10500, nullptr, "GetProfileList"}, 37 {10500, nullptr, "GetProfileList"},
38 {10600, nullptr, "DeclareOpenOnlinePlaySession"}, 38 {10600, nullptr, "DeclareOpenOnlinePlaySession"},
@@ -206,6 +206,17 @@ private:
206 rb.Push(true); 206 rb.Push(true);
207 } 207 }
208 208
209 void CheckBlockedUserListAvailability(HLERequestContext& ctx) {
210 IPC::RequestParser rp{ctx};
211 const auto uuid{rp.PopRaw<Common::UUID>()};
212
213 LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString());
214
215 IPC::ResponseBuilder rb{ctx, 3};
216 rb.Push(ResultSuccess);
217 rb.Push(true);
218 }
219
209 KernelHelpers::ServiceContext service_context; 220 KernelHelpers::ServiceContext service_context;
210 221
211 Kernel::KEvent* completion_event; 222 Kernel::KEvent* completion_event;
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp
new file mode 100644
index 000000000..b2bf1d78d
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp
@@ -0,0 +1,42 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/core.h"
5#include "core/core_timing.h"
6#include "core/hid/emulated_console.h"
7#include "core/hid/hid_core.h"
8#include "core/hle/service/hid/controllers/console_six_axis.h"
9#include "core/memory.h"
10
11namespace Service::HID {
12constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
13
14ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
15 : ControllerBase{hid_core_} {
16 console = hid_core.GetEmulatedConsole();
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
18 "ConsoleSharedMemory is bigger than the shared memory");
19 shared_memory = std::construct_at(
20 reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
21}
22
23ConsoleSixAxis::~ConsoleSixAxis() = default;
24
25void ConsoleSixAxis::OnInit() {}
26
27void ConsoleSixAxis::OnRelease() {}
28
29void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
30 if (!IsControllerActivated()) {
31 return;
32 }
33
34 const auto motion_status = console->GetMotion();
35
36 shared_memory->sampling_number++;
37 shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
38 shared_memory->verticalization_error = motion_status.verticalization_error;
39 shared_memory->gyro_bias = motion_status.gyro_bias;
40}
41
42} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h
new file mode 100644
index 000000000..5b7c6a29a
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/console_six_axis.h
@@ -0,0 +1,43 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/vector_math.h"
7#include "core/hle/service/hid/controllers/controller_base.h"
8
9namespace Core::HID {
10class EmulatedConsole;
11} // namespace Core::HID
12
13namespace Service::HID {
14class ConsoleSixAxis final : public ControllerBase {
15public:
16 explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
17 ~ConsoleSixAxis() override;
18
19 // Called when the controller is initialized
20 void OnInit() override;
21
22 // When the controller is released
23 void OnRelease() override;
24
25 // When the controller is requesting an update for the shared memory
26 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
27
28private:
29 // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
30 struct ConsoleSharedMemory {
31 u64 sampling_number{};
32 bool is_seven_six_axis_sensor_at_rest{};
33 INSERT_PADDING_BYTES(3); // padding
34 f32 verticalization_error{};
35 Common::Vec3f gyro_bias{};
36 INSERT_PADDING_BYTES(4); // padding
37 };
38 static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
39
40 ConsoleSharedMemory* shared_memory = nullptr;
41 Core::HID::EmulatedConsole* console = nullptr;
42};
43} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index 8ec9f4a95..9de19ebfc 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -13,7 +13,7 @@
13namespace Service::HID { 13namespace Service::HID {
14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; 14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000;
15 15
16Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 16DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
17 : ControllerBase{hid_core_} { 17 : ControllerBase{hid_core_} {
18 static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, 18 static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size,
19 "DebugPadSharedMemory is bigger than the shared memory"); 19 "DebugPadSharedMemory is bigger than the shared memory");
@@ -22,13 +22,13 @@ Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_
22 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); 22 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
23} 23}
24 24
25Controller_DebugPad::~Controller_DebugPad() = default; 25DebugPad::~DebugPad() = default;
26 26
27void Controller_DebugPad::OnInit() {} 27void DebugPad::OnInit() {}
28 28
29void Controller_DebugPad::OnRelease() {} 29void DebugPad::OnRelease() {}
30 30
31void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 31void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
32 if (!IsControllerActivated()) { 32 if (!IsControllerActivated()) {
33 shared_memory->debug_pad_lifo.buffer_count = 0; 33 shared_memory->debug_pad_lifo.buffer_count = 0;
34 shared_memory->debug_pad_lifo.buffer_tail = 0; 34 shared_memory->debug_pad_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index 68ff0ea79..5566dba77 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -15,10 +15,10 @@ struct AnalogStickState;
15} // namespace Core::HID 15} // namespace Core::HID
16 16
17namespace Service::HID { 17namespace Service::HID {
18class Controller_DebugPad final : public ControllerBase { 18class DebugPad final : public ControllerBase {
19public: 19public:
20 explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 20 explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
21 ~Controller_DebugPad() override; 21 ~DebugPad() override;
22 22
23 // Called when the controller is initialized 23 // Called when the controller is initialized
24 void OnInit() override; 24 void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index 63eecd42b..59b2ec73c 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -23,7 +23,7 @@ constexpr f32 Square(s32 num) {
23 return static_cast<f32>(num * num); 23 return static_cast<f32>(num * num);
24} 24}
25 25
26Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 26Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
27 : ControllerBase(hid_core_) { 27 : ControllerBase(hid_core_) {
28 static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, 28 static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size,
29 "GestureSharedMemory is bigger than the shared memory"); 29 "GestureSharedMemory is bigger than the shared memory");
@@ -31,17 +31,17 @@ Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_sh
31 reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); 31 reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
32 console = hid_core.GetEmulatedConsole(); 32 console = hid_core.GetEmulatedConsole();
33} 33}
34Controller_Gesture::~Controller_Gesture() = default; 34Gesture::~Gesture() = default;
35 35
36void Controller_Gesture::OnInit() { 36void Gesture::OnInit() {
37 shared_memory->gesture_lifo.buffer_count = 0; 37 shared_memory->gesture_lifo.buffer_count = 0;
38 shared_memory->gesture_lifo.buffer_tail = 0; 38 shared_memory->gesture_lifo.buffer_tail = 0;
39 force_update = true; 39 force_update = true;
40} 40}
41 41
42void Controller_Gesture::OnRelease() {} 42void Gesture::OnRelease() {}
43 43
44void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 44void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
45 if (!IsControllerActivated()) { 45 if (!IsControllerActivated()) {
46 shared_memory->gesture_lifo.buffer_count = 0; 46 shared_memory->gesture_lifo.buffer_count = 0;
47 shared_memory->gesture_lifo.buffer_tail = 0; 47 shared_memory->gesture_lifo.buffer_tail = 0;
@@ -64,7 +64,7 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
64 UpdateGestureSharedMemory(gesture, time_difference); 64 UpdateGestureSharedMemory(gesture, time_difference);
65} 65}
66 66
67void Controller_Gesture::ReadTouchInput() { 67void Gesture::ReadTouchInput() {
68 if (!Settings::values.touchscreen.enabled) { 68 if (!Settings::values.touchscreen.enabled) {
69 fingers = {}; 69 fingers = {};
70 return; 70 return;
@@ -76,8 +76,7 @@ void Controller_Gesture::ReadTouchInput() {
76 } 76 }
77} 77}
78 78
79bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, 79bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference) {
80 f32 time_difference) {
81 const auto& last_entry = GetLastGestureEntry(); 80 const auto& last_entry = GetLastGestureEntry();
82 if (force_update) { 81 if (force_update) {
83 force_update = false; 82 force_update = false;
@@ -100,8 +99,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
100 return false; 99 return false;
101} 100}
102 101
103void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, 102void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) {
104 f32 time_difference) {
105 GestureType type = GestureType::Idle; 103 GestureType type = GestureType::Idle;
106 GestureAttribute attributes{}; 104 GestureAttribute attributes{};
107 105
@@ -138,8 +136,8 @@ void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture,
138 shared_memory->gesture_lifo.WriteNextEntry(next_state); 136 shared_memory->gesture_lifo.WriteNextEntry(next_state);
139} 137}
140 138
141void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type, 139void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
142 GestureAttribute& attributes) { 140 GestureAttribute& attributes) {
143 const auto& last_entry = GetLastGestureEntry(); 141 const auto& last_entry = GetLastGestureEntry();
144 142
145 gesture.detection_count++; 143 gesture.detection_count++;
@@ -152,8 +150,8 @@ void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& typ
152 } 150 }
153} 151}
154 152
155void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type, 153void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type,
156 f32 time_difference) { 154 f32 time_difference) {
157 const auto& last_entry = GetLastGestureEntry(); 155 const auto& last_entry = GetLastGestureEntry();
158 156
159 // Promote to pan type if touch moved 157 // Promote to pan type if touch moved
@@ -186,9 +184,8 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Gestu
186 } 184 }
187} 185}
188 186
189void Controller_Gesture::EndGesture(GestureProperties& gesture, 187void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
190 GestureProperties& last_gesture_props, GestureType& type, 188 GestureType& type, GestureAttribute& attributes, f32 time_difference) {
191 GestureAttribute& attributes, f32 time_difference) {
192 const auto& last_entry = GetLastGestureEntry(); 189 const auto& last_entry = GetLastGestureEntry();
193 190
194 if (last_gesture_props.active_points != 0) { 191 if (last_gesture_props.active_points != 0) {
@@ -222,9 +219,8 @@ void Controller_Gesture::EndGesture(GestureProperties& gesture,
222 } 219 }
223} 220}
224 221
225void Controller_Gesture::SetTapEvent(GestureProperties& gesture, 222void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
226 GestureProperties& last_gesture_props, GestureType& type, 223 GestureType& type, GestureAttribute& attributes) {
227 GestureAttribute& attributes) {
228 type = GestureType::Tap; 224 type = GestureType::Tap;
229 gesture = last_gesture_props; 225 gesture = last_gesture_props;
230 force_update = true; 226 force_update = true;
@@ -236,9 +232,8 @@ void Controller_Gesture::SetTapEvent(GestureProperties& gesture,
236 } 232 }
237} 233}
238 234
239void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, 235void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
240 GestureProperties& last_gesture_props, GestureType& type, 236 GestureType& type, f32 time_difference) {
241 f32 time_difference) {
242 const auto& last_entry = GetLastGestureEntry(); 237 const auto& last_entry = GetLastGestureEntry();
243 238
244 next_state.delta = gesture.mid_point - last_entry.pos; 239 next_state.delta = gesture.mid_point - last_entry.pos;
@@ -263,9 +258,8 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
263 } 258 }
264} 259}
265 260
266void Controller_Gesture::EndPanEvent(GestureProperties& gesture, 261void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
267 GestureProperties& last_gesture_props, GestureType& type, 262 GestureType& type, f32 time_difference) {
268 f32 time_difference) {
269 const auto& last_entry = GetLastGestureEntry(); 263 const auto& last_entry = GetLastGestureEntry();
270 next_state.vel_x = 264 next_state.vel_x =
271 static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); 265 static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference);
@@ -287,8 +281,8 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
287 force_update = true; 281 force_update = true;
288} 282}
289 283
290void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, 284void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
291 GestureProperties& last_gesture_props, GestureType& type) { 285 GestureType& type) {
292 const auto& last_entry = GetLastGestureEntry(); 286 const auto& last_entry = GetLastGestureEntry();
293 287
294 type = GestureType::Swipe; 288 type = GestureType::Swipe;
@@ -311,11 +305,11 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
311 next_state.direction = GestureDirection::Up; 305 next_state.direction = GestureDirection::Up;
312} 306}
313 307
314const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { 308const Gesture::GestureState& Gesture::GetLastGestureEntry() const {
315 return shared_memory->gesture_lifo.ReadCurrentEntry().state; 309 return shared_memory->gesture_lifo.ReadCurrentEntry().state;
316} 310}
317 311
318Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() { 312Gesture::GestureProperties Gesture::GetGestureProperties() {
319 GestureProperties gesture; 313 GestureProperties gesture;
320 std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; 314 std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers;
321 const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), 315 const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(),
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 0d6099ea0..4c6f8ee07 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -12,10 +12,10 @@
12#include "core/hle/service/hid/ring_lifo.h" 12#include "core/hle/service/hid/ring_lifo.h"
13 13
14namespace Service::HID { 14namespace Service::HID {
15class Controller_Gesture final : public ControllerBase { 15class Gesture final : public ControllerBase {
16public: 16public:
17 explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 17 explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
18 ~Controller_Gesture() override; 18 ~Gesture() override;
19 19
20 // Called when the controller is initialized 20 // Called when the controller is initialized
21 void OnInit() override; 21 void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 117d87433..ddb1b0ba4 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -12,7 +12,7 @@
12namespace Service::HID { 12namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; 13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
14 14
15Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 15Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
16 : ControllerBase{hid_core_} { 16 : ControllerBase{hid_core_} {
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, 17 static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size,
18 "KeyboardSharedMemory is bigger than the shared memory"); 18 "KeyboardSharedMemory is bigger than the shared memory");
@@ -21,13 +21,13 @@ Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_
21 emulated_devices = hid_core.GetEmulatedDevices(); 21 emulated_devices = hid_core.GetEmulatedDevices();
22} 22}
23 23
24Controller_Keyboard::~Controller_Keyboard() = default; 24Keyboard::~Keyboard() = default;
25 25
26void Controller_Keyboard::OnInit() {} 26void Keyboard::OnInit() {}
27 27
28void Controller_Keyboard::OnRelease() {} 28void Keyboard::OnRelease() {}
29 29
30void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 30void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
31 if (!IsControllerActivated()) { 31 if (!IsControllerActivated()) {
32 shared_memory->keyboard_lifo.buffer_count = 0; 32 shared_memory->keyboard_lifo.buffer_count = 0;
33 shared_memory->keyboard_lifo.buffer_tail = 0; 33 shared_memory->keyboard_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index 7532f53c6..172ec1309 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -14,10 +14,10 @@ struct KeyboardKey;
14} // namespace Core::HID 14} // namespace Core::HID
15 15
16namespace Service::HID { 16namespace Service::HID {
17class Controller_Keyboard final : public ControllerBase { 17class Keyboard final : public ControllerBase {
18public: 18public:
19 explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 19 explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
20 ~Controller_Keyboard() override; 20 ~Keyboard() override;
21 21
22 // Called when the controller is initialized 22 // Called when the controller is initialized
23 void OnInit() override; 23 void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 0afc66681..6e5a04e34 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -12,8 +12,7 @@
12namespace Service::HID { 12namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; 13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
14 14
15Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 15Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
16 : ControllerBase{hid_core_} {
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, 16 static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size,
18 "MouseSharedMemory is bigger than the shared memory"); 17 "MouseSharedMemory is bigger than the shared memory");
19 shared_memory = std::construct_at( 18 shared_memory = std::construct_at(
@@ -21,12 +20,12 @@ Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared
21 emulated_devices = hid_core.GetEmulatedDevices(); 20 emulated_devices = hid_core.GetEmulatedDevices();
22} 21}
23 22
24Controller_Mouse::~Controller_Mouse() = default; 23Mouse::~Mouse() = default;
25 24
26void Controller_Mouse::OnInit() {} 25void Mouse::OnInit() {}
27void Controller_Mouse::OnRelease() {} 26void Mouse::OnRelease() {}
28 27
29void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 28void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
30 if (!IsControllerActivated()) { 29 if (!IsControllerActivated()) {
31 shared_memory->mouse_lifo.buffer_count = 0; 30 shared_memory->mouse_lifo.buffer_count = 0;
32 shared_memory->mouse_lifo.buffer_tail = 0; 31 shared_memory->mouse_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 733d00577..a80f3823f 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -14,10 +14,10 @@ struct AnalogStickState;
14} // namespace Core::HID 14} // namespace Core::HID
15 15
16namespace Service::HID { 16namespace Service::HID {
17class Controller_Mouse final : public ControllerBase { 17class Mouse final : public ControllerBase {
18public: 18public:
19 explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 19 explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
20 ~Controller_Mouse() override; 20 ~Mouse() override;
21 21
22 // Called when the controller is initialized 22 // Called when the controller is initialized
23 void OnInit() override; 23 void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 127af2b82..08ee9de9c 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -18,6 +18,7 @@
18#include "core/hle/kernel/k_readable_event.h" 18#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/service/hid/controllers/npad.h" 19#include "core/hle/service/hid/controllers/npad.h"
20#include "core/hle/service/hid/errors.h" 20#include "core/hle/service/hid/errors.h"
21#include "core/hle/service/hid/hid_util.h"
21#include "core/hle/service/kernel_helpers.h" 22#include "core/hle/service/kernel_helpers.h"
22 23
23namespace Service::HID { 24namespace Service::HID {
@@ -29,60 +30,8 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
29 Core::HID::NpadIdType::Handheld, 30 Core::HID::NpadIdType::Handheld,
30}; 31};
31 32
32bool Controller_NPad::IsNpadIdValid(Core::HID::NpadIdType npad_id) { 33NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
33 switch (npad_id) { 34 KernelHelpers::ServiceContext& service_context_)
34 case Core::HID::NpadIdType::Player1:
35 case Core::HID::NpadIdType::Player2:
36 case Core::HID::NpadIdType::Player3:
37 case Core::HID::NpadIdType::Player4:
38 case Core::HID::NpadIdType::Player5:
39 case Core::HID::NpadIdType::Player6:
40 case Core::HID::NpadIdType::Player7:
41 case Core::HID::NpadIdType::Player8:
42 case Core::HID::NpadIdType::Other:
43 case Core::HID::NpadIdType::Handheld:
44 return true;
45 default:
46 LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
47 return false;
48 }
49}
50
51Result Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle) {
52 const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
53 const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
54 const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
55
56 if (!npad_type) {
57 return VibrationInvalidStyleIndex;
58 }
59 if (!npad_id) {
60 return VibrationInvalidNpadId;
61 }
62 if (!device_index) {
63 return VibrationDeviceIndexOutOfRange;
64 }
65
66 return ResultSuccess;
67}
68
69Result Controller_NPad::VerifyValidSixAxisSensorHandle(
70 const Core::HID::SixAxisSensorHandle& device_handle) {
71 const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
72 const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
73
74 if (!npad_id) {
75 return InvalidNpadId;
76 }
77 if (!device_index) {
78 return NpadDeviceIndexOutOfRange;
79 }
80
81 return ResultSuccess;
82}
83
84Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
85 KernelHelpers::ServiceContext& service_context_)
86 : ControllerBase{hid_core_}, service_context{service_context_} { 35 : ControllerBase{hid_core_}, service_context{service_context_} {
87 static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); 36 static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size);
88 for (std::size_t i = 0; i < controller_data.size(); ++i) { 37 for (std::size_t i = 0; i < controller_data.size(); ++i) {
@@ -103,7 +52,7 @@ Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_m
103 } 52 }
104} 53}
105 54
106Controller_NPad::~Controller_NPad() { 55NPad::~NPad() {
107 for (std::size_t i = 0; i < controller_data.size(); ++i) { 56 for (std::size_t i = 0; i < controller_data.size(); ++i) {
108 auto& controller = controller_data[i]; 57 auto& controller = controller_data[i];
109 controller.device->DeleteCallback(controller.callback_key); 58 controller.device->DeleteCallback(controller.callback_key);
@@ -111,8 +60,7 @@ Controller_NPad::~Controller_NPad() {
111 OnRelease(); 60 OnRelease();
112} 61}
113 62
114void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, 63void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
115 std::size_t controller_idx) {
116 if (type == Core::HID::ControllerTriggerType::All) { 64 if (type == Core::HID::ControllerTriggerType::All) {
117 ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx); 65 ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
118 ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx); 66 ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
@@ -150,7 +98,7 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
150 } 98 }
151} 99}
152 100
153void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) { 101void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
154 auto& controller = GetControllerFromNpadIdType(npad_id); 102 auto& controller = GetControllerFromNpadIdType(npad_id);
155 if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) { 103 if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) {
156 return; 104 return;
@@ -350,7 +298,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
350 hid_core.SetLastActiveController(npad_id); 298 hid_core.SetLastActiveController(npad_id);
351} 299}
352 300
353void Controller_NPad::OnInit() { 301void NPad::OnInit() {
354 if (!IsControllerActivated()) { 302 if (!IsControllerActivated()) {
355 return; 303 return;
356 } 304 }
@@ -384,7 +332,7 @@ void Controller_NPad::OnInit() {
384 } 332 }
385} 333}
386 334
387void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) { 335void NPad::WriteEmptyEntry(NpadInternalState* npad) {
388 NPadGenericState dummy_pad_state{}; 336 NPadGenericState dummy_pad_state{};
389 NpadGcTriggerState dummy_gc_state{}; 337 NpadGcTriggerState dummy_gc_state{};
390 dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1; 338 dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
@@ -405,7 +353,7 @@ void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
405 npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state); 353 npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
406} 354}
407 355
408void Controller_NPad::OnRelease() { 356void NPad::OnRelease() {
409 is_controller_initialized = false; 357 is_controller_initialized = false;
410 for (std::size_t i = 0; i < controller_data.size(); ++i) { 358 for (std::size_t i = 0; i < controller_data.size(); ++i) {
411 auto& controller = controller_data[i]; 359 auto& controller = controller_data[i];
@@ -416,7 +364,7 @@ void Controller_NPad::OnRelease() {
416 } 364 }
417} 365}
418 366
419void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { 367void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
420 std::scoped_lock lock{mutex}; 368 std::scoped_lock lock{mutex};
421 auto& controller = GetControllerFromNpadIdType(npad_id); 369 auto& controller = GetControllerFromNpadIdType(npad_id);
422 const auto controller_type = controller.device->GetNpadStyleIndex(); 370 const auto controller_type = controller.device->GetNpadStyleIndex();
@@ -485,7 +433,7 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
485 } 433 }
486} 434}
487 435
488void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 436void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
489 if (!IsControllerActivated()) { 437 if (!IsControllerActivated()) {
490 return; 438 return;
491 } 439 }
@@ -615,134 +563,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
615 } 563 }
616} 564}
617 565
618void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) { 566void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
619 if (!IsControllerActivated()) {
620 return;
621 }
622
623 for (std::size_t i = 0; i < controller_data.size(); ++i) {
624 auto& controller = controller_data[i];
625
626 const auto& controller_type = controller.device->GetNpadStyleIndex();
627
628 if (controller_type == Core::HID::NpadStyleIndex::None ||
629 !controller.device->IsConnected()) {
630 continue;
631 }
632
633 auto* npad = controller.shared_memory;
634 const auto& motion_state = controller.device->GetMotions();
635 auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
636 auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
637 auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
638 auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
639 auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
640 auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
641
642 // Clear previous state
643 sixaxis_fullkey_state = {};
644 sixaxis_handheld_state = {};
645 sixaxis_dual_left_state = {};
646 sixaxis_dual_right_state = {};
647 sixaxis_left_lifo_state = {};
648 sixaxis_right_lifo_state = {};
649
650 if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
651 controller.sixaxis_at_rest = true;
652 for (std::size_t e = 0; e < motion_state.size(); ++e) {
653 controller.sixaxis_at_rest =
654 controller.sixaxis_at_rest && motion_state[e].is_at_rest;
655 }
656 }
657
658 const auto set_motion_state = [&](SixAxisSensorState& state,
659 const Core::HID::ControllerMotion& hid_state) {
660 using namespace std::literals::chrono_literals;
661 static constexpr SixAxisSensorState default_motion_state = {
662 .delta_time = std::chrono::nanoseconds(5ms).count(),
663 .accel = {0, 0, -1.0f},
664 .orientation =
665 {
666 Common::Vec3f{1.0f, 0, 0},
667 Common::Vec3f{0, 1.0f, 0},
668 Common::Vec3f{0, 0, 1.0f},
669 },
670 .attribute = {1},
671 };
672 if (!controller.sixaxis_sensor_enabled) {
673 state = default_motion_state;
674 return;
675 }
676 if (!Settings::values.motion_enabled.GetValue()) {
677 state = default_motion_state;
678 return;
679 }
680 state.attribute.is_connected.Assign(1);
681 state.delta_time = std::chrono::nanoseconds(5ms).count();
682 state.accel = hid_state.accel;
683 state.gyro = hid_state.gyro;
684 state.rotation = hid_state.rotation;
685 state.orientation = hid_state.orientation;
686 };
687
688 switch (controller_type) {
689 case Core::HID::NpadStyleIndex::None:
690 ASSERT(false);
691 break;
692 case Core::HID::NpadStyleIndex::ProController:
693 set_motion_state(sixaxis_fullkey_state, motion_state[0]);
694 break;
695 case Core::HID::NpadStyleIndex::Handheld:
696 set_motion_state(sixaxis_handheld_state, motion_state[0]);
697 break;
698 case Core::HID::NpadStyleIndex::JoyconDual:
699 set_motion_state(sixaxis_dual_left_state, motion_state[0]);
700 set_motion_state(sixaxis_dual_right_state, motion_state[1]);
701 break;
702 case Core::HID::NpadStyleIndex::JoyconLeft:
703 set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
704 break;
705 case Core::HID::NpadStyleIndex::JoyconRight:
706 set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
707 break;
708 case Core::HID::NpadStyleIndex::Pokeball:
709 using namespace std::literals::chrono_literals;
710 set_motion_state(sixaxis_fullkey_state, motion_state[0]);
711 sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
712 break;
713 default:
714 break;
715 }
716
717 sixaxis_fullkey_state.sampling_number =
718 npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
719 sixaxis_handheld_state.sampling_number =
720 npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
721 sixaxis_dual_left_state.sampling_number =
722 npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
723 sixaxis_dual_right_state.sampling_number =
724 npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
725 sixaxis_left_lifo_state.sampling_number =
726 npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
727 sixaxis_right_lifo_state.sampling_number =
728 npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
729
730 if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
731 // This buffer only is updated on handheld on HW
732 npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
733 } else {
734 // Handheld doesn't update this buffer on HW
735 npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
736 }
737
738 npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
739 npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
740 npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
741 npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
742 }
743}
744
745void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
746 hid_core.SetSupportedStyleTag(style_set); 567 hid_core.SetSupportedStyleTag(style_set);
747 568
748 if (is_controller_initialized) { 569 if (is_controller_initialized) {
@@ -753,14 +574,14 @@ void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
753 is_controller_initialized = true; 574 is_controller_initialized = true;
754} 575}
755 576
756Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const { 577Core::HID::NpadStyleTag NPad::GetSupportedStyleSet() const {
757 if (!is_controller_initialized) { 578 if (!is_controller_initialized) {
758 return {Core::HID::NpadStyleSet::None}; 579 return {Core::HID::NpadStyleSet::None};
759 } 580 }
760 return hid_core.GetSupportedStyleTag(); 581 return hid_core.GetSupportedStyleTag();
761} 582}
762 583
763Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) { 584Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
764 constexpr std::size_t max_number_npad_ids = 0xa; 585 constexpr std::size_t max_number_npad_ids = 0xa;
765 const auto length = data.size(); 586 const auto length = data.size();
766 ASSERT(length > 0 && (length % sizeof(u32)) == 0); 587 ASSERT(length > 0 && (length % sizeof(u32)) == 0);
@@ -776,17 +597,17 @@ Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
776 return ResultSuccess; 597 return ResultSuccess;
777} 598}
778 599
779void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { 600void NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
780 const auto copy_amount = supported_npad_id_types.size() * sizeof(u32); 601 const auto copy_amount = supported_npad_id_types.size() * sizeof(u32);
781 ASSERT(max_length <= copy_amount); 602 ASSERT(max_length <= copy_amount);
782 std::memcpy(data, supported_npad_id_types.data(), copy_amount); 603 std::memcpy(data, supported_npad_id_types.data(), copy_amount);
783} 604}
784 605
785std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const { 606std::size_t NPad::GetSupportedNpadIdTypesSize() const {
786 return supported_npad_id_types.size(); 607 return supported_npad_id_types.size();
787} 608}
788 609
789void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { 610void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
790 if (joy_hold_type != NpadJoyHoldType::Horizontal && 611 if (joy_hold_type != NpadJoyHoldType::Horizontal &&
791 joy_hold_type != NpadJoyHoldType::Vertical) { 612 joy_hold_type != NpadJoyHoldType::Vertical) {
792 LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}", 613 LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}",
@@ -796,11 +617,11 @@ void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
796 hold_type = joy_hold_type; 617 hold_type = joy_hold_type;
797} 618}
798 619
799Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const { 620NPad::NpadJoyHoldType NPad::GetHoldType() const {
800 return hold_type; 621 return hold_type;
801} 622}
802 623
803void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) { 624void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
804 if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) { 625 if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
805 ASSERT_MSG(false, "Activation mode should be always None, Single or Dual"); 626 ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
806 return; 627 return;
@@ -809,21 +630,20 @@ void Controller_NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode a
809 handheld_activation_mode = activation_mode; 630 handheld_activation_mode = activation_mode;
810} 631}
811 632
812Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActivationMode() const { 633NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const {
813 return handheld_activation_mode; 634 return handheld_activation_mode;
814} 635}
815 636
816void Controller_NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { 637void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
817 communication_mode = communication_mode_; 638 communication_mode = communication_mode_;
818} 639}
819 640
820Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode() const { 641NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const {
821 return communication_mode; 642 return communication_mode;
822} 643}
823 644
824bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, 645bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
825 NpadJoyDeviceType npad_device_type, 646 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) {
826 NpadJoyAssignmentMode assignment_mode) {
827 if (!IsNpadIdValid(npad_id)) { 647 if (!IsNpadIdValid(npad_id)) {
828 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 648 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
829 return false; 649 return false;
@@ -892,9 +712,8 @@ bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID:
892 return true; 712 return true;
893} 713}
894 714
895bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, 715bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
896 std::size_t device_index, 716 const Core::HID::VibrationValue& vibration_value) {
897 const Core::HID::VibrationValue& vibration_value) {
898 auto& controller = GetControllerFromNpadIdType(npad_id); 717 auto& controller = GetControllerFromNpadIdType(npad_id);
899 if (!controller.device->IsConnected()) { 718 if (!controller.device->IsConnected()) {
900 return false; 719 return false;
@@ -938,10 +757,9 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
938 return controller.device->SetVibration(device_index, vibration); 757 return controller.device->SetVibration(device_index, vibration);
939} 758}
940 759
941void Controller_NPad::VibrateController( 760void NPad::VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle,
942 const Core::HID::VibrationDeviceHandle& vibration_device_handle, 761 const Core::HID::VibrationValue& vibration_value) {
943 const Core::HID::VibrationValue& vibration_value) { 762 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
944 if (IsDeviceHandleValid(vibration_device_handle).IsError()) {
945 return; 763 return;
946 } 764 }
947 765
@@ -985,7 +803,7 @@ void Controller_NPad::VibrateController(
985 } 803 }
986} 804}
987 805
988void Controller_NPad::VibrateControllers( 806void NPad::VibrateControllers(
989 std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, 807 std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
990 std::span<const Core::HID::VibrationValue> vibration_values) { 808 std::span<const Core::HID::VibrationValue> vibration_values) {
991 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { 809 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
@@ -1002,9 +820,9 @@ void Controller_NPad::VibrateControllers(
1002 } 820 }
1003} 821}
1004 822
1005Core::HID::VibrationValue Controller_NPad::GetLastVibration( 823Core::HID::VibrationValue NPad::GetLastVibration(
1006 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { 824 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
1007 if (IsDeviceHandleValid(vibration_device_handle).IsError()) { 825 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
1008 return {}; 826 return {};
1009 } 827 }
1010 828
@@ -1013,9 +831,9 @@ Core::HID::VibrationValue Controller_NPad::GetLastVibration(
1013 return controller.vibration[device_index].latest_vibration_value; 831 return controller.vibration[device_index].latest_vibration_value;
1014} 832}
1015 833
1016void Controller_NPad::InitializeVibrationDevice( 834void NPad::InitializeVibrationDevice(
1017 const Core::HID::VibrationDeviceHandle& vibration_device_handle) { 835 const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
1018 if (IsDeviceHandleValid(vibration_device_handle).IsError()) { 836 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
1019 return; 837 return;
1020 } 838 }
1021 839
@@ -1024,8 +842,8 @@ void Controller_NPad::InitializeVibrationDevice(
1024 InitializeVibrationDeviceAtIndex(npad_index, device_index); 842 InitializeVibrationDeviceAtIndex(npad_index, device_index);
1025} 843}
1026 844
1027void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, 845void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
1028 std::size_t device_index) { 846 std::size_t device_index) {
1029 auto& controller = GetControllerFromNpadIdType(npad_id); 847 auto& controller = GetControllerFromNpadIdType(npad_id);
1030 if (!Settings::values.vibration_enabled.GetValue()) { 848 if (!Settings::values.vibration_enabled.GetValue()) {
1031 controller.vibration[device_index].device_mounted = false; 849 controller.vibration[device_index].device_mounted = false;
@@ -1036,13 +854,13 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa
1036 controller.device->IsVibrationEnabled(device_index); 854 controller.device->IsVibrationEnabled(device_index);
1037} 855}
1038 856
1039void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { 857void NPad::SetPermitVibrationSession(bool permit_vibration_session) {
1040 permit_vibration_session_enabled = permit_vibration_session; 858 permit_vibration_session_enabled = permit_vibration_session;
1041} 859}
1042 860
1043bool Controller_NPad::IsVibrationDeviceMounted( 861bool NPad::IsVibrationDeviceMounted(
1044 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { 862 const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
1045 if (IsDeviceHandleValid(vibration_device_handle).IsError()) { 863 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
1046 return false; 864 return false;
1047 } 865 }
1048 866
@@ -1051,7 +869,7 @@ bool Controller_NPad::IsVibrationDeviceMounted(
1051 return controller.vibration[device_index].device_mounted; 869 return controller.vibration[device_index].device_mounted;
1052} 870}
1053 871
1054Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) { 872Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
1055 if (!IsNpadIdValid(npad_id)) { 873 if (!IsNpadIdValid(npad_id)) {
1056 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 874 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1057 // Fallback to player 1 875 // Fallback to player 1
@@ -1063,18 +881,17 @@ Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::Npad
1063 return controller.styleset_changed_event->GetReadableEvent(); 881 return controller.styleset_changed_event->GetReadableEvent();
1064} 882}
1065 883
1066void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const { 884void NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
1067 const auto& controller = GetControllerFromNpadIdType(npad_id); 885 const auto& controller = GetControllerFromNpadIdType(npad_id);
1068 controller.styleset_changed_event->Signal(); 886 controller.styleset_changed_event->Signal();
1069} 887}
1070 888
1071void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, 889void NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) {
1072 Core::HID::NpadIdType npad_id) {
1073 UpdateControllerAt(controller, npad_id, true); 890 UpdateControllerAt(controller, npad_id, true);
1074} 891}
1075 892
1076void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, 893void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id,
1077 Core::HID::NpadIdType npad_id, bool connected) { 894 bool connected) {
1078 auto& controller = GetControllerFromNpadIdType(npad_id); 895 auto& controller = GetControllerFromNpadIdType(npad_id);
1079 if (!connected) { 896 if (!connected) {
1080 DisconnectNpad(npad_id); 897 DisconnectNpad(npad_id);
@@ -1085,7 +902,7 @@ void Controller_NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type,
1085 InitNewlyAddedController(npad_id); 902 InitNewlyAddedController(npad_id);
1086} 903}
1087 904
1088Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) { 905Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
1089 if (!IsNpadIdValid(npad_id)) { 906 if (!IsNpadIdValid(npad_id)) {
1090 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 907 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1091 return InvalidNpadId; 908 return InvalidNpadId;
@@ -1134,54 +951,9 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
1134 return ResultSuccess; 951 return ResultSuccess;
1135} 952}
1136 953
1137Result Controller_NPad::SetGyroscopeZeroDriftMode( 954Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
1138 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1139 Core::HID::GyroscopeZeroDriftMode drift_mode) {
1140 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1141 if (is_valid.IsError()) {
1142 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1143 return is_valid;
1144 }
1145
1146 auto& sixaxis = GetSixaxisState(sixaxis_handle);
1147 auto& controller = GetControllerFromHandle(sixaxis_handle);
1148 sixaxis.gyroscope_zero_drift_mode = drift_mode;
1149 controller.device->SetGyroscopeZeroDriftMode(drift_mode);
1150
1151 return ResultSuccess;
1152}
1153
1154Result Controller_NPad::GetGyroscopeZeroDriftMode(
1155 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1156 Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
1157 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1158 if (is_valid.IsError()) {
1159 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1160 return is_valid;
1161 }
1162
1163 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
1164 drift_mode = sixaxis.gyroscope_zero_drift_mode;
1165
1166 return ResultSuccess;
1167}
1168
1169Result Controller_NPad::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1170 bool& is_at_rest) const {
1171 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1172 if (is_valid.IsError()) {
1173 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1174 return is_valid;
1175 }
1176
1177 const auto& controller = GetControllerFromHandle(sixaxis_handle);
1178 is_at_rest = controller.sixaxis_at_rest;
1179 return ResultSuccess;
1180}
1181
1182Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
1183 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const { 955 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const {
1184 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); 956 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
1185 if (is_valid.IsError()) { 957 if (is_valid.IsError()) {
1186 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); 958 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1187 return is_valid; 959 return is_valid;
@@ -1192,65 +964,9 @@ Result Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
1192 return ResultSuccess; 964 return ResultSuccess;
1193} 965}
1194 966
1195Result Controller_NPad::EnableSixAxisSensorUnalteredPassthrough( 967Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
1196 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
1197 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1198 if (is_valid.IsError()) {
1199 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1200 return is_valid;
1201 }
1202
1203 auto& sixaxis = GetSixaxisState(sixaxis_handle);
1204 sixaxis.unaltered_passtrough = is_enabled;
1205 return ResultSuccess;
1206}
1207
1208Result Controller_NPad::IsSixAxisSensorUnalteredPassthroughEnabled(
1209 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
1210 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1211 if (is_valid.IsError()) {
1212 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1213 return is_valid;
1214 }
1215
1216 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
1217 is_enabled = sixaxis.unaltered_passtrough;
1218 return ResultSuccess;
1219}
1220
1221Result Controller_NPad::LoadSixAxisSensorCalibrationParameter(
1222 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1223 Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
1224 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1225 if (is_valid.IsError()) {
1226 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1227 return is_valid;
1228 }
1229
1230 // TODO: Request this data to the controller. On error return 0xd8ca
1231 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
1232 calibration = sixaxis.calibration;
1233 return ResultSuccess;
1234}
1235
1236Result Controller_NPad::GetSixAxisSensorIcInformation(
1237 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
1238 Core::HID::SixAxisSensorIcInformation& ic_information) const {
1239 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1240 if (is_valid.IsError()) {
1241 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1242 return is_valid;
1243 }
1244
1245 // TODO: Request this data to the controller. On error return 0xd8ca
1246 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
1247 ic_information = sixaxis.ic_information;
1248 return ResultSuccess;
1249}
1250
1251Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
1252 const Core::HID::SixAxisSensorHandle& sixaxis_handle) { 968 const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
1253 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle); 969 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
1254 if (is_valid.IsError()) { 970 if (is_valid.IsError()) {
1255 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); 971 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1256 return is_valid; 972 return is_valid;
@@ -1262,83 +978,32 @@ Result Controller_NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
1262 return ResultSuccess; 978 return ResultSuccess;
1263} 979}
1264 980
1265Result Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 981NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) {
1266 bool sixaxis_status) { 982 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo;
1267 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1268 if (is_valid.IsError()) {
1269 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1270 return is_valid;
1271 }
1272
1273 auto& controller = GetControllerFromHandle(sixaxis_handle);
1274 controller.sixaxis_sensor_enabled = sixaxis_status;
1275 return ResultSuccess;
1276} 983}
1277 984
1278Result Controller_NPad::IsSixAxisSensorFusionEnabled( 985NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) {
1279 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const { 986 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo;
1280 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1281 if (is_valid.IsError()) {
1282 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1283 return is_valid;
1284 }
1285
1286 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
1287 is_fusion_enabled = sixaxis.is_fusion_enabled;
1288
1289 return ResultSuccess;
1290} 987}
1291Result Controller_NPad::SetSixAxisFusionEnabled(
1292 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) {
1293 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1294 if (is_valid.IsError()) {
1295 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1296 return is_valid;
1297 }
1298 988
1299 auto& sixaxis = GetSixaxisState(sixaxis_handle); 989NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) {
1300 sixaxis.is_fusion_enabled = is_fusion_enabled; 990 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo;
1301
1302 return ResultSuccess;
1303} 991}
1304 992
1305Result Controller_NPad::SetSixAxisFusionParameters( 993NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) {
1306 const Core::HID::SixAxisSensorHandle& sixaxis_handle, 994 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo;
1307 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
1308 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1309 if (is_valid.IsError()) {
1310 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1311 return is_valid;
1312 }
1313
1314 const auto param1 = sixaxis_fusion_parameters.parameter1;
1315 if (param1 < 0.0f || param1 > 1.0f) {
1316 return InvalidSixAxisFusionRange;
1317 }
1318
1319 auto& sixaxis = GetSixaxisState(sixaxis_handle);
1320 sixaxis.fusion = sixaxis_fusion_parameters;
1321
1322 return ResultSuccess;
1323} 995}
1324 996
1325Result Controller_NPad::GetSixAxisFusionParameters( 997NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) {
1326 const Core::HID::SixAxisSensorHandle& sixaxis_handle, 998 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo;
1327 Core::HID::SixAxisSensorFusionParameters& parameters) const { 999}
1328 const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
1329 if (is_valid.IsError()) {
1330 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
1331 return is_valid;
1332 }
1333
1334 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
1335 parameters = sixaxis.fusion;
1336 1000
1337 return ResultSuccess; 1001NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) {
1002 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo;
1338} 1003}
1339 1004
1340Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, 1005Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
1341 Core::HID::NpadIdType npad_id_2) { 1006 Core::HID::NpadIdType npad_id_2) {
1342 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { 1007 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
1343 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, 1008 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
1344 npad_id_2); 1009 npad_id_2);
@@ -1400,18 +1065,17 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
1400 return ResultSuccess; 1065 return ResultSuccess;
1401} 1066}
1402 1067
1403void Controller_NPad::StartLRAssignmentMode() { 1068void NPad::StartLRAssignmentMode() {
1404 // Nothing internally is used for lr assignment mode. Since we have the ability to set the 1069 // Nothing internally is used for lr assignment mode. Since we have the ability to set the
1405 // controller types from boot, it doesn't really matter about showing a selection screen 1070 // controller types from boot, it doesn't really matter about showing a selection screen
1406 is_in_lr_assignment_mode = true; 1071 is_in_lr_assignment_mode = true;
1407} 1072}
1408 1073
1409void Controller_NPad::StopLRAssignmentMode() { 1074void NPad::StopLRAssignmentMode() {
1410 is_in_lr_assignment_mode = false; 1075 is_in_lr_assignment_mode = false;
1411} 1076}
1412 1077
1413Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, 1078Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2) {
1414 Core::HID::NpadIdType npad_id_2) {
1415 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { 1079 if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
1416 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, 1080 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
1417 npad_id_2); 1081 npad_id_2);
@@ -1442,8 +1106,7 @@ Result Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
1442 return ResultSuccess; 1106 return ResultSuccess;
1443} 1107}
1444 1108
1445Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id, 1109Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
1446 Core::HID::LedPattern& pattern) const {
1447 if (!IsNpadIdValid(npad_id)) { 1110 if (!IsNpadIdValid(npad_id)) {
1448 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1111 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1449 return InvalidNpadId; 1112 return InvalidNpadId;
@@ -1453,8 +1116,8 @@ Result Controller_NPad::GetLedPattern(Core::HID::NpadIdType npad_id,
1453 return ResultSuccess; 1116 return ResultSuccess;
1454} 1117}
1455 1118
1456Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, 1119Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
1457 bool& is_valid) const { 1120 bool& is_valid) const {
1458 if (!IsNpadIdValid(npad_id)) { 1121 if (!IsNpadIdValid(npad_id)) {
1459 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1122 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1460 return InvalidNpadId; 1123 return InvalidNpadId;
@@ -1464,8 +1127,8 @@ Result Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::
1464 return ResultSuccess; 1127 return ResultSuccess;
1465} 1128}
1466 1129
1467Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled( 1130Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
1468 bool is_protection_enabled, Core::HID::NpadIdType npad_id) { 1131 Core::HID::NpadIdType npad_id) {
1469 if (!IsNpadIdValid(npad_id)) { 1132 if (!IsNpadIdValid(npad_id)) {
1470 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1133 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1471 return InvalidNpadId; 1134 return InvalidNpadId;
@@ -1475,11 +1138,11 @@ Result Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(
1475 return ResultSuccess; 1138 return ResultSuccess;
1476} 1139}
1477 1140
1478void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { 1141void NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
1479 analog_stick_use_center_clamp = use_center_clamp; 1142 analog_stick_use_center_clamp = use_center_clamp;
1480} 1143}
1481 1144
1482void Controller_NPad::ClearAllConnectedControllers() { 1145void NPad::ClearAllConnectedControllers() {
1483 for (auto& controller : controller_data) { 1146 for (auto& controller : controller_data) {
1484 if (controller.device->IsConnected() && 1147 if (controller.device->IsConnected() &&
1485 controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) { 1148 controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) {
@@ -1489,13 +1152,13 @@ void Controller_NPad::ClearAllConnectedControllers() {
1489 } 1152 }
1490} 1153}
1491 1154
1492void Controller_NPad::DisconnectAllConnectedControllers() { 1155void NPad::DisconnectAllConnectedControllers() {
1493 for (auto& controller : controller_data) { 1156 for (auto& controller : controller_data) {
1494 controller.device->Disconnect(); 1157 controller.device->Disconnect();
1495 } 1158 }
1496} 1159}
1497 1160
1498void Controller_NPad::ConnectAllDisconnectedControllers() { 1161void NPad::ConnectAllDisconnectedControllers() {
1499 for (auto& controller : controller_data) { 1162 for (auto& controller : controller_data) {
1500 if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None && 1163 if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None &&
1501 !controller.device->IsConnected()) { 1164 !controller.device->IsConnected()) {
@@ -1504,18 +1167,18 @@ void Controller_NPad::ConnectAllDisconnectedControllers() {
1504 } 1167 }
1505} 1168}
1506 1169
1507void Controller_NPad::ClearAllControllers() { 1170void NPad::ClearAllControllers() {
1508 for (auto& controller : controller_data) { 1171 for (auto& controller : controller_data) {
1509 controller.device->Disconnect(); 1172 controller.device->Disconnect();
1510 controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); 1173 controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
1511 } 1174 }
1512} 1175}
1513 1176
1514Core::HID::NpadButton Controller_NPad::GetAndResetPressState() { 1177Core::HID::NpadButton NPad::GetAndResetPressState() {
1515 return static_cast<Core::HID::NpadButton>(press_state.exchange(0)); 1178 return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
1516} 1179}
1517 1180
1518void Controller_NPad::ApplyNpadSystemCommonPolicy() { 1181void NPad::ApplyNpadSystemCommonPolicy() {
1519 Core::HID::NpadStyleTag styletag{}; 1182 Core::HID::NpadStyleTag styletag{};
1520 styletag.fullkey.Assign(1); 1183 styletag.fullkey.Assign(1);
1521 styletag.handheld.Assign(1); 1184 styletag.handheld.Assign(1);
@@ -1540,7 +1203,7 @@ void Controller_NPad::ApplyNpadSystemCommonPolicy() {
1540 supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; 1203 supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
1541} 1204}
1542 1205
1543bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const { 1206bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
1544 if (controller == Core::HID::NpadStyleIndex::Handheld) { 1207 if (controller == Core::HID::NpadStyleIndex::Handheld) {
1545 const bool support_handheld = 1208 const bool support_handheld =
1546 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), 1209 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
@@ -1591,51 +1254,50 @@ bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller
1591 return false; 1254 return false;
1592} 1255}
1593 1256
1594Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( 1257NPad::NpadControllerData& NPad::GetControllerFromHandle(
1595 const Core::HID::SixAxisSensorHandle& device_handle) { 1258 const Core::HID::VibrationDeviceHandle& device_handle) {
1596 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1259 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1597 return GetControllerFromNpadIdType(npad_id); 1260 return GetControllerFromNpadIdType(npad_id);
1598} 1261}
1599 1262
1600const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( 1263const NPad::NpadControllerData& NPad::GetControllerFromHandle(
1601 const Core::HID::SixAxisSensorHandle& device_handle) const { 1264 const Core::HID::VibrationDeviceHandle& device_handle) const {
1602 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1265 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1603 return GetControllerFromNpadIdType(npad_id); 1266 return GetControllerFromNpadIdType(npad_id);
1604} 1267}
1605 1268
1606Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( 1269NPad::NpadControllerData& NPad::GetControllerFromHandle(
1607 const Core::HID::VibrationDeviceHandle& device_handle) { 1270 const Core::HID::SixAxisSensorHandle& device_handle) {
1608 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1271 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1609 return GetControllerFromNpadIdType(npad_id); 1272 return GetControllerFromNpadIdType(npad_id);
1610} 1273}
1611 1274
1612const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromHandle( 1275const NPad::NpadControllerData& NPad::GetControllerFromHandle(
1613 const Core::HID::VibrationDeviceHandle& device_handle) const { 1276 const Core::HID::SixAxisSensorHandle& device_handle) const {
1614 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1277 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1615 return GetControllerFromNpadIdType(npad_id); 1278 return GetControllerFromNpadIdType(npad_id);
1616} 1279}
1617 1280
1618Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType( 1281NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
1619 Core::HID::NpadIdType npad_id) {
1620 if (!IsNpadIdValid(npad_id)) { 1282 if (!IsNpadIdValid(npad_id)) {
1621 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1283 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1622 npad_id = Core::HID::NpadIdType::Player1; 1284 npad_id = Core::HID::NpadIdType::Player1;
1623 } 1285 }
1624 const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id); 1286 const auto npad_index = NpadIdTypeToIndex(npad_id);
1625 return controller_data[npad_index]; 1287 return controller_data[npad_index];
1626} 1288}
1627 1289
1628const Controller_NPad::NpadControllerData& Controller_NPad::GetControllerFromNpadIdType( 1290const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(
1629 Core::HID::NpadIdType npad_id) const { 1291 Core::HID::NpadIdType npad_id) const {
1630 if (!IsNpadIdValid(npad_id)) { 1292 if (!IsNpadIdValid(npad_id)) {
1631 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); 1293 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
1632 npad_id = Core::HID::NpadIdType::Player1; 1294 npad_id = Core::HID::NpadIdType::Player1;
1633 } 1295 }
1634 const auto npad_index = Core::HID::NpadIdTypeToIndex(npad_id); 1296 const auto npad_index = NpadIdTypeToIndex(npad_id);
1635 return controller_data[npad_index]; 1297 return controller_data[npad_index];
1636} 1298}
1637 1299
1638Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( 1300Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1639 const Core::HID::SixAxisSensorHandle& sixaxis_handle) { 1301 const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
1640 auto& controller = GetControllerFromHandle(sixaxis_handle); 1302 auto& controller = GetControllerFromHandle(sixaxis_handle);
1641 switch (sixaxis_handle.npad_type) { 1303 switch (sixaxis_handle.npad_type) {
@@ -1658,7 +1320,7 @@ Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
1658 } 1320 }
1659} 1321}
1660 1322
1661const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties( 1323const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1662 const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { 1324 const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
1663 const auto& controller = GetControllerFromHandle(sixaxis_handle); 1325 const auto& controller = GetControllerFromHandle(sixaxis_handle);
1664 switch (sixaxis_handle.npad_type) { 1326 switch (sixaxis_handle.npad_type) {
@@ -1681,65 +1343,13 @@ const Core::HID::SixAxisSensorProperties& Controller_NPad::GetSixaxisProperties(
1681 } 1343 }
1682} 1344}
1683 1345
1684Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState( 1346NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) {
1685 const Core::HID::SixAxisSensorHandle& sixaxis_handle) { 1347 const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory;
1686 auto& controller = GetControllerFromHandle(sixaxis_handle);
1687 switch (sixaxis_handle.npad_type) {
1688 case Core::HID::NpadStyleIndex::ProController:
1689 case Core::HID::NpadStyleIndex::Pokeball:
1690 return controller.sixaxis_fullkey;
1691 case Core::HID::NpadStyleIndex::Handheld:
1692 return controller.sixaxis_handheld;
1693 case Core::HID::NpadStyleIndex::JoyconDual:
1694 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1695 return controller.sixaxis_dual_left;
1696 }
1697 return controller.sixaxis_dual_right;
1698 case Core::HID::NpadStyleIndex::JoyconLeft:
1699 return controller.sixaxis_left;
1700 case Core::HID::NpadStyleIndex::JoyconRight:
1701 return controller.sixaxis_right;
1702 default:
1703 return controller.sixaxis_unknown;
1704 }
1705}
1706
1707const Controller_NPad::SixaxisParameters& Controller_NPad::GetSixaxisState(
1708 const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
1709 const auto& controller = GetControllerFromHandle(sixaxis_handle);
1710 switch (sixaxis_handle.npad_type) {
1711 case Core::HID::NpadStyleIndex::ProController:
1712 case Core::HID::NpadStyleIndex::Pokeball:
1713 return controller.sixaxis_fullkey;
1714 case Core::HID::NpadStyleIndex::Handheld:
1715 return controller.sixaxis_handheld;
1716 case Core::HID::NpadStyleIndex::JoyconDual:
1717 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
1718 return controller.sixaxis_dual_left;
1719 }
1720 return controller.sixaxis_dual_right;
1721 case Core::HID::NpadStyleIndex::JoyconLeft:
1722 return controller.sixaxis_left;
1723 case Core::HID::NpadStyleIndex::JoyconRight:
1724 return controller.sixaxis_right;
1725 default:
1726 return controller.sixaxis_unknown;
1727 }
1728}
1729
1730Controller_NPad::AppletDetailedUiType Controller_NPad::GetAppletDetailedUiType(
1731 Core::HID::NpadIdType npad_id) {
1732
1733 auto controller = GetControllerFromNpadIdType(npad_id);
1734 auto shared_memory = controller.shared_memory;
1735 Service::HID::Controller_NPad::AppletFooterUiType applet_footer_type =
1736 shared_memory->applet_footer_type;
1737 1348
1738 Controller_NPad::AppletDetailedUiType detailed_ui_type{ 1349 return {
1739 .ui_variant = 0, 1350 .ui_variant = 0,
1740 .footer = applet_footer_type, 1351 .footer = shared_memory->applet_footer_type,
1741 }; 1352 };
1742 return detailed_ui_type;
1743} 1353}
1744 1354
1745} // namespace Service::HID 1355} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index cd93abdd1..9167c93f0 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -10,7 +10,6 @@
10 10
11#include "common/bit_field.h" 11#include "common/bit_field.h"
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/vector_math.h"
14 13
15#include "core/hid/hid_types.h" 14#include "core/hid/hid_types.h"
16#include "core/hle/service/hid/controllers/controller_base.h" 15#include "core/hle/service/hid/controllers/controller_base.h"
@@ -34,11 +33,11 @@ union Result;
34 33
35namespace Service::HID { 34namespace Service::HID {
36 35
37class Controller_NPad final : public ControllerBase { 36class NPad final : public ControllerBase {
38public: 37public:
39 explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 38 explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
40 KernelHelpers::ServiceContext& service_context_); 39 KernelHelpers::ServiceContext& service_context_);
41 ~Controller_NPad() override; 40 ~NPad() override;
42 41
43 // Called when the controller is initialized 42 // Called when the controller is initialized
44 void OnInit() override; 43 void OnInit() override;
@@ -49,9 +48,6 @@ public:
49 // When the controller is requesting an update for the shared memory 48 // When the controller is requesting an update for the shared memory
50 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 49 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
51 50
52 // When the controller is requesting a motion update for the shared memory
53 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
54
55 // This is nn::hid::NpadJoyHoldType 51 // This is nn::hid::NpadJoyHoldType
56 enum class NpadJoyHoldType : u64 { 52 enum class NpadJoyHoldType : u64 {
57 Vertical = 0, 53 Vertical = 0,
@@ -133,6 +129,8 @@ public:
133 Revision3 = 3, 129 Revision3 = 3,
134 }; 130 };
135 131
132 using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>;
133
136 void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); 134 void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
137 Core::HID::NpadStyleTag GetSupportedStyleSet() const; 135 Core::HID::NpadStyleTag GetSupportedStyleSet() const;
138 136
@@ -185,37 +183,18 @@ public:
185 183
186 Result DisconnectNpad(Core::HID::NpadIdType npad_id); 184 Result DisconnectNpad(Core::HID::NpadIdType npad_id);
187 185
188 Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
189 Core::HID::GyroscopeZeroDriftMode drift_mode);
190 Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
191 Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
192 Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
193 bool& is_at_rest) const;
194 Result IsFirmwareUpdateAvailableForSixAxisSensor( 186 Result IsFirmwareUpdateAvailableForSixAxisSensor(
195 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const; 187 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const;
196 Result EnableSixAxisSensorUnalteredPassthrough(
197 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
198 Result IsSixAxisSensorUnalteredPassthroughEnabled(
199 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
200 Result LoadSixAxisSensorCalibrationParameter(
201 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
202 Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
203 Result GetSixAxisSensorIcInformation(
204 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
205 Core::HID::SixAxisSensorIcInformation& ic_information) const;
206 Result ResetIsSixAxisSensorDeviceNewlyAssigned( 188 Result ResetIsSixAxisSensorDeviceNewlyAssigned(
207 const Core::HID::SixAxisSensorHandle& sixaxis_handle); 189 const Core::HID::SixAxisSensorHandle& sixaxis_handle);
208 Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 190
209 bool sixaxis_status); 191 SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id);
210 Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 192 SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id);
211 bool& is_fusion_enabled) const; 193 SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id);
212 Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, 194 SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id);
213 bool is_fusion_enabled); 195 SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id);
214 Result SetSixAxisFusionParameters( 196 SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id);
215 const Core::HID::SixAxisSensorHandle& sixaxis_handle, 197
216 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
217 Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
218 Core::HID::SixAxisSensorFusionParameters& parameters) const;
219 Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; 198 Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
220 Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, 199 Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
221 bool& is_enabled) const; 200 bool& is_enabled) const;
@@ -239,10 +218,6 @@ public:
239 218
240 void ApplyNpadSystemCommonPolicy(); 219 void ApplyNpadSystemCommonPolicy();
241 220
242 static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
243 static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
244 static Result VerifyValidSixAxisSensorHandle(
245 const Core::HID::SixAxisSensorHandle& device_handle);
246 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); 221 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
247 222
248private: 223private:
@@ -302,29 +277,6 @@ private:
302 }; 277 };
303 static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); 278 static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
304 279
305 // This is nn::hid::SixAxisSensorAttribute
306 struct SixAxisSensorAttribute {
307 union {
308 u32 raw{};
309 BitField<0, 1, u32> is_connected;
310 BitField<1, 1, u32> is_interpolated;
311 };
312 };
313 static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
314
315 // This is nn::hid::SixAxisSensorState
316 struct SixAxisSensorState {
317 s64 delta_time{};
318 s64 sampling_number{};
319 Common::Vec3f accel{};
320 Common::Vec3f gyro{};
321 Common::Vec3f rotation{};
322 std::array<Common::Vec3f, 3> orientation{};
323 SixAxisSensorAttribute attribute{};
324 INSERT_PADDING_BYTES(4); // Reserved
325 };
326 static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
327
328 // This is nn::hid::server::NpadGcTriggerState 280 // This is nn::hid::server::NpadGcTriggerState
329 struct NpadGcTriggerState { 281 struct NpadGcTriggerState {
330 s64 sampling_number{}; 282 s64 sampling_number{};
@@ -444,12 +396,12 @@ private:
444 Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{}; 396 Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{};
445 Lifo<NPadGenericState, hid_entry_count> palma_lifo{}; 397 Lifo<NPadGenericState, hid_entry_count> palma_lifo{};
446 Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{}; 398 Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{};
447 Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{}; 399 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
448 Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{}; 400 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
449 Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{}; 401 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
450 Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{}; 402 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
451 Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{}; 403 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
452 Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{}; 404 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
453 DeviceType device_type{}; 405 DeviceType device_type{};
454 INSERT_PADDING_BYTES(0x4); // Reserved 406 INSERT_PADDING_BYTES(0x4); // Reserved
455 NPadSystemProperties system_properties{}; 407 NPadSystemProperties system_properties{};
@@ -483,16 +435,6 @@ private:
483 std::chrono::steady_clock::time_point last_vibration_timepoint{}; 435 std::chrono::steady_clock::time_point last_vibration_timepoint{};
484 }; 436 };
485 437
486 struct SixaxisParameters {
487 bool is_fusion_enabled{true};
488 bool unaltered_passtrough{false};
489 Core::HID::SixAxisSensorFusionParameters fusion{};
490 Core::HID::SixAxisSensorCalibrationParameter calibration{};
491 Core::HID::SixAxisSensorIcInformation ic_information{};
492 Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
493 Core::HID::GyroscopeZeroDriftMode::Standard};
494 };
495
496 struct NpadControllerData { 438 struct NpadControllerData {
497 Kernel::KEvent* styleset_changed_event{}; 439 Kernel::KEvent* styleset_changed_event{};
498 NpadInternalState* shared_memory = nullptr; 440 NpadInternalState* shared_memory = nullptr;
@@ -506,27 +448,10 @@ private:
506 bool is_dual_left_connected{true}; 448 bool is_dual_left_connected{true};
507 bool is_dual_right_connected{true}; 449 bool is_dual_right_connected{true};
508 450
509 // Motion parameters
510 bool sixaxis_at_rest{true};
511 bool sixaxis_sensor_enabled{true};
512 SixaxisParameters sixaxis_fullkey{};
513 SixaxisParameters sixaxis_handheld{};
514 SixaxisParameters sixaxis_dual_left{};
515 SixaxisParameters sixaxis_dual_right{};
516 SixaxisParameters sixaxis_left{};
517 SixaxisParameters sixaxis_right{};
518 SixaxisParameters sixaxis_unknown{};
519
520 // Current pad state 451 // Current pad state
521 NPadGenericState npad_pad_state{}; 452 NPadGenericState npad_pad_state{};
522 NPadGenericState npad_libnx_state{}; 453 NPadGenericState npad_libnx_state{};
523 NpadGcTriggerState npad_trigger_state{}; 454 NpadGcTriggerState npad_trigger_state{};
524 SixAxisSensorState sixaxis_fullkey_state{};
525 SixAxisSensorState sixaxis_handheld_state{};
526 SixAxisSensorState sixaxis_dual_left_state{};
527 SixAxisSensorState sixaxis_dual_right_state{};
528 SixAxisSensorState sixaxis_left_lifo_state{};
529 SixAxisSensorState sixaxis_right_lifo_state{};
530 int callback_key{}; 455 int callback_key{};
531 }; 456 };
532 457
@@ -537,13 +462,13 @@ private:
537 void WriteEmptyEntry(NpadInternalState* npad); 462 void WriteEmptyEntry(NpadInternalState* npad);
538 463
539 NpadControllerData& GetControllerFromHandle( 464 NpadControllerData& GetControllerFromHandle(
540 const Core::HID::SixAxisSensorHandle& device_handle);
541 const NpadControllerData& GetControllerFromHandle(
542 const Core::HID::SixAxisSensorHandle& device_handle) const;
543 NpadControllerData& GetControllerFromHandle(
544 const Core::HID::VibrationDeviceHandle& device_handle); 465 const Core::HID::VibrationDeviceHandle& device_handle);
545 const NpadControllerData& GetControllerFromHandle( 466 const NpadControllerData& GetControllerFromHandle(
546 const Core::HID::VibrationDeviceHandle& device_handle) const; 467 const Core::HID::VibrationDeviceHandle& device_handle) const;
468 NpadControllerData& GetControllerFromHandle(
469 const Core::HID::SixAxisSensorHandle& device_handle);
470 const NpadControllerData& GetControllerFromHandle(
471 const Core::HID::SixAxisSensorHandle& device_handle) const;
547 NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id); 472 NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
548 const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const; 473 const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
549 474
@@ -551,9 +476,6 @@ private:
551 const Core::HID::SixAxisSensorHandle& device_handle); 476 const Core::HID::SixAxisSensorHandle& device_handle);
552 const Core::HID::SixAxisSensorProperties& GetSixaxisProperties( 477 const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
553 const Core::HID::SixAxisSensorHandle& device_handle) const; 478 const Core::HID::SixAxisSensorHandle& device_handle) const;
554 SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
555 const SixaxisParameters& GetSixaxisState(
556 const Core::HID::SixAxisSensorHandle& device_handle) const;
557 479
558 std::atomic<u64> press_state{}; 480 std::atomic<u64> press_state{};
559 481
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 51a18335f..588ff9d62 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -12,35 +12,35 @@
12 12
13namespace Service::HID { 13namespace Service::HID {
14 14
15Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 15Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
16 KernelHelpers::ServiceContext& service_context_) 16 KernelHelpers::ServiceContext& service_context_)
17 : ControllerBase{hid_core_}, service_context{service_context_} { 17 : ControllerBase{hid_core_}, service_context{service_context_} {
18 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); 18 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
19 operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); 19 operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
20} 20}
21 21
22Controller_Palma::~Controller_Palma() { 22Palma::~Palma() {
23 service_context.CloseEvent(operation_complete_event); 23 service_context.CloseEvent(operation_complete_event);
24}; 24};
25 25
26void Controller_Palma::OnInit() {} 26void Palma::OnInit() {}
27 27
28void Controller_Palma::OnRelease() {} 28void Palma::OnRelease() {}
29 29
30void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 30void Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
31 if (!IsControllerActivated()) { 31 if (!IsControllerActivated()) {
32 return; 32 return;
33 } 33 }
34} 34}
35 35
36Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, 36Result Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
37 PalmaConnectionHandle& handle) { 37 PalmaConnectionHandle& handle) {
38 active_handle.npad_id = npad_id; 38 active_handle.npad_id = npad_id;
39 handle = active_handle; 39 handle = active_handle;
40 return ResultSuccess; 40 return ResultSuccess;
41} 41}
42 42
43Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) { 43Result Palma::InitializePalma(const PalmaConnectionHandle& handle) {
44 if (handle.npad_id != active_handle.npad_id) { 44 if (handle.npad_id != active_handle.npad_id) {
45 return InvalidPalmaHandle; 45 return InvalidPalmaHandle;
46 } 46 }
@@ -48,7 +48,7 @@ Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) {
48 return ResultSuccess; 48 return ResultSuccess;
49} 49}
50 50
51Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent( 51Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent(
52 const PalmaConnectionHandle& handle) const { 52 const PalmaConnectionHandle& handle) const {
53 if (handle.npad_id != active_handle.npad_id) { 53 if (handle.npad_id != active_handle.npad_id) {
54 LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id); 54 LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id);
@@ -56,9 +56,9 @@ Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent(
56 return operation_complete_event->GetReadableEvent(); 56 return operation_complete_event->GetReadableEvent();
57} 57}
58 58
59Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle, 59Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
60 PalmaOperationType& operation_type, 60 PalmaOperationType& operation_type,
61 PalmaOperationData& data) const { 61 PalmaOperationData& data) const {
62 if (handle.npad_id != active_handle.npad_id) { 62 if (handle.npad_id != active_handle.npad_id) {
63 return InvalidPalmaHandle; 63 return InvalidPalmaHandle;
64 } 64 }
@@ -67,8 +67,7 @@ Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& hand
67 return ResultSuccess; 67 return ResultSuccess;
68} 68}
69 69
70Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, 70Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity) {
71 u64 palma_activity) {
72 if (handle.npad_id != active_handle.npad_id) { 71 if (handle.npad_id != active_handle.npad_id) {
73 return InvalidPalmaHandle; 72 return InvalidPalmaHandle;
74 } 73 }
@@ -79,8 +78,7 @@ Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
79 return ResultSuccess; 78 return ResultSuccess;
80} 79}
81 80
82Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, 81Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_) {
83 PalmaFrModeType fr_mode_) {
84 if (handle.npad_id != active_handle.npad_id) { 82 if (handle.npad_id != active_handle.npad_id) {
85 return InvalidPalmaHandle; 83 return InvalidPalmaHandle;
86 } 84 }
@@ -88,7 +86,7 @@ Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle,
88 return ResultSuccess; 86 return ResultSuccess;
89} 87}
90 88
91Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { 89Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
92 if (handle.npad_id != active_handle.npad_id) { 90 if (handle.npad_id != active_handle.npad_id) {
93 return InvalidPalmaHandle; 91 return InvalidPalmaHandle;
94 } 92 }
@@ -99,25 +97,25 @@ Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
99 return ResultSuccess; 97 return ResultSuccess;
100} 98}
101 99
102Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) { 100Result Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
103 if (handle.npad_id != active_handle.npad_id) { 101 if (handle.npad_id != active_handle.npad_id) {
104 return InvalidPalmaHandle; 102 return InvalidPalmaHandle;
105 } 103 }
106 return ResultSuccess; 104 return ResultSuccess;
107} 105}
108 106
109Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) { 107Result Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
110 if (handle.npad_id != active_handle.npad_id) { 108 if (handle.npad_id != active_handle.npad_id) {
111 return InvalidPalmaHandle; 109 return InvalidPalmaHandle;
112 } 110 }
113 return ResultSuccess; 111 return ResultSuccess;
114} 112}
115 113
116void Controller_Palma::ReadPalmaApplicationSection() {} 114void Palma::ReadPalmaApplicationSection() {}
117 115
118void Controller_Palma::WritePalmaApplicationSection() {} 116void Palma::WritePalmaApplicationSection() {}
119 117
120Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { 118Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
121 if (handle.npad_id != active_handle.npad_id) { 119 if (handle.npad_id != active_handle.npad_id) {
122 return InvalidPalmaHandle; 120 return InvalidPalmaHandle;
123 } 121 }
@@ -128,7 +126,7 @@ Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle
128 return ResultSuccess; 126 return ResultSuccess;
129} 127}
130 128
131Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { 129Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
132 if (handle.npad_id != active_handle.npad_id) { 130 if (handle.npad_id != active_handle.npad_id) {
133 return InvalidPalmaHandle; 131 return InvalidPalmaHandle;
134 } 132 }
@@ -139,10 +137,9 @@ Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle&
139 return ResultSuccess; 137 return ResultSuccess;
140} 138}
141 139
142void Controller_Palma::WritePalmaActivityEntry() {} 140void Palma::WritePalmaActivityEntry() {}
143 141
144Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, 142Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown) {
145 u64 unknown) {
146 if (handle.npad_id != active_handle.npad_id) { 143 if (handle.npad_id != active_handle.npad_id) {
147 return InvalidPalmaHandle; 144 return InvalidPalmaHandle;
148 } 145 }
@@ -153,8 +150,8 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
153 return ResultSuccess; 150 return ResultSuccess;
154} 151}
155 152
156Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, 153Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
157 Common::ProcessAddress t_mem, u64 size) { 154 Common::ProcessAddress t_mem, u64 size) {
158 if (handle.npad_id != active_handle.npad_id) { 155 if (handle.npad_id != active_handle.npad_id) {
159 return InvalidPalmaHandle; 156 return InvalidPalmaHandle;
160 } 157 }
@@ -165,8 +162,8 @@ Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle
165 return ResultSuccess; 162 return ResultSuccess;
166} 163}
167 164
168Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, 165Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
169 s32 database_id_version_) { 166 s32 database_id_version_) {
170 if (handle.npad_id != active_handle.npad_id) { 167 if (handle.npad_id != active_handle.npad_id) {
171 return InvalidPalmaHandle; 168 return InvalidPalmaHandle;
172 } 169 }
@@ -178,8 +175,7 @@ Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnec
178 return ResultSuccess; 175 return ResultSuccess;
179} 176}
180 177
181Result Controller_Palma::GetPalmaDataBaseIdentificationVersion( 178Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle) {
182 const PalmaConnectionHandle& handle) {
183 if (handle.npad_id != active_handle.npad_id) { 179 if (handle.npad_id != active_handle.npad_id) {
184 return InvalidPalmaHandle; 180 return InvalidPalmaHandle;
185 } 181 }
@@ -191,26 +187,26 @@ Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
191 return ResultSuccess; 187 return ResultSuccess;
192} 188}
193 189
194void Controller_Palma::SuspendPalmaFeature() {} 190void Palma::SuspendPalmaFeature() {}
195 191
196Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const { 192Result Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
197 if (handle.npad_id != active_handle.npad_id) { 193 if (handle.npad_id != active_handle.npad_id) {
198 return InvalidPalmaHandle; 194 return InvalidPalmaHandle;
199 } 195 }
200 return operation.result; 196 return operation.result;
201} 197}
202void Controller_Palma::ReadPalmaPlayLog() {} 198void Palma::ReadPalmaPlayLog() {}
203 199
204void Controller_Palma::ResetPalmaPlayLog() {} 200void Palma::ResetPalmaPlayLog() {}
205 201
206void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) { 202void Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
207 // If true controllers are able to be paired 203 // If true controllers are able to be paired
208 is_connectable = is_all_connectable; 204 is_connectable = is_all_connectable;
209} 205}
210 206
211void Controller_Palma::SetIsPalmaPairedConnectable() {} 207void Palma::SetIsPalmaPairedConnectable() {}
212 208
213Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) { 209Result Palma::PairPalma(const PalmaConnectionHandle& handle) {
214 if (handle.npad_id != active_handle.npad_id) { 210 if (handle.npad_id != active_handle.npad_id) {
215 return InvalidPalmaHandle; 211 return InvalidPalmaHandle;
216 } 212 }
@@ -218,14 +214,14 @@ Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) {
218 return ResultSuccess; 214 return ResultSuccess;
219} 215}
220 216
221void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {} 217void Palma::SetPalmaBoostMode(bool boost_mode) {}
222 218
223void Controller_Palma::CancelWritePalmaWaveEntry() {} 219void Palma::CancelWritePalmaWaveEntry() {}
224 220
225void Controller_Palma::EnablePalmaBoostMode() {} 221void Palma::EnablePalmaBoostMode() {}
226 222
227void Controller_Palma::GetPalmaBluetoothAddress() {} 223void Palma::GetPalmaBluetoothAddress() {}
228 224
229void Controller_Palma::SetDisallowedPalmaConnection() {} 225void Palma::SetDisallowedPalmaConnection() {}
230 226
231} // namespace Service::HID 227} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
index a0491a819..a6047f36a 100644
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -23,7 +23,7 @@ class EmulatedController;
23} // namespace Core::HID 23} // namespace Core::HID
24 24
25namespace Service::HID { 25namespace Service::HID {
26class Controller_Palma final : public ControllerBase { 26class Palma final : public ControllerBase {
27public: 27public:
28 using PalmaOperationData = std::array<u8, 0x140>; 28 using PalmaOperationData = std::array<u8, 0x140>;
29 29
@@ -97,9 +97,9 @@ public:
97 static_assert(sizeof(PalmaConnectionHandle) == 0x8, 97 static_assert(sizeof(PalmaConnectionHandle) == 0x8,
98 "PalmaConnectionHandle has incorrect size."); 98 "PalmaConnectionHandle has incorrect size.");
99 99
100 explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 100 explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
101 KernelHelpers::ServiceContext& service_context_); 101 KernelHelpers::ServiceContext& service_context_);
102 ~Controller_Palma() override; 102 ~Palma() override;
103 103
104 // Called when the controller is initialized 104 // Called when the controller is initialized
105 void OnInit() override; 105 void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/seven_six_axis.cpp
index bcb272eaf..495568484 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/seven_six_axis.cpp
@@ -1,32 +1,29 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include <cstring>
5#include "common/common_types.h"
4#include "core/core.h" 6#include "core/core.h"
5#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/frontend/emu_window.h"
6#include "core/hid/emulated_console.h" 9#include "core/hid/emulated_console.h"
10#include "core/hid/emulated_devices.h"
7#include "core/hid/hid_core.h" 11#include "core/hid/hid_core.h"
8#include "core/hle/service/hid/controllers/console_sixaxis.h" 12#include "core/hle/service/hid/controllers/seven_six_axis.h"
9#include "core/memory.h" 13#include "core/memory.h"
10 14
11namespace Service::HID { 15namespace Service::HID {
12constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; 16SevenSixAxis::SevenSixAxis(Core::System& system_)
13
14Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_)
15 : ControllerBase{system_.HIDCore()}, system{system_} { 17 : ControllerBase{system_.HIDCore()}, system{system_} {
16 console = hid_core.GetEmulatedConsole(); 18 console = hid_core.GetEmulatedConsole();
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
18 "ConsoleSharedMemory is bigger than the shared memory");
19 shared_memory = std::construct_at(
20 reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
21} 19}
22 20
23Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default; 21SevenSixAxis::~SevenSixAxis() = default;
24
25void Controller_ConsoleSixAxis::OnInit() {}
26 22
27void Controller_ConsoleSixAxis::OnRelease() {} 23void SevenSixAxis::OnInit() {}
24void SevenSixAxis::OnRelease() {}
28 25
29void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 26void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
30 if (!IsControllerActivated() || transfer_memory == 0) { 27 if (!IsControllerActivated() || transfer_memory == 0) {
31 seven_sixaxis_lifo.buffer_count = 0; 28 seven_sixaxis_lifo.buffer_count = 0;
32 seven_sixaxis_lifo.buffer_tail = 0; 29 seven_sixaxis_lifo.buffer_tail = 0;
@@ -53,22 +50,17 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
53 -motion_status.quaternion.xyz.z, 50 -motion_status.quaternion.xyz.z,
54 }; 51 };
55 52
56 shared_memory->sampling_number++;
57 shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
58 shared_memory->verticalization_error = motion_status.verticalization_error;
59 shared_memory->gyro_bias = motion_status.gyro_bias;
60
61 // Update seven six axis transfer memory
62 seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); 53 seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
63 system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, 54 system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo,
64 sizeof(seven_sixaxis_lifo)); 55 sizeof(seven_sixaxis_lifo));
65} 56}
66 57
67void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { 58void SevenSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
68 transfer_memory = t_mem; 59 transfer_memory = t_mem;
69} 60}
70 61
71void Controller_ConsoleSixAxis::ResetTimestamp() { 62void SevenSixAxis::ResetTimestamp() {
72 last_saved_timestamp = last_global_timestamp; 63 last_saved_timestamp = last_global_timestamp;
73} 64}
65
74} // namespace Service::HID 66} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/seven_six_axis.h
index 7015d924c..40e3f5d12 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/seven_six_axis.h
@@ -1,10 +1,9 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#pragma once 4#pragma once
5 5
6#include <array> 6#include "common/common_types.h"
7
8#include "common/quaternion.h" 7#include "common/quaternion.h"
9#include "common/typed_address.h" 8#include "common/typed_address.h"
10#include "core/hle/service/hid/controllers/controller_base.h" 9#include "core/hle/service/hid/controllers/controller_base.h"
@@ -19,10 +18,10 @@ class EmulatedConsole;
19} // namespace Core::HID 18} // namespace Core::HID
20 19
21namespace Service::HID { 20namespace Service::HID {
22class Controller_ConsoleSixAxis final : public ControllerBase { 21class SevenSixAxis final : public ControllerBase {
23public: 22public:
24 explicit Controller_ConsoleSixAxis(Core::System& system_, u8* raw_shared_memory_); 23 explicit SevenSixAxis(Core::System& system_);
25 ~Controller_ConsoleSixAxis() override; 24 ~SevenSixAxis() override;
26 25
27 // Called when the controller is initialized 26 // Called when the controller is initialized
28 void OnInit() override; 27 void OnInit() override;
@@ -51,28 +50,16 @@ private:
51 }; 50 };
52 static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size"); 51 static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size");
53 52
54 // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
55 struct ConsoleSharedMemory {
56 u64 sampling_number{};
57 bool is_seven_six_axis_sensor_at_rest{};
58 INSERT_PADDING_BYTES(3); // padding
59 f32 verticalization_error{};
60 Common::Vec3f gyro_bias{};
61 INSERT_PADDING_BYTES(4); // padding
62 };
63 static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
64
65 Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; 53 Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
66 static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); 54 static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
67 55
56 u64 last_saved_timestamp{};
57 u64 last_global_timestamp{};
58
68 SevenSixAxisState next_seven_sixaxis_state{}; 59 SevenSixAxisState next_seven_sixaxis_state{};
69 Common::ProcessAddress transfer_memory{}; 60 Common::ProcessAddress transfer_memory{};
70 ConsoleSharedMemory* shared_memory = nullptr;
71 Core::HID::EmulatedConsole* console = nullptr; 61 Core::HID::EmulatedConsole* console = nullptr;
72 62
73 u64 last_saved_timestamp{};
74 u64 last_global_timestamp{};
75
76 Core::System& system; 63 Core::System& system;
77}; 64};
78} // namespace Service::HID 65} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp
new file mode 100644
index 000000000..3d24a5c04
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/six_axis.cpp
@@ -0,0 +1,413 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "common/common_types.h"
5#include "core/core_timing.h"
6#include "core/hid/emulated_controller.h"
7#include "core/hid/hid_core.h"
8#include "core/hle/service/hid/controllers/npad.h"
9#include "core/hle/service/hid/controllers/six_axis.h"
10#include "core/hle/service/hid/errors.h"
11#include "core/hle/service/hid/hid_util.h"
12
13namespace Service::HID {
14
15SixAxis::SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_)
16 : ControllerBase{hid_core_}, npad{npad_} {
17 for (std::size_t i = 0; i < controller_data.size(); ++i) {
18 auto& controller = controller_data[i];
19 controller.device = hid_core.GetEmulatedControllerByIndex(i);
20 }
21}
22
23SixAxis::~SixAxis() = default;
24
25void SixAxis::OnInit() {}
26void SixAxis::OnRelease() {}
27
28void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
29 if (!IsControllerActivated()) {
30 return;
31 }
32
33 for (std::size_t i = 0; i < controller_data.size(); ++i) {
34 auto& controller = controller_data[i];
35
36 const auto npad_id = IndexToNpadIdType(i);
37 const auto& controller_type = controller.device->GetNpadStyleIndex();
38
39 if (controller_type == Core::HID::NpadStyleIndex::None ||
40 !controller.device->IsConnected()) {
41 continue;
42 }
43
44 const auto& motion_state = controller.device->GetMotions();
45 auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
46 auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
47 auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
48 auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
49 auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
50 auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
51
52 auto& sixaxis_fullkey_lifo = npad->GetSixAxisFullkeyLifo(npad_id);
53 auto& sixaxis_handheld_lifo = npad->GetSixAxisHandheldLifo(npad_id);
54 auto& sixaxis_dual_left_lifo = npad->GetSixAxisDualLeftLifo(npad_id);
55 auto& sixaxis_dual_right_lifo = npad->GetSixAxisDualRightLifo(npad_id);
56 auto& sixaxis_left_lifo = npad->GetSixAxisLeftLifo(npad_id);
57 auto& sixaxis_right_lifo = npad->GetSixAxisRightLifo(npad_id);
58
59 // Clear previous state
60 sixaxis_fullkey_state = {};
61 sixaxis_handheld_state = {};
62 sixaxis_dual_left_state = {};
63 sixaxis_dual_right_state = {};
64 sixaxis_left_lifo_state = {};
65 sixaxis_right_lifo_state = {};
66
67 if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
68 controller.sixaxis_at_rest = true;
69 for (std::size_t e = 0; e < motion_state.size(); ++e) {
70 controller.sixaxis_at_rest =
71 controller.sixaxis_at_rest && motion_state[e].is_at_rest;
72 }
73 }
74
75 const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state,
76 const Core::HID::ControllerMotion& hid_state) {
77 using namespace std::literals::chrono_literals;
78 static constexpr Core::HID::SixAxisSensorState default_motion_state = {
79 .delta_time = std::chrono::nanoseconds(5ms).count(),
80 .accel = {0, 0, -1.0f},
81 .orientation =
82 {
83 Common::Vec3f{1.0f, 0, 0},
84 Common::Vec3f{0, 1.0f, 0},
85 Common::Vec3f{0, 0, 1.0f},
86 },
87 .attribute = {1},
88 };
89 if (!controller.sixaxis_sensor_enabled) {
90 state = default_motion_state;
91 return;
92 }
93 if (!Settings::values.motion_enabled.GetValue()) {
94 state = default_motion_state;
95 return;
96 }
97 state.attribute.is_connected.Assign(1);
98 state.delta_time = std::chrono::nanoseconds(5ms).count();
99 state.accel = hid_state.accel;
100 state.gyro = hid_state.gyro;
101 state.rotation = hid_state.rotation;
102 state.orientation = hid_state.orientation;
103 };
104
105 switch (controller_type) {
106 case Core::HID::NpadStyleIndex::None:
107 ASSERT(false);
108 break;
109 case Core::HID::NpadStyleIndex::ProController:
110 set_motion_state(sixaxis_fullkey_state, motion_state[0]);
111 break;
112 case Core::HID::NpadStyleIndex::Handheld:
113 set_motion_state(sixaxis_handheld_state, motion_state[0]);
114 break;
115 case Core::HID::NpadStyleIndex::JoyconDual:
116 set_motion_state(sixaxis_dual_left_state, motion_state[0]);
117 set_motion_state(sixaxis_dual_right_state, motion_state[1]);
118 break;
119 case Core::HID::NpadStyleIndex::JoyconLeft:
120 set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
121 break;
122 case Core::HID::NpadStyleIndex::JoyconRight:
123 set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
124 break;
125 case Core::HID::NpadStyleIndex::Pokeball:
126 using namespace std::literals::chrono_literals;
127 set_motion_state(sixaxis_fullkey_state, motion_state[0]);
128 sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
129 break;
130 default:
131 break;
132 }
133
134 sixaxis_fullkey_state.sampling_number =
135 sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
136 sixaxis_handheld_state.sampling_number =
137 sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
138 sixaxis_dual_left_state.sampling_number =
139 sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
140 sixaxis_dual_right_state.sampling_number =
141 sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
142 sixaxis_left_lifo_state.sampling_number =
143 sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
144 sixaxis_right_lifo_state.sampling_number =
145 sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
146
147 if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
148 // This buffer only is updated on handheld on HW
149 sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
150 } else {
151 // Handheld doesn't update this buffer on HW
152 sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
153 }
154
155 sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
156 sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
157 sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
158 sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
159 }
160}
161
162Result SixAxis::SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
163 Core::HID::GyroscopeZeroDriftMode drift_mode) {
164 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
165 if (is_valid.IsError()) {
166 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
167 return is_valid;
168 }
169
170 auto& sixaxis = GetSixaxisState(sixaxis_handle);
171 auto& controller = GetControllerFromHandle(sixaxis_handle);
172 sixaxis.gyroscope_zero_drift_mode = drift_mode;
173 controller.device->SetGyroscopeZeroDriftMode(drift_mode);
174
175 return ResultSuccess;
176}
177
178Result SixAxis::GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
179 Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
180 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
181 if (is_valid.IsError()) {
182 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
183 return is_valid;
184 }
185
186 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
187 drift_mode = sixaxis.gyroscope_zero_drift_mode;
188
189 return ResultSuccess;
190}
191
192Result SixAxis::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
193 bool& is_at_rest) const {
194 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
195 if (is_valid.IsError()) {
196 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
197 return is_valid;
198 }
199
200 const auto& controller = GetControllerFromHandle(sixaxis_handle);
201 is_at_rest = controller.sixaxis_at_rest;
202 return ResultSuccess;
203}
204
205Result SixAxis::LoadSixAxisSensorCalibrationParameter(
206 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
207 Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
208 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
209 if (is_valid.IsError()) {
210 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
211 return is_valid;
212 }
213
214 // TODO: Request this data to the controller. On error return 0xd8ca
215 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
216 calibration = sixaxis.calibration;
217 return ResultSuccess;
218}
219
220Result SixAxis::GetSixAxisSensorIcInformation(
221 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
222 Core::HID::SixAxisSensorIcInformation& ic_information) const {
223 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
224 if (is_valid.IsError()) {
225 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
226 return is_valid;
227 }
228
229 // TODO: Request this data to the controller. On error return 0xd8ca
230 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
231 ic_information = sixaxis.ic_information;
232 return ResultSuccess;
233}
234
235Result SixAxis::EnableSixAxisSensorUnalteredPassthrough(
236 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
237 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
238 if (is_valid.IsError()) {
239 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
240 return is_valid;
241 }
242
243 auto& sixaxis = GetSixaxisState(sixaxis_handle);
244 sixaxis.unaltered_passtrough = is_enabled;
245 return ResultSuccess;
246}
247
248Result SixAxis::IsSixAxisSensorUnalteredPassthroughEnabled(
249 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
250 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
251 if (is_valid.IsError()) {
252 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
253 return is_valid;
254 }
255
256 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
257 is_enabled = sixaxis.unaltered_passtrough;
258 return ResultSuccess;
259}
260
261Result SixAxis::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
262 bool sixaxis_status) {
263 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
264 if (is_valid.IsError()) {
265 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
266 return is_valid;
267 }
268
269 auto& controller = GetControllerFromHandle(sixaxis_handle);
270 controller.sixaxis_sensor_enabled = sixaxis_status;
271 return ResultSuccess;
272}
273
274Result SixAxis::IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
275 bool& is_fusion_enabled) const {
276 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
277 if (is_valid.IsError()) {
278 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
279 return is_valid;
280 }
281
282 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
283 is_fusion_enabled = sixaxis.is_fusion_enabled;
284
285 return ResultSuccess;
286}
287Result SixAxis::SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
288 bool is_fusion_enabled) {
289 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
290 if (is_valid.IsError()) {
291 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
292 return is_valid;
293 }
294
295 auto& sixaxis = GetSixaxisState(sixaxis_handle);
296 sixaxis.is_fusion_enabled = is_fusion_enabled;
297
298 return ResultSuccess;
299}
300
301Result SixAxis::SetSixAxisFusionParameters(
302 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
303 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
304 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
305 if (is_valid.IsError()) {
306 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
307 return is_valid;
308 }
309
310 const auto param1 = sixaxis_fusion_parameters.parameter1;
311 if (param1 < 0.0f || param1 > 1.0f) {
312 return InvalidSixAxisFusionRange;
313 }
314
315 auto& sixaxis = GetSixaxisState(sixaxis_handle);
316 sixaxis.fusion = sixaxis_fusion_parameters;
317
318 return ResultSuccess;
319}
320
321Result SixAxis::GetSixAxisFusionParameters(
322 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
323 Core::HID::SixAxisSensorFusionParameters& parameters) const {
324 const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
325 if (is_valid.IsError()) {
326 LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
327 return is_valid;
328 }
329
330 const auto& sixaxis = GetSixaxisState(sixaxis_handle);
331 parameters = sixaxis.fusion;
332
333 return ResultSuccess;
334}
335
336SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
337 const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
338 auto& controller = GetControllerFromHandle(sixaxis_handle);
339 switch (sixaxis_handle.npad_type) {
340 case Core::HID::NpadStyleIndex::ProController:
341 case Core::HID::NpadStyleIndex::Pokeball:
342 return controller.sixaxis_fullkey;
343 case Core::HID::NpadStyleIndex::Handheld:
344 return controller.sixaxis_handheld;
345 case Core::HID::NpadStyleIndex::JoyconDual:
346 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
347 return controller.sixaxis_dual_left;
348 }
349 return controller.sixaxis_dual_right;
350 case Core::HID::NpadStyleIndex::JoyconLeft:
351 return controller.sixaxis_left;
352 case Core::HID::NpadStyleIndex::JoyconRight:
353 return controller.sixaxis_right;
354 default:
355 return controller.sixaxis_unknown;
356 }
357}
358
359const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
360 const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
361 const auto& controller = GetControllerFromHandle(sixaxis_handle);
362 switch (sixaxis_handle.npad_type) {
363 case Core::HID::NpadStyleIndex::ProController:
364 case Core::HID::NpadStyleIndex::Pokeball:
365 return controller.sixaxis_fullkey;
366 case Core::HID::NpadStyleIndex::Handheld:
367 return controller.sixaxis_handheld;
368 case Core::HID::NpadStyleIndex::JoyconDual:
369 if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
370 return controller.sixaxis_dual_left;
371 }
372 return controller.sixaxis_dual_right;
373 case Core::HID::NpadStyleIndex::JoyconLeft:
374 return controller.sixaxis_left;
375 case Core::HID::NpadStyleIndex::JoyconRight:
376 return controller.sixaxis_right;
377 default:
378 return controller.sixaxis_unknown;
379 }
380}
381
382SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
383 const Core::HID::SixAxisSensorHandle& device_handle) {
384 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
385 return GetControllerFromNpadIdType(npad_id);
386}
387
388const SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
389 const Core::HID::SixAxisSensorHandle& device_handle) const {
390 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
391 return GetControllerFromNpadIdType(npad_id);
392}
393
394SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
395 if (!IsNpadIdValid(npad_id)) {
396 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
397 npad_id = Core::HID::NpadIdType::Player1;
398 }
399 const auto npad_index = NpadIdTypeToIndex(npad_id);
400 return controller_data[npad_index];
401}
402
403const SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(
404 Core::HID::NpadIdType npad_id) const {
405 if (!IsNpadIdValid(npad_id)) {
406 LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
407 npad_id = Core::HID::NpadIdType::Player1;
408 }
409 const auto npad_index = NpadIdTypeToIndex(npad_id);
410 return controller_data[npad_index];
411}
412
413} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.h b/src/core/hle/service/hid/controllers/six_axis.h
new file mode 100644
index 000000000..4c4f5dc7b
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/six_axis.h
@@ -0,0 +1,111 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/common_types.h"
7#include "core/hid/hid_types.h"
8#include "core/hle/service/hid/controllers/controller_base.h"
9#include "core/hle/service/hid/ring_lifo.h"
10
11namespace Core::HID {
12class EmulatedController;
13} // namespace Core::HID
14
15namespace Service::HID {
16class NPad;
17
18class SixAxis final : public ControllerBase {
19public:
20 explicit SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_);
21 ~SixAxis() override;
22
23 // Called when the controller is initialized
24 void OnInit() override;
25
26 // When the controller is released
27 void OnRelease() override;
28
29 // When the controller is requesting an update for the shared memory
30 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
31
32 Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
33 Core::HID::GyroscopeZeroDriftMode drift_mode);
34 Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
35 Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
36 Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
37 bool& is_at_rest) const;
38 Result EnableSixAxisSensorUnalteredPassthrough(
39 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
40 Result IsSixAxisSensorUnalteredPassthroughEnabled(
41 const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
42 Result LoadSixAxisSensorCalibrationParameter(
43 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
44 Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
45 Result GetSixAxisSensorIcInformation(
46 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
47 Core::HID::SixAxisSensorIcInformation& ic_information) const;
48 Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
49 bool sixaxis_status);
50 Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
51 bool& is_fusion_enabled) const;
52 Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
53 bool is_fusion_enabled);
54 Result SetSixAxisFusionParameters(
55 const Core::HID::SixAxisSensorHandle& sixaxis_handle,
56 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
57 Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
58 Core::HID::SixAxisSensorFusionParameters& parameters) const;
59
60private:
61 static constexpr std::size_t NPAD_COUNT = 10;
62
63 struct SixaxisParameters {
64 bool is_fusion_enabled{true};
65 bool unaltered_passtrough{false};
66 Core::HID::SixAxisSensorFusionParameters fusion{};
67 Core::HID::SixAxisSensorCalibrationParameter calibration{};
68 Core::HID::SixAxisSensorIcInformation ic_information{};
69 Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
70 Core::HID::GyroscopeZeroDriftMode::Standard};
71 };
72
73 struct NpadControllerData {
74 Core::HID::EmulatedController* device = nullptr;
75
76 // Motion parameters
77 bool sixaxis_at_rest{true};
78 bool sixaxis_sensor_enabled{true};
79 SixaxisParameters sixaxis_fullkey{};
80 SixaxisParameters sixaxis_handheld{};
81 SixaxisParameters sixaxis_dual_left{};
82 SixaxisParameters sixaxis_dual_right{};
83 SixaxisParameters sixaxis_left{};
84 SixaxisParameters sixaxis_right{};
85 SixaxisParameters sixaxis_unknown{};
86
87 // Current pad state
88 Core::HID::SixAxisSensorState sixaxis_fullkey_state{};
89 Core::HID::SixAxisSensorState sixaxis_handheld_state{};
90 Core::HID::SixAxisSensorState sixaxis_dual_left_state{};
91 Core::HID::SixAxisSensorState sixaxis_dual_right_state{};
92 Core::HID::SixAxisSensorState sixaxis_left_lifo_state{};
93 Core::HID::SixAxisSensorState sixaxis_right_lifo_state{};
94 int callback_key{};
95 };
96
97 SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
98 const SixaxisParameters& GetSixaxisState(
99 const Core::HID::SixAxisSensorHandle& device_handle) const;
100
101 NpadControllerData& GetControllerFromHandle(
102 const Core::HID::SixAxisSensorHandle& device_handle);
103 const NpadControllerData& GetControllerFromHandle(
104 const Core::HID::SixAxisSensorHandle& device_handle) const;
105 NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
106 const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
107
108 std::shared_ptr<NPad> npad;
109 std::array<NpadControllerData, NPAD_COUNT> controller_data{};
110};
111} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 3ef91df4b..3bcf0ee9f 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -15,8 +15,7 @@
15namespace Service::HID { 15namespace Service::HID {
16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; 16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
17 17
18Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_, 18TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
19 u8* raw_shared_memory_)
20 : ControllerBase{hid_core_} { 19 : ControllerBase{hid_core_} {
21 static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, 20 static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size,
22 "TouchSharedMemory is bigger than the shared memory"); 21 "TouchSharedMemory is bigger than the shared memory");
@@ -25,13 +24,13 @@ Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_,
25 console = hid_core.GetEmulatedConsole(); 24 console = hid_core.GetEmulatedConsole();
26} 25}
27 26
28Controller_Touchscreen::~Controller_Touchscreen() = default; 27TouchScreen::~TouchScreen() = default;
29 28
30void Controller_Touchscreen::OnInit() {} 29void TouchScreen::OnInit() {}
31 30
32void Controller_Touchscreen::OnRelease() {} 31void TouchScreen::OnRelease() {}
33 32
34void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 33void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
35 shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); 34 shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
36 35
37 if (!IsControllerActivated()) { 36 if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index dd00921fd..cd342ce91 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -14,10 +14,10 @@ class EmulatedConsole;
14} // namespace Core::HID 14} // namespace Core::HID
15 15
16namespace Service::HID { 16namespace Service::HID {
17class Controller_Touchscreen final : public ControllerBase { 17class TouchScreen final : public ControllerBase {
18public: 18public:
19 explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 19 explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
20 ~Controller_Touchscreen() override; 20 ~TouchScreen() override;
21 21
22 // Called when the controller is initialized 22 // Called when the controller is initialized
23 void OnInit() override; 23 void OnInit() override;
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
index 62119e2c5..0aaed1fa7 100644
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ b/src/core/hle/service/hid/controllers/xpad.cpp
@@ -10,20 +10,19 @@
10namespace Service::HID { 10namespace Service::HID {
11constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; 11constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
12 12
13Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 13XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
14 : ControllerBase{hid_core_} {
15 static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, 14 static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size,
16 "XpadSharedMemory is bigger than the shared memory"); 15 "XpadSharedMemory is bigger than the shared memory");
17 shared_memory = std::construct_at( 16 shared_memory = std::construct_at(
18 reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); 17 reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
19} 18}
20Controller_XPad::~Controller_XPad() = default; 19XPad::~XPad() = default;
21 20
22void Controller_XPad::OnInit() {} 21void XPad::OnInit() {}
23 22
24void Controller_XPad::OnRelease() {} 23void XPad::OnRelease() {}
25 24
26void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 25void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
27 if (!IsControllerActivated()) { 26 if (!IsControllerActivated()) {
28 shared_memory->basic_xpad_lifo.buffer_count = 0; 27 shared_memory->basic_xpad_lifo.buffer_count = 0;
29 shared_memory->basic_xpad_lifo.buffer_tail = 0; 28 shared_memory->basic_xpad_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h
index d01dee5fc..9e63a317a 100644
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ b/src/core/hle/service/hid/controllers/xpad.h
@@ -10,10 +10,10 @@
10#include "core/hle/service/hid/ring_lifo.h" 10#include "core/hle/service/hid/ring_lifo.h"
11 11
12namespace Service::HID { 12namespace Service::HID {
13class Controller_XPad final : public ControllerBase { 13class XPad final : public ControllerBase {
14public: 14public:
15 explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 15 explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
16 ~Controller_XPad() override; 16 ~XPad() override;
17 17
18 // Called when the controller is initialized 18 // Called when the controller is initialized
19 void OnInit() override; 19 void OnInit() override;
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 9caed6541..583142e35 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -12,11 +12,12 @@
12#include "core/hle/service/hid/errors.h" 12#include "core/hle/service/hid/errors.h"
13#include "core/hle/service/hid/hid_firmware_settings.h" 13#include "core/hle/service/hid/hid_firmware_settings.h"
14#include "core/hle/service/hid/hid_server.h" 14#include "core/hle/service/hid/hid_server.h"
15#include "core/hle/service/hid/hid_util.h"
15#include "core/hle/service/hid/resource_manager.h" 16#include "core/hle/service/hid/resource_manager.h"
16#include "core/hle/service/ipc_helpers.h" 17#include "core/hle/service/ipc_helpers.h"
17#include "core/memory.h" 18#include "core/memory.h"
18 19
19#include "core/hle/service/hid/controllers/console_sixaxis.h" 20#include "core/hle/service/hid/controllers/console_six_axis.h"
20#include "core/hle/service/hid/controllers/controller_base.h" 21#include "core/hle/service/hid/controllers/controller_base.h"
21#include "core/hle/service/hid/controllers/debug_pad.h" 22#include "core/hle/service/hid/controllers/debug_pad.h"
22#include "core/hle/service/hid/controllers/gesture.h" 23#include "core/hle/service/hid/controllers/gesture.h"
@@ -24,9 +25,9 @@
24#include "core/hle/service/hid/controllers/mouse.h" 25#include "core/hle/service/hid/controllers/mouse.h"
25#include "core/hle/service/hid/controllers/npad.h" 26#include "core/hle/service/hid/controllers/npad.h"
26#include "core/hle/service/hid/controllers/palma.h" 27#include "core/hle/service/hid/controllers/palma.h"
27#include "core/hle/service/hid/controllers/stubbed.h" 28#include "core/hle/service/hid/controllers/seven_six_axis.h"
29#include "core/hle/service/hid/controllers/six_axis.h"
28#include "core/hle/service/hid/controllers/touchscreen.h" 30#include "core/hle/service/hid/controllers/touchscreen.h"
29#include "core/hle/service/hid/controllers/xpad.h"
30 31
31namespace Service::HID { 32namespace Service::HID {
32 33
@@ -50,8 +51,7 @@ private:
50 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; 51 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
51 52
52 if (resource_manager != nullptr) { 53 if (resource_manager != nullptr) {
53 resource_manager->GetController<Controller_NPad>(HidController::NPad) 54 resource_manager->GetNpad()->InitializeVibrationDevice(vibration_device_handle);
54 .InitializeVibrationDevice(vibration_device_handle);
55 } 55 }
56 56
57 LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}", 57 LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
@@ -235,15 +235,14 @@ void IHidServer::ActivateDebugPad(HLERequestContext& ctx) {
235 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 235 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
236 236
237 Result result = ResultSuccess; 237 Result result = ResultSuccess;
238 auto& debug_pad = 238 auto debug_pad = GetResourceManager()->GetDebugPad();
239 GetResourceManager()->GetController<Controller_DebugPad>(HidController::DebugPad);
240 239
241 if (!firmware_settings->IsDeviceManaged()) { 240 if (!firmware_settings->IsDeviceManaged()) {
242 result = debug_pad.Activate(); 241 result = debug_pad->Activate();
243 } 242 }
244 243
245 if (result.IsSuccess()) { 244 if (result.IsSuccess()) {
246 result = debug_pad.Activate(applet_resource_user_id); 245 result = debug_pad->Activate(applet_resource_user_id);
247 } 246 }
248 247
249 IPC::ResponseBuilder rb{ctx, 2}; 248 IPC::ResponseBuilder rb{ctx, 2};
@@ -257,15 +256,14 @@ void IHidServer::ActivateTouchScreen(HLERequestContext& ctx) {
257 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 256 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
258 257
259 Result result = ResultSuccess; 258 Result result = ResultSuccess;
260 auto& touch_screen = 259 auto touch_screen = GetResourceManager()->GetTouchScreen();
261 GetResourceManager()->GetController<Controller_Touchscreen>(HidController::Touchscreen);
262 260
263 if (!firmware_settings->IsDeviceManaged()) { 261 if (!firmware_settings->IsDeviceManaged()) {
264 result = touch_screen.Activate(); 262 result = touch_screen->Activate();
265 } 263 }
266 264
267 if (result.IsSuccess()) { 265 if (result.IsSuccess()) {
268 result = touch_screen.Activate(applet_resource_user_id); 266 result = touch_screen->Activate(applet_resource_user_id);
269 } 267 }
270 268
271 IPC::ResponseBuilder rb{ctx, 2}; 269 IPC::ResponseBuilder rb{ctx, 2};
@@ -279,14 +277,14 @@ void IHidServer::ActivateMouse(HLERequestContext& ctx) {
279 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 277 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
280 278
281 Result result = ResultSuccess; 279 Result result = ResultSuccess;
282 auto& mouse = GetResourceManager()->GetController<Controller_Mouse>(HidController::Mouse); 280 auto mouse = GetResourceManager()->GetMouse();
283 281
284 if (!firmware_settings->IsDeviceManaged()) { 282 if (!firmware_settings->IsDeviceManaged()) {
285 result = mouse.Activate(); 283 result = mouse->Activate();
286 } 284 }
287 285
288 if (result.IsSuccess()) { 286 if (result.IsSuccess()) {
289 result = mouse.Activate(applet_resource_user_id); 287 result = mouse->Activate(applet_resource_user_id);
290 } 288 }
291 289
292 IPC::ResponseBuilder rb{ctx, 2}; 290 IPC::ResponseBuilder rb{ctx, 2};
@@ -300,15 +298,14 @@ void IHidServer::ActivateKeyboard(HLERequestContext& ctx) {
300 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 298 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
301 299
302 Result result = ResultSuccess; 300 Result result = ResultSuccess;
303 auto& keyboard = 301 auto keyboard = GetResourceManager()->GetKeyboard();
304 GetResourceManager()->GetController<Controller_Keyboard>(HidController::Keyboard);
305 302
306 if (!firmware_settings->IsDeviceManaged()) { 303 if (!firmware_settings->IsDeviceManaged()) {
307 result = keyboard.Activate(); 304 result = keyboard->Activate();
308 } 305 }
309 306
310 if (result.IsSuccess()) { 307 if (result.IsSuccess()) {
311 result = keyboard.Activate(applet_resource_user_id); 308 result = keyboard->Activate(applet_resource_user_id);
312 } 309 }
313 310
314 IPC::ResponseBuilder rb{ctx, 2}; 311 IPC::ResponseBuilder rb{ctx, 2};
@@ -502,8 +499,8 @@ void IHidServer::StartSixAxisSensor(HLERequestContext& ctx) {
502 499
503 const auto parameters{rp.PopRaw<Parameters>()}; 500 const auto parameters{rp.PopRaw<Parameters>()};
504 501
505 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 502 auto six_axis = GetResourceManager()->GetSixAxis();
506 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true); 503 const auto result = six_axis->SetSixAxisEnabled(parameters.sixaxis_handle, true);
507 504
508 LOG_DEBUG(Service_HID, 505 LOG_DEBUG(Service_HID,
509 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 506 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -525,8 +522,8 @@ void IHidServer::StopSixAxisSensor(HLERequestContext& ctx) {
525 522
526 const auto parameters{rp.PopRaw<Parameters>()}; 523 const auto parameters{rp.PopRaw<Parameters>()};
527 524
528 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 525 auto six_axis = GetResourceManager()->GetSixAxis();
529 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false); 526 const auto result = six_axis->SetSixAxisEnabled(parameters.sixaxis_handle, false);
530 527
531 LOG_DEBUG(Service_HID, 528 LOG_DEBUG(Service_HID,
532 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 529 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -549,9 +546,9 @@ void IHidServer::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) {
549 const auto parameters{rp.PopRaw<Parameters>()}; 546 const auto parameters{rp.PopRaw<Parameters>()};
550 547
551 bool is_enabled{}; 548 bool is_enabled{};
552 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 549 auto six_axis = GetResourceManager()->GetSixAxis();
553 const auto result = 550 const auto result =
554 controller.IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled); 551 six_axis->IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled);
555 552
556 LOG_DEBUG(Service_HID, 553 LOG_DEBUG(Service_HID,
557 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 554 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -575,9 +572,9 @@ void IHidServer::EnableSixAxisSensorFusion(HLERequestContext& ctx) {
575 572
576 const auto parameters{rp.PopRaw<Parameters>()}; 573 const auto parameters{rp.PopRaw<Parameters>()};
577 574
578 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 575 auto six_axis = GetResourceManager()->GetSixAxis();
579 const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, 576 const auto result = six_axis->SetSixAxisFusionEnabled(parameters.sixaxis_handle,
580 parameters.enable_sixaxis_sensor_fusion); 577 parameters.enable_sixaxis_sensor_fusion);
581 578
582 LOG_DEBUG(Service_HID, 579 LOG_DEBUG(Service_HID,
583 "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, " 580 "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
@@ -602,9 +599,9 @@ void IHidServer::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
602 599
603 const auto parameters{rp.PopRaw<Parameters>()}; 600 const auto parameters{rp.PopRaw<Parameters>()};
604 601
605 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 602 auto six_axis = GetResourceManager()->GetSixAxis();
606 const auto result = 603 const auto result =
607 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion); 604 six_axis->SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
608 605
609 LOG_DEBUG(Service_HID, 606 LOG_DEBUG(Service_HID,
610 "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, " 607 "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
@@ -629,10 +626,9 @@ void IHidServer::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
629 const auto parameters{rp.PopRaw<Parameters>()}; 626 const auto parameters{rp.PopRaw<Parameters>()};
630 627
631 Core::HID::SixAxisSensorFusionParameters fusion_parameters{}; 628 Core::HID::SixAxisSensorFusionParameters fusion_parameters{};
632 const auto& controller = 629 auto six_axis = GetResourceManager()->GetSixAxis();
633 GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
634 const auto result = 630 const auto result =
635 controller.GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); 631 six_axis->GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
636 632
637 LOG_DEBUG(Service_HID, 633 LOG_DEBUG(Service_HID,
638 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 634 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -660,10 +656,10 @@ void IHidServer::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
660 .parameter1 = 0.03f, 656 .parameter1 = 0.03f,
661 .parameter2 = 0.4f, 657 .parameter2 = 0.4f,
662 }; 658 };
663 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 659 auto six_axis = GetResourceManager()->GetSixAxis();
664 const auto result1 = 660 const auto result1 =
665 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); 661 six_axis->SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
666 const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true); 662 const auto result2 = six_axis->SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
667 663
668 LOG_DEBUG(Service_HID, 664 LOG_DEBUG(Service_HID,
669 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 665 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -684,8 +680,8 @@ void IHidServer::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
684 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()}; 680 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
685 const auto applet_resource_user_id{rp.Pop<u64>()}; 681 const auto applet_resource_user_id{rp.Pop<u64>()};
686 682
687 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 683 auto six_axis = GetResourceManager()->GetSixAxis();
688 const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode); 684 const auto result = six_axis->SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
689 685
690 LOG_DEBUG(Service_HID, 686 LOG_DEBUG(Service_HID,
691 "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, " 687 "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
@@ -709,8 +705,8 @@ void IHidServer::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
709 const auto parameters{rp.PopRaw<Parameters>()}; 705 const auto parameters{rp.PopRaw<Parameters>()};
710 706
711 auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; 707 auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
712 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 708 auto six_axis = GetResourceManager()->GetSixAxis();
713 const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); 709 const auto result = six_axis->GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
714 710
715 LOG_DEBUG(Service_HID, 711 LOG_DEBUG(Service_HID,
716 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 712 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -734,8 +730,8 @@ void IHidServer::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
734 const auto parameters{rp.PopRaw<Parameters>()}; 730 const auto parameters{rp.PopRaw<Parameters>()};
735 731
736 const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard}; 732 const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
737 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 733 auto six_axis = GetResourceManager()->GetSixAxis();
738 const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); 734 const auto result = six_axis->SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
739 735
740 LOG_DEBUG(Service_HID, 736 LOG_DEBUG(Service_HID,
741 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 737 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -758,8 +754,8 @@ void IHidServer::IsSixAxisSensorAtRest(HLERequestContext& ctx) {
758 const auto parameters{rp.PopRaw<Parameters>()}; 754 const auto parameters{rp.PopRaw<Parameters>()};
759 755
760 bool is_at_rest{}; 756 bool is_at_rest{};
761 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 757 auto six_axis = GetResourceManager()->GetSixAxis();
762 controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest); 758 six_axis->IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
763 759
764 LOG_DEBUG(Service_HID, 760 LOG_DEBUG(Service_HID,
765 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 761 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -783,9 +779,9 @@ void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ct
783 const auto parameters{rp.PopRaw<Parameters>()}; 779 const auto parameters{rp.PopRaw<Parameters>()};
784 780
785 bool is_firmware_available{}; 781 bool is_firmware_available{};
786 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 782 auto controller = GetResourceManager()->GetNpad();
787 controller.IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle, 783 controller->IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
788 is_firmware_available); 784 is_firmware_available);
789 785
790 LOG_WARNING( 786 LOG_WARNING(
791 Service_HID, 787 Service_HID,
@@ -809,9 +805,9 @@ void IHidServer::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx)
809 805
810 const auto parameters{rp.PopRaw<Parameters>()}; 806 const auto parameters{rp.PopRaw<Parameters>()};
811 807
812 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 808 auto six_axis = GetResourceManager()->GetSixAxis();
813 const auto result = controller.EnableSixAxisSensorUnalteredPassthrough( 809 const auto result = six_axis->EnableSixAxisSensorUnalteredPassthrough(parameters.sixaxis_handle,
814 parameters.sixaxis_handle, parameters.enabled); 810 parameters.enabled);
815 811
816 LOG_DEBUG(Service_HID, 812 LOG_DEBUG(Service_HID,
817 "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, " 813 "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, "
@@ -836,8 +832,8 @@ void IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& c
836 const auto parameters{rp.PopRaw<Parameters>()}; 832 const auto parameters{rp.PopRaw<Parameters>()};
837 833
838 bool is_unaltered_sisxaxis_enabled{}; 834 bool is_unaltered_sisxaxis_enabled{};
839 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 835 auto six_axis = GetResourceManager()->GetSixAxis();
840 const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled( 836 const auto result = six_axis->IsSixAxisSensorUnalteredPassthroughEnabled(
841 parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled); 837 parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled);
842 838
843 LOG_DEBUG( 839 LOG_DEBUG(
@@ -863,9 +859,9 @@ void IHidServer::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) {
863 const auto parameters{rp.PopRaw<Parameters>()}; 859 const auto parameters{rp.PopRaw<Parameters>()};
864 860
865 Core::HID::SixAxisSensorCalibrationParameter calibration{}; 861 Core::HID::SixAxisSensorCalibrationParameter calibration{};
866 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 862 auto six_axis = GetResourceManager()->GetSixAxis();
867 const auto result = 863 const auto result =
868 controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration); 864 six_axis->LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration);
869 865
870 LOG_WARNING( 866 LOG_WARNING(
871 Service_HID, 867 Service_HID,
@@ -893,9 +889,9 @@ void IHidServer::GetSixAxisSensorIcInformation(HLERequestContext& ctx) {
893 const auto parameters{rp.PopRaw<Parameters>()}; 889 const auto parameters{rp.PopRaw<Parameters>()};
894 890
895 Core::HID::SixAxisSensorIcInformation ic_information{}; 891 Core::HID::SixAxisSensorIcInformation ic_information{};
896 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 892 auto six_axis = GetResourceManager()->GetSixAxis();
897 const auto result = 893 const auto result =
898 controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information); 894 six_axis->GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information);
899 895
900 LOG_WARNING( 896 LOG_WARNING(
901 Service_HID, 897 Service_HID,
@@ -922,9 +918,9 @@ void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx)
922 918
923 const auto parameters{rp.PopRaw<Parameters>()}; 919 const auto parameters{rp.PopRaw<Parameters>()};
924 920
925 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 921 auto controller = GetResourceManager()->GetNpad();
926 const auto result = 922 const auto result =
927 controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle); 923 controller->ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
928 924
929 LOG_WARNING( 925 LOG_WARNING(
930 Service_HID, 926 Service_HID,
@@ -951,15 +947,15 @@ void IHidServer::ActivateGesture(HLERequestContext& ctx) {
951 parameters.basic_gesture_id, parameters.applet_resource_user_id); 947 parameters.basic_gesture_id, parameters.applet_resource_user_id);
952 948
953 Result result = ResultSuccess; 949 Result result = ResultSuccess;
954 auto& gesture = GetResourceManager()->GetController<Controller_Gesture>(HidController::Gesture); 950 auto gesture = GetResourceManager()->GetGesture();
955 951
956 if (!firmware_settings->IsDeviceManaged()) { 952 if (!firmware_settings->IsDeviceManaged()) {
957 result = gesture.Activate(); 953 result = gesture->Activate();
958 } 954 }
959 955
960 if (result.IsSuccess()) { 956 if (result.IsSuccess()) {
961 // TODO: Use gesture id here 957 // TODO: Use gesture id here
962 result = gesture.Activate(parameters.applet_resource_user_id); 958 result = gesture->Activate(parameters.applet_resource_user_id);
963 } 959 }
964 960
965 IPC::ResponseBuilder rb{ctx, 2}; 961 IPC::ResponseBuilder rb{ctx, 2};
@@ -977,9 +973,7 @@ void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
977 973
978 const auto parameters{rp.PopRaw<Parameters>()}; 974 const auto parameters{rp.PopRaw<Parameters>()};
979 975
980 GetResourceManager() 976 GetResourceManager()->GetNpad()->SetSupportedStyleSet({parameters.supported_styleset});
981 ->GetController<Controller_NPad>(HidController::NPad)
982 .SetSupportedStyleSet({parameters.supported_styleset});
983 977
984 LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}", 978 LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
985 parameters.supported_styleset, parameters.applet_resource_user_id); 979 parameters.supported_styleset, parameters.applet_resource_user_id);
@@ -996,19 +990,14 @@ void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
996 990
997 IPC::ResponseBuilder rb{ctx, 3}; 991 IPC::ResponseBuilder rb{ctx, 3};
998 rb.Push(ResultSuccess); 992 rb.Push(ResultSuccess);
999 rb.PushEnum(GetResourceManager() 993 rb.PushEnum(GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw);
1000 ->GetController<Controller_NPad>(HidController::NPad)
1001 .GetSupportedStyleSet()
1002 .raw);
1003} 994}
1004 995
1005void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) { 996void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) {
1006 IPC::RequestParser rp{ctx}; 997 IPC::RequestParser rp{ctx};
1007 const auto applet_resource_user_id{rp.Pop<u64>()}; 998 const auto applet_resource_user_id{rp.Pop<u64>()};
1008 999
1009 const auto result = GetResourceManager() 1000 const auto result = GetResourceManager()->GetNpad()->SetSupportedNpadIdTypes(ctx.ReadBuffer());
1010 ->GetController<Controller_NPad>(HidController::NPad)
1011 .SetSupportedNpadIdTypes(ctx.ReadBuffer());
1012 1001
1013 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1002 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1014 1003
@@ -1022,10 +1011,10 @@ void IHidServer::ActivateNpad(HLERequestContext& ctx) {
1022 1011
1023 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1012 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1024 1013
1025 auto& npad = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1014 auto npad = GetResourceManager()->GetNpad();
1026 1015
1027 // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0); 1016 // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
1028 const Result result = npad.Activate(applet_resource_user_id); 1017 const Result result = npad->Activate(applet_resource_user_id);
1029 1018
1030 IPC::ResponseBuilder rb{ctx, 2}; 1019 IPC::ResponseBuilder rb{ctx, 2};
1031 rb.Push(result); 1020 rb.Push(result);
@@ -1059,15 +1048,12 @@ void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
1059 parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown); 1048 parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
1060 1049
1061 // Games expect this event to be signaled after calling this function 1050 // Games expect this event to be signaled after calling this function
1062 GetResourceManager() 1051 GetResourceManager()->GetNpad()->SignalStyleSetChangedEvent(parameters.npad_id);
1063 ->GetController<Controller_NPad>(HidController::NPad)
1064 .SignalStyleSetChangedEvent(parameters.npad_id);
1065 1052
1066 IPC::ResponseBuilder rb{ctx, 2, 1}; 1053 IPC::ResponseBuilder rb{ctx, 2, 1};
1067 rb.Push(ResultSuccess); 1054 rb.Push(ResultSuccess);
1068 rb.PushCopyObjects(GetResourceManager() 1055 rb.PushCopyObjects(
1069 ->GetController<Controller_NPad>(HidController::NPad) 1056 GetResourceManager()->GetNpad()->GetStyleSetChangedEvent(parameters.npad_id));
1070 .GetStyleSetChangedEvent(parameters.npad_id));
1071} 1057}
1072 1058
1073void IHidServer::DisconnectNpad(HLERequestContext& ctx) { 1059void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
@@ -1081,8 +1067,8 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
1081 1067
1082 const auto parameters{rp.PopRaw<Parameters>()}; 1068 const auto parameters{rp.PopRaw<Parameters>()};
1083 1069
1084 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1070 auto controller = GetResourceManager()->GetNpad();
1085 controller.DisconnectNpad(parameters.npad_id); 1071 controller->DisconnectNpad(parameters.npad_id);
1086 1072
1087 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1073 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1088 parameters.applet_resource_user_id); 1074 parameters.applet_resource_user_id);
@@ -1096,8 +1082,8 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
1096 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; 1082 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
1097 1083
1098 Core::HID::LedPattern pattern{0, 0, 0, 0}; 1084 Core::HID::LedPattern pattern{0, 0, 0, 0};
1099 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1085 auto controller = GetResourceManager()->GetNpad();
1100 const auto result = controller.GetLedPattern(npad_id, pattern); 1086 const auto result = controller->GetLedPattern(npad_id, pattern);
1101 1087
1102 LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id); 1088 LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
1103 1089
@@ -1109,7 +1095,7 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
1109void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { 1095void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
1110 IPC::RequestParser rp{ctx}; 1096 IPC::RequestParser rp{ctx};
1111 struct Parameters { 1097 struct Parameters {
1112 Controller_NPad::NpadRevision revision; 1098 NPad::NpadRevision revision;
1113 INSERT_PADDING_WORDS_NOINIT(1); 1099 INSERT_PADDING_WORDS_NOINIT(1);
1114 u64 applet_resource_user_id; 1100 u64 applet_resource_user_id;
1115 }; 1101 };
@@ -1120,10 +1106,10 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
1120 LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision, 1106 LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
1121 parameters.applet_resource_user_id); 1107 parameters.applet_resource_user_id);
1122 1108
1123 auto& npad = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1109 auto npad = GetResourceManager()->GetNpad();
1124 1110
1125 // TODO: npad->SetRevision(applet_resource_user_id, revision); 1111 // TODO: npad->SetRevision(applet_resource_user_id, revision);
1126 const auto result = npad.Activate(parameters.applet_resource_user_id); 1112 const auto result = npad->Activate(parameters.applet_resource_user_id);
1127 1113
1128 IPC::ResponseBuilder rb{ctx, 2}; 1114 IPC::ResponseBuilder rb{ctx, 2};
1129 rb.Push(result); 1115 rb.Push(result);
@@ -1132,11 +1118,9 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
1132void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { 1118void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
1133 IPC::RequestParser rp{ctx}; 1119 IPC::RequestParser rp{ctx};
1134 const auto applet_resource_user_id{rp.Pop<u64>()}; 1120 const auto applet_resource_user_id{rp.Pop<u64>()};
1135 const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()}; 1121 const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()};
1136 1122
1137 GetResourceManager() 1123 GetResourceManager()->GetNpad()->SetHoldType(hold_type);
1138 ->GetController<Controller_NPad>(HidController::NPad)
1139 .SetHoldType(hold_type);
1140 1124
1141 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}", 1125 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
1142 applet_resource_user_id, hold_type); 1126 applet_resource_user_id, hold_type);
@@ -1153,8 +1137,7 @@ void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
1153 1137
1154 IPC::ResponseBuilder rb{ctx, 4}; 1138 IPC::ResponseBuilder rb{ctx, 4};
1155 rb.Push(ResultSuccess); 1139 rb.Push(ResultSuccess);
1156 rb.PushEnum( 1140 rb.PushEnum(GetResourceManager()->GetNpad()->GetHoldType());
1157 GetResourceManager()->GetController<Controller_NPad>(HidController::NPad).GetHoldType());
1158} 1141}
1159 1142
1160void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) { 1143void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
@@ -1169,10 +1152,9 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx)
1169 const auto parameters{rp.PopRaw<Parameters>()}; 1152 const auto parameters{rp.PopRaw<Parameters>()};
1170 1153
1171 Core::HID::NpadIdType new_npad_id{}; 1154 Core::HID::NpadIdType new_npad_id{};
1172 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1155 auto controller = GetResourceManager()->GetNpad();
1173 controller.SetNpadMode(new_npad_id, parameters.npad_id, 1156 controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left,
1174 Controller_NPad::NpadJoyDeviceType::Left, 1157 NPad::NpadJoyAssignmentMode::Single);
1175 Controller_NPad::NpadJoyAssignmentMode::Single);
1176 1158
1177 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1159 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1178 parameters.applet_resource_user_id); 1160 parameters.applet_resource_user_id);
@@ -1187,16 +1169,16 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1187 Core::HID::NpadIdType npad_id; 1169 Core::HID::NpadIdType npad_id;
1188 INSERT_PADDING_WORDS_NOINIT(1); 1170 INSERT_PADDING_WORDS_NOINIT(1);
1189 u64 applet_resource_user_id; 1171 u64 applet_resource_user_id;
1190 Controller_NPad::NpadJoyDeviceType npad_joy_device_type; 1172 NPad::NpadJoyDeviceType npad_joy_device_type;
1191 }; 1173 };
1192 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); 1174 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1193 1175
1194 const auto parameters{rp.PopRaw<Parameters>()}; 1176 const auto parameters{rp.PopRaw<Parameters>()};
1195 1177
1196 Core::HID::NpadIdType new_npad_id{}; 1178 Core::HID::NpadIdType new_npad_id{};
1197 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1179 auto controller = GetResourceManager()->GetNpad();
1198 controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, 1180 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1199 Controller_NPad::NpadJoyAssignmentMode::Single); 1181 NPad::NpadJoyAssignmentMode::Single);
1200 1182
1201 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", 1183 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1202 parameters.npad_id, parameters.applet_resource_user_id, 1184 parameters.npad_id, parameters.applet_resource_user_id,
@@ -1218,9 +1200,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
1218 const auto parameters{rp.PopRaw<Parameters>()}; 1200 const auto parameters{rp.PopRaw<Parameters>()};
1219 1201
1220 Core::HID::NpadIdType new_npad_id{}; 1202 Core::HID::NpadIdType new_npad_id{};
1221 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1203 auto controller = GetResourceManager()->GetNpad();
1222 controller.SetNpadMode(new_npad_id, parameters.npad_id, {}, 1204 controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual);
1223 Controller_NPad::NpadJoyAssignmentMode::Dual);
1224 1205
1225 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1206 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1226 parameters.applet_resource_user_id); // Spams a lot when controller applet is open 1207 parameters.applet_resource_user_id); // Spams a lot when controller applet is open
@@ -1235,8 +1216,8 @@ void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
1235 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; 1216 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1236 const auto applet_resource_user_id{rp.Pop<u64>()}; 1217 const auto applet_resource_user_id{rp.Pop<u64>()};
1237 1218
1238 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1219 auto controller = GetResourceManager()->GetNpad();
1239 const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); 1220 const auto result = controller->MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
1240 1221
1241 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", 1222 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1242 npad_id_1, npad_id_2, applet_resource_user_id); 1223 npad_id_1, npad_id_2, applet_resource_user_id);
@@ -1249,9 +1230,7 @@ void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) {
1249 IPC::RequestParser rp{ctx}; 1230 IPC::RequestParser rp{ctx};
1250 const auto applet_resource_user_id{rp.Pop<u64>()}; 1231 const auto applet_resource_user_id{rp.Pop<u64>()};
1251 1232
1252 GetResourceManager() 1233 GetResourceManager()->GetNpad()->StartLRAssignmentMode();
1253 ->GetController<Controller_NPad>(HidController::NPad)
1254 .StartLRAssignmentMode();
1255 1234
1256 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1235 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1257 1236
@@ -1263,9 +1242,7 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
1263 IPC::RequestParser rp{ctx}; 1242 IPC::RequestParser rp{ctx};
1264 const auto applet_resource_user_id{rp.Pop<u64>()}; 1243 const auto applet_resource_user_id{rp.Pop<u64>()};
1265 1244
1266 GetResourceManager() 1245 GetResourceManager()->GetNpad()->StopLRAssignmentMode();
1267 ->GetController<Controller_NPad>(HidController::NPad)
1268 .StopLRAssignmentMode();
1269 1246
1270 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1247 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1271 1248
@@ -1276,11 +1253,9 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
1276void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { 1253void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
1277 IPC::RequestParser rp{ctx}; 1254 IPC::RequestParser rp{ctx};
1278 const auto applet_resource_user_id{rp.Pop<u64>()}; 1255 const auto applet_resource_user_id{rp.Pop<u64>()};
1279 const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()}; 1256 const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()};
1280 1257
1281 GetResourceManager() 1258 GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode);
1282 ->GetController<Controller_NPad>(HidController::NPad)
1283 .SetNpadHandheldActivationMode(activation_mode);
1284 1259
1285 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}", 1260 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
1286 applet_resource_user_id, activation_mode); 1261 applet_resource_user_id, activation_mode);
@@ -1297,9 +1272,7 @@ void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
1297 1272
1298 IPC::ResponseBuilder rb{ctx, 4}; 1273 IPC::ResponseBuilder rb{ctx, 4};
1299 rb.Push(ResultSuccess); 1274 rb.Push(ResultSuccess);
1300 rb.PushEnum(GetResourceManager() 1275 rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadHandheldActivationMode());
1301 ->GetController<Controller_NPad>(HidController::NPad)
1302 .GetNpadHandheldActivationMode());
1303} 1276}
1304 1277
1305void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) { 1278void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
@@ -1308,8 +1281,8 @@ void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
1308 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()}; 1281 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1309 const auto applet_resource_user_id{rp.Pop<u64>()}; 1282 const auto applet_resource_user_id{rp.Pop<u64>()};
1310 1283
1311 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1284 auto controller = GetResourceManager()->GetNpad();
1312 const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2); 1285 const auto result = controller->SwapNpadAssignment(npad_id_1, npad_id_2);
1313 1286
1314 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", 1287 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1315 npad_id_1, npad_id_2, applet_resource_user_id); 1288 npad_id_1, npad_id_2, applet_resource_user_id);
@@ -1330,9 +1303,9 @@ void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext&
1330 const auto parameters{rp.PopRaw<Parameters>()}; 1303 const auto parameters{rp.PopRaw<Parameters>()};
1331 1304
1332 bool is_enabled = false; 1305 bool is_enabled = false;
1333 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1306 auto controller = GetResourceManager()->GetNpad();
1334 const auto result = 1307 const auto result =
1335 controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled); 1308 controller->IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
1336 1309
1337 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", 1310 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
1338 parameters.npad_id, parameters.applet_resource_user_id); 1311 parameters.npad_id, parameters.applet_resource_user_id);
@@ -1354,8 +1327,8 @@ void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ct
1354 1327
1355 const auto parameters{rp.PopRaw<Parameters>()}; 1328 const auto parameters{rp.PopRaw<Parameters>()};
1356 1329
1357 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1330 auto controller = GetResourceManager()->GetNpad();
1358 const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled( 1331 const auto result = controller->SetUnintendedHomeButtonInputProtectionEnabled(
1359 parameters.is_enabled, parameters.npad_id); 1332 parameters.is_enabled, parameters.npad_id);
1360 1333
1361 LOG_DEBUG(Service_HID, 1334 LOG_DEBUG(Service_HID,
@@ -1372,17 +1345,17 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
1372 Core::HID::NpadIdType npad_id; 1345 Core::HID::NpadIdType npad_id;
1373 INSERT_PADDING_WORDS_NOINIT(1); 1346 INSERT_PADDING_WORDS_NOINIT(1);
1374 u64 applet_resource_user_id; 1347 u64 applet_resource_user_id;
1375 Controller_NPad::NpadJoyDeviceType npad_joy_device_type; 1348 NPad::NpadJoyDeviceType npad_joy_device_type;
1376 }; 1349 };
1377 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); 1350 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1378 1351
1379 const auto parameters{rp.PopRaw<Parameters>()}; 1352 const auto parameters{rp.PopRaw<Parameters>()};
1380 1353
1381 Core::HID::NpadIdType new_npad_id{}; 1354 Core::HID::NpadIdType new_npad_id{};
1382 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad); 1355 auto controller = GetResourceManager()->GetNpad();
1383 const auto is_reassigned = 1356 const auto is_reassigned =
1384 controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, 1357 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1385 Controller_NPad::NpadJoyAssignmentMode::Single); 1358 NPad::NpadJoyAssignmentMode::Single);
1386 1359
1387 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", 1360 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1388 parameters.npad_id, parameters.applet_resource_user_id, 1361 parameters.npad_id, parameters.applet_resource_user_id,
@@ -1405,9 +1378,8 @@ void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
1405 1378
1406 const auto parameters{rp.PopRaw<Parameters>()}; 1379 const auto parameters{rp.PopRaw<Parameters>()};
1407 1380
1408 GetResourceManager() 1381 GetResourceManager()->GetNpad()->SetAnalogStickUseCenterClamp(
1409 ->GetController<Controller_NPad>(HidController::NPad) 1382 parameters.analog_stick_use_center_clamp);
1410 .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp);
1411 1383
1412 LOG_WARNING(Service_HID, 1384 LOG_WARNING(Service_HID,
1413 "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}", 1385 "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
@@ -1451,8 +1423,7 @@ void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1451void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) { 1423void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
1452 IPC::RequestParser rp{ctx}; 1424 IPC::RequestParser rp{ctx};
1453 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()}; 1425 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
1454 const auto& controller = 1426 const auto controller = GetResourceManager()->GetNpad();
1455 GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1456 1427
1457 Core::HID::VibrationDeviceInfo vibration_device_info; 1428 Core::HID::VibrationDeviceInfo vibration_device_info;
1458 bool check_device_index = false; 1429 bool check_device_index = false;
@@ -1496,7 +1467,7 @@ void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
1496 LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}", 1467 LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
1497 vibration_device_info.type, vibration_device_info.position); 1468 vibration_device_info.type, vibration_device_info.position);
1498 1469
1499 const auto result = controller.IsDeviceHandleValid(vibration_device_handle); 1470 const auto result = IsVibrationHandleValid(vibration_device_handle);
1500 if (result.IsError()) { 1471 if (result.IsError()) {
1501 IPC::ResponseBuilder rb{ctx, 2}; 1472 IPC::ResponseBuilder rb{ctx, 2};
1502 rb.Push(result); 1473 rb.Push(result);
@@ -1520,9 +1491,8 @@ void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
1520 1491
1521 const auto parameters{rp.PopRaw<Parameters>()}; 1492 const auto parameters{rp.PopRaw<Parameters>()};
1522 1493
1523 GetResourceManager() 1494 GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
1524 ->GetController<Controller_NPad>(HidController::NPad) 1495 parameters.vibration_value);
1525 .VibrateController(parameters.vibration_device_handle, parameters.vibration_value);
1526 1496
1527 LOG_DEBUG(Service_HID, 1497 LOG_DEBUG(Service_HID,
1528 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", 1498 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
@@ -1553,9 +1523,8 @@ void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
1553 1523
1554 IPC::ResponseBuilder rb{ctx, 6}; 1524 IPC::ResponseBuilder rb{ctx, 6};
1555 rb.Push(ResultSuccess); 1525 rb.Push(ResultSuccess);
1556 rb.PushRaw(GetResourceManager() 1526 rb.PushRaw(
1557 ->GetController<Controller_NPad>(HidController::NPad) 1527 GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle));
1558 .GetLastVibration(parameters.vibration_device_handle));
1559} 1528}
1560 1529
1561void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) { 1530void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
@@ -1606,9 +1575,7 @@ void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
1606 auto vibration_values = std::span( 1575 auto vibration_values = std::span(
1607 reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); 1576 reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
1608 1577
1609 GetResourceManager() 1578 GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values);
1610 ->GetController<Controller_NPad>(HidController::NPad)
1611 .VibrateControllers(vibration_device_handles, vibration_values);
1612 1579
1613 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1580 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1614 1581
@@ -1662,9 +1629,8 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
1662 } 1629 }
1663 }(); 1630 }();
1664 1631
1665 GetResourceManager() 1632 GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
1666 ->GetController<Controller_NPad>(HidController::NPad) 1633 vibration_value);
1667 .VibrateController(parameters.vibration_device_handle, vibration_value);
1668 1634
1669 LOG_DEBUG(Service_HID, 1635 LOG_DEBUG(Service_HID,
1670 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, " 1636 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
@@ -1688,9 +1654,8 @@ void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
1688 1654
1689 const auto parameters{rp.PopRaw<Parameters>()}; 1655 const auto parameters{rp.PopRaw<Parameters>()};
1690 1656
1691 const auto last_vibration = GetResourceManager() 1657 const auto last_vibration =
1692 ->GetController<Controller_NPad>(HidController::NPad) 1658 GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle);
1693 .GetLastVibration(parameters.vibration_device_handle);
1694 1659
1695 const auto gc_erm_command = [last_vibration] { 1660 const auto gc_erm_command = [last_vibration] {
1696 if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) { 1661 if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
@@ -1725,9 +1690,7 @@ void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) {
1725 IPC::RequestParser rp{ctx}; 1690 IPC::RequestParser rp{ctx};
1726 const auto applet_resource_user_id{rp.Pop<u64>()}; 1691 const auto applet_resource_user_id{rp.Pop<u64>()};
1727 1692
1728 GetResourceManager() 1693 GetResourceManager()->GetNpad()->SetPermitVibrationSession(true);
1729 ->GetController<Controller_NPad>(HidController::NPad)
1730 .SetPermitVibrationSession(true);
1731 1694
1732 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1695 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1733 1696
@@ -1736,9 +1699,7 @@ void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) {
1736} 1699}
1737 1700
1738void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) { 1701void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {
1739 GetResourceManager() 1702 GetResourceManager()->GetNpad()->SetPermitVibrationSession(false);
1740 ->GetController<Controller_NPad>(HidController::NPad)
1741 .SetPermitVibrationSession(false);
1742 1703
1743 LOG_DEBUG(Service_HID, "called"); 1704 LOG_DEBUG(Service_HID, "called");
1744 1705
@@ -1765,9 +1726,8 @@ void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
1765 1726
1766 IPC::ResponseBuilder rb{ctx, 3}; 1727 IPC::ResponseBuilder rb{ctx, 3};
1767 rb.Push(ResultSuccess); 1728 rb.Push(ResultSuccess);
1768 rb.Push(GetResourceManager() 1729 rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted(
1769 ->GetController<Controller_NPad>(HidController::NPad) 1730 parameters.vibration_device_handle));
1770 .IsVibrationDeviceMounted(parameters.vibration_device_handle));
1771} 1731}
1772 1732
1773void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) { 1733void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
@@ -1777,15 +1737,14 @@ void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
1777 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1737 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1778 1738
1779 Result result = ResultSuccess; 1739 Result result = ResultSuccess;
1780 auto console_sixaxis = GetResourceManager()->GetController<Controller_ConsoleSixAxis>( 1740 auto console_sixaxis = GetResourceManager()->GetConsoleSixAxis();
1781 HidController::ConsoleSixAxisSensor);
1782 1741
1783 if (!firmware_settings->IsDeviceManaged()) { 1742 if (!firmware_settings->IsDeviceManaged()) {
1784 result = console_sixaxis.Activate(); 1743 result = console_sixaxis->Activate();
1785 } 1744 }
1786 1745
1787 if (result.IsSuccess()) { 1746 if (result.IsSuccess()) {
1788 result = console_sixaxis.Activate(applet_resource_user_id); 1747 result = console_sixaxis->Activate(applet_resource_user_id);
1789 } 1748 }
1790 1749
1791 IPC::ResponseBuilder rb{ctx, 2}; 1750 IPC::ResponseBuilder rb{ctx, 2};
@@ -1839,15 +1798,14 @@ void IHidServer::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
1839 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1798 LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1840 1799
1841 Result result = ResultSuccess; 1800 Result result = ResultSuccess;
1842 auto console_sixaxis = GetResourceManager()->GetController<Controller_ConsoleSixAxis>( 1801 auto seven_sixaxis = GetResourceManager()->GetSevenSixAxis();
1843 HidController::ConsoleSixAxisSensor);
1844 1802
1845 if (!firmware_settings->IsDeviceManaged()) { 1803 if (!firmware_settings->IsDeviceManaged()) {
1846 result = console_sixaxis.Activate(); 1804 result = seven_sixaxis->Activate();
1847 } 1805 }
1848 1806
1849 if (result.IsSuccess()) { 1807 if (result.IsSuccess()) {
1850 console_sixaxis.Activate(applet_resource_user_id); 1808 seven_sixaxis->Activate(applet_resource_user_id);
1851 } 1809 }
1852 1810
1853 IPC::ResponseBuilder rb{ctx, 2}; 1811 IPC::ResponseBuilder rb{ctx, 2};
@@ -1911,13 +1869,10 @@ void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
1911 ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size"); 1869 ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size");
1912 1870
1913 // Activate console six axis controller 1871 // Activate console six axis controller
1914 GetResourceManager() 1872 GetResourceManager()->GetConsoleSixAxis()->Activate();
1915 ->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor) 1873 GetResourceManager()->GetSevenSixAxis()->Activate();
1916 .Activate();
1917 1874
1918 GetResourceManager() 1875 GetResourceManager()->GetSevenSixAxis()->SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
1919 ->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1920 .SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
1921 1876
1922 LOG_WARNING(Service_HID, 1877 LOG_WARNING(Service_HID,
1923 "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, " 1878 "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
@@ -1943,9 +1898,7 @@ void IHidServer::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) {
1943 IPC::RequestParser rp{ctx}; 1898 IPC::RequestParser rp{ctx};
1944 const auto applet_resource_user_id{rp.Pop<u64>()}; 1899 const auto applet_resource_user_id{rp.Pop<u64>()};
1945 1900
1946 GetResourceManager() 1901 GetResourceManager()->GetSevenSixAxis()->ResetTimestamp();
1947 ->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1948 .ResetTimestamp();
1949 1902
1950 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 1903 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1951 1904
@@ -1977,9 +1930,9 @@ void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) {
1977 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", 1930 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
1978 parameters.npad_id, parameters.applet_resource_user_id); 1931 parameters.npad_id, parameters.applet_resource_user_id);
1979 1932
1980 Controller_Palma::PalmaConnectionHandle handle; 1933 Palma::PalmaConnectionHandle handle;
1981 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 1934 auto controller = GetResourceManager()->GetPalma();
1982 const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle); 1935 const auto result = controller->GetPalmaConnectionHandle(parameters.npad_id, handle);
1983 1936
1984 IPC::ResponseBuilder rb{ctx, 4}; 1937 IPC::ResponseBuilder rb{ctx, 4};
1985 rb.Push(result); 1938 rb.Push(result);
@@ -1988,12 +1941,12 @@ void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) {
1988 1941
1989void IHidServer::InitializePalma(HLERequestContext& ctx) { 1942void IHidServer::InitializePalma(HLERequestContext& ctx) {
1990 IPC::RequestParser rp{ctx}; 1943 IPC::RequestParser rp{ctx};
1991 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1944 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
1992 1945
1993 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 1946 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1994 1947
1995 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 1948 auto controller = GetResourceManager()->GetPalma();
1996 const auto result = controller.InitializePalma(connection_handle); 1949 const auto result = controller->InitializePalma(connection_handle);
1997 1950
1998 IPC::ResponseBuilder rb{ctx, 2}; 1951 IPC::ResponseBuilder rb{ctx, 2};
1999 rb.Push(result); 1952 rb.Push(result);
@@ -2001,27 +1954,27 @@ void IHidServer::InitializePalma(HLERequestContext& ctx) {
2001 1954
2002void IHidServer::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) { 1955void IHidServer::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) {
2003 IPC::RequestParser rp{ctx}; 1956 IPC::RequestParser rp{ctx};
2004 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1957 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2005 1958
2006 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 1959 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2007 1960
2008 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 1961 auto controller = GetResourceManager()->GetPalma();
2009 1962
2010 IPC::ResponseBuilder rb{ctx, 2, 1}; 1963 IPC::ResponseBuilder rb{ctx, 2, 1};
2011 rb.Push(ResultSuccess); 1964 rb.Push(ResultSuccess);
2012 rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle)); 1965 rb.PushCopyObjects(controller->AcquirePalmaOperationCompleteEvent(connection_handle));
2013} 1966}
2014 1967
2015void IHidServer::GetPalmaOperationInfo(HLERequestContext& ctx) { 1968void IHidServer::GetPalmaOperationInfo(HLERequestContext& ctx) {
2016 IPC::RequestParser rp{ctx}; 1969 IPC::RequestParser rp{ctx};
2017 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1970 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2018 1971
2019 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 1972 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2020 1973
2021 Controller_Palma::PalmaOperationType operation_type; 1974 Palma::PalmaOperationType operation_type;
2022 Controller_Palma::PalmaOperationData data; 1975 Palma::PalmaOperationData data;
2023 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 1976 auto controller = GetResourceManager()->GetPalma();
2024 const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data); 1977 const auto result = controller->GetPalmaOperationInfo(connection_handle, operation_type, data);
2025 1978
2026 if (result.IsError()) { 1979 if (result.IsError()) {
2027 IPC::ResponseBuilder rb{ctx, 2}; 1980 IPC::ResponseBuilder rb{ctx, 2};
@@ -2036,14 +1989,14 @@ void IHidServer::GetPalmaOperationInfo(HLERequestContext& ctx) {
2036 1989
2037void IHidServer::PlayPalmaActivity(HLERequestContext& ctx) { 1990void IHidServer::PlayPalmaActivity(HLERequestContext& ctx) {
2038 IPC::RequestParser rp{ctx}; 1991 IPC::RequestParser rp{ctx};
2039 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 1992 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2040 const auto palma_activity{rp.Pop<u64>()}; 1993 const auto palma_activity{rp.Pop<u64>()};
2041 1994
2042 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}", 1995 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
2043 connection_handle.npad_id, palma_activity); 1996 connection_handle.npad_id, palma_activity);
2044 1997
2045 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 1998 auto controller = GetResourceManager()->GetPalma();
2046 const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity); 1999 const auto result = controller->PlayPalmaActivity(connection_handle, palma_activity);
2047 2000
2048 IPC::ResponseBuilder rb{ctx, 2}; 2001 IPC::ResponseBuilder rb{ctx, 2};
2049 rb.Push(result); 2002 rb.Push(result);
@@ -2051,14 +2004,14 @@ void IHidServer::PlayPalmaActivity(HLERequestContext& ctx) {
2051 2004
2052void IHidServer::SetPalmaFrModeType(HLERequestContext& ctx) { 2005void IHidServer::SetPalmaFrModeType(HLERequestContext& ctx) {
2053 IPC::RequestParser rp{ctx}; 2006 IPC::RequestParser rp{ctx};
2054 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2007 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2055 const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()}; 2008 const auto fr_mode{rp.PopEnum<Palma::PalmaFrModeType>()};
2056 2009
2057 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}", 2010 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
2058 connection_handle.npad_id, fr_mode); 2011 connection_handle.npad_id, fr_mode);
2059 2012
2060 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 2013 auto controller = GetResourceManager()->GetPalma();
2061 const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode); 2014 const auto result = controller->SetPalmaFrModeType(connection_handle, fr_mode);
2062 2015
2063 IPC::ResponseBuilder rb{ctx, 2}; 2016 IPC::ResponseBuilder rb{ctx, 2};
2064 rb.Push(result); 2017 rb.Push(result);
@@ -2066,12 +2019,12 @@ void IHidServer::SetPalmaFrModeType(HLERequestContext& ctx) {
2066 2019
2067void IHidServer::ReadPalmaStep(HLERequestContext& ctx) { 2020void IHidServer::ReadPalmaStep(HLERequestContext& ctx) {
2068 IPC::RequestParser rp{ctx}; 2021 IPC::RequestParser rp{ctx};
2069 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2022 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2070 2023
2071 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2024 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2072 2025
2073 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 2026 auto controller = GetResourceManager()->GetPalma();
2074 const auto result = controller.ReadPalmaStep(connection_handle); 2027 const auto result = controller->ReadPalmaStep(connection_handle);
2075 2028
2076 IPC::ResponseBuilder rb{ctx, 2}; 2029 IPC::ResponseBuilder rb{ctx, 2};
2077 rb.Push(result); 2030 rb.Push(result);
@@ -2082,7 +2035,7 @@ void IHidServer::EnablePalmaStep(HLERequestContext& ctx) {
2082 struct Parameters { 2035 struct Parameters {
2083 bool is_enabled; 2036 bool is_enabled;
2084 INSERT_PADDING_WORDS_NOINIT(1); 2037 INSERT_PADDING_WORDS_NOINIT(1);
2085 Controller_Palma::PalmaConnectionHandle connection_handle; 2038 Palma::PalmaConnectionHandle connection_handle;
2086 }; 2039 };
2087 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); 2040 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2088 2041
@@ -2091,9 +2044,9 @@ void IHidServer::EnablePalmaStep(HLERequestContext& ctx) {
2091 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}", 2044 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
2092 parameters.connection_handle.npad_id, parameters.is_enabled); 2045 parameters.connection_handle.npad_id, parameters.is_enabled);
2093 2046
2094 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 2047 auto controller = GetResourceManager()->GetPalma();
2095 const auto result = 2048 const auto result =
2096 controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled); 2049 controller->EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
2097 2050
2098 IPC::ResponseBuilder rb{ctx, 2}; 2051 IPC::ResponseBuilder rb{ctx, 2};
2099 rb.Push(result); 2052 rb.Push(result);
@@ -2101,12 +2054,12 @@ void IHidServer::EnablePalmaStep(HLERequestContext& ctx) {
2101 2054
2102void IHidServer::ResetPalmaStep(HLERequestContext& ctx) { 2055void IHidServer::ResetPalmaStep(HLERequestContext& ctx) {
2103 IPC::RequestParser rp{ctx}; 2056 IPC::RequestParser rp{ctx};
2104 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2057 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2105 2058
2106 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2059 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2107 2060
2108 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma); 2061 auto controller = GetResourceManager()->GetPalma();
2109 const auto result = controller.ResetPalmaStep(connection_handle); 2062 const auto result = controller->ResetPalmaStep(connection_handle);
2110 2063
2111 IPC::ResponseBuilder rb{ctx, 2}; 2064 IPC::ResponseBuilder rb{ctx, 2};
2112 rb.Push(result); 2065 rb.Push(result);
@@ -2128,13 +2081,11 @@ void IHidServer::WritePalmaApplicationSection(HLERequestContext& ctx) {
2128 2081
2129void IHidServer::ReadPalmaUniqueCode(HLERequestContext& ctx) { 2082void IHidServer::ReadPalmaUniqueCode(HLERequestContext& ctx) {
2130 IPC::RequestParser rp{ctx}; 2083 IPC::RequestParser rp{ctx};
2131 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2084 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2132 2085
2133 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2086 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2134 2087
2135 GetResourceManager() 2088 GetResourceManager()->GetPalma()->ReadPalmaUniqueCode(connection_handle);
2136 ->GetController<Controller_Palma>(HidController::Palma)
2137 .ReadPalmaUniqueCode(connection_handle);
2138 2089
2139 IPC::ResponseBuilder rb{ctx, 2}; 2090 IPC::ResponseBuilder rb{ctx, 2};
2140 rb.Push(ResultSuccess); 2091 rb.Push(ResultSuccess);
@@ -2142,13 +2093,11 @@ void IHidServer::ReadPalmaUniqueCode(HLERequestContext& ctx) {
2142 2093
2143void IHidServer::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) { 2094void IHidServer::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) {
2144 IPC::RequestParser rp{ctx}; 2095 IPC::RequestParser rp{ctx};
2145 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2096 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2146 2097
2147 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2098 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2148 2099
2149 GetResourceManager() 2100 GetResourceManager()->GetPalma()->SetPalmaUniqueCodeInvalid(connection_handle);
2150 ->GetController<Controller_Palma>(HidController::Palma)
2151 .SetPalmaUniqueCodeInvalid(connection_handle);
2152 2101
2153 IPC::ResponseBuilder rb{ctx, 2}; 2102 IPC::ResponseBuilder rb{ctx, 2};
2154 rb.Push(ResultSuccess); 2103 rb.Push(ResultSuccess);
@@ -2163,7 +2112,7 @@ void IHidServer::WritePalmaActivityEntry(HLERequestContext& ctx) {
2163 2112
2164void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) { 2113void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
2165 IPC::RequestParser rp{ctx}; 2114 IPC::RequestParser rp{ctx};
2166 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2115 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2167 const auto unknown{rp.Pop<u64>()}; 2116 const auto unknown{rp.Pop<u64>()};
2168 2117
2169 [[maybe_unused]] const auto buffer = ctx.ReadBuffer(); 2118 [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
@@ -2171,9 +2120,7 @@ void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
2171 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}", 2120 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
2172 connection_handle.npad_id, unknown); 2121 connection_handle.npad_id, unknown);
2173 2122
2174 GetResourceManager() 2123 GetResourceManager()->GetPalma()->WritePalmaRgbLedPatternEntry(connection_handle, unknown);
2175 ->GetController<Controller_Palma>(HidController::Palma)
2176 .WritePalmaRgbLedPatternEntry(connection_handle, unknown);
2177 2124
2178 IPC::ResponseBuilder rb{ctx, 2}; 2125 IPC::ResponseBuilder rb{ctx, 2};
2179 rb.Push(ResultSuccess); 2126 rb.Push(ResultSuccess);
@@ -2181,8 +2128,8 @@ void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
2181 2128
2182void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) { 2129void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) {
2183 IPC::RequestParser rp{ctx}; 2130 IPC::RequestParser rp{ctx};
2184 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2131 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2185 const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()}; 2132 const auto wave_set{rp.PopEnum<Palma::PalmaWaveSet>()};
2186 const auto unknown{rp.Pop<u64>()}; 2133 const auto unknown{rp.Pop<u64>()};
2187 const auto t_mem_size{rp.Pop<u64>()}; 2134 const auto t_mem_size{rp.Pop<u64>()};
2188 const auto t_mem_handle{ctx.GetCopyHandle(0)}; 2135 const auto t_mem_handle{ctx.GetCopyHandle(0)};
@@ -2207,9 +2154,8 @@ void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) {
2207 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}", 2154 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
2208 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); 2155 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
2209 2156
2210 GetResourceManager() 2157 GetResourceManager()->GetPalma()->WritePalmaWaveEntry(connection_handle, wave_set,
2211 ->GetController<Controller_Palma>(HidController::Palma) 2158 t_mem->GetSourceAddress(), t_mem_size);
2212 .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size);
2213 2159
2214 IPC::ResponseBuilder rb{ctx, 2}; 2160 IPC::ResponseBuilder rb{ctx, 2};
2215 rb.Push(ResultSuccess); 2161 rb.Push(ResultSuccess);
@@ -2220,7 +2166,7 @@ void IHidServer::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2220 struct Parameters { 2166 struct Parameters {
2221 s32 database_id_version; 2167 s32 database_id_version;
2222 INSERT_PADDING_WORDS_NOINIT(1); 2168 INSERT_PADDING_WORDS_NOINIT(1);
2223 Controller_Palma::PalmaConnectionHandle connection_handle; 2169 Palma::PalmaConnectionHandle connection_handle;
2224 }; 2170 };
2225 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); 2171 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2226 2172
@@ -2229,10 +2175,8 @@ void IHidServer::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2229 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}", 2175 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
2230 parameters.connection_handle.npad_id, parameters.database_id_version); 2176 parameters.connection_handle.npad_id, parameters.database_id_version);
2231 2177
2232 GetResourceManager() 2178 GetResourceManager()->GetPalma()->SetPalmaDataBaseIdentificationVersion(
2233 ->GetController<Controller_Palma>(HidController::Palma) 2179 parameters.connection_handle, parameters.database_id_version);
2234 .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle,
2235 parameters.database_id_version);
2236 2180
2237 IPC::ResponseBuilder rb{ctx, 2}; 2181 IPC::ResponseBuilder rb{ctx, 2};
2238 rb.Push(ResultSuccess); 2182 rb.Push(ResultSuccess);
@@ -2240,13 +2184,11 @@ void IHidServer::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2240 2184
2241void IHidServer::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) { 2185void IHidServer::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2242 IPC::RequestParser rp{ctx}; 2186 IPC::RequestParser rp{ctx};
2243 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2187 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2244 2188
2245 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2189 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2246 2190
2247 GetResourceManager() 2191 GetResourceManager()->GetPalma()->GetPalmaDataBaseIdentificationVersion(connection_handle);
2248 ->GetController<Controller_Palma>(HidController::Palma)
2249 .GetPalmaDataBaseIdentificationVersion(connection_handle);
2250 2192
2251 IPC::ResponseBuilder rb{ctx, 2}; 2193 IPC::ResponseBuilder rb{ctx, 2};
2252 rb.Push(ResultSuccess); 2194 rb.Push(ResultSuccess);
@@ -2261,13 +2203,12 @@ void IHidServer::SuspendPalmaFeature(HLERequestContext& ctx) {
2261 2203
2262void IHidServer::GetPalmaOperationResult(HLERequestContext& ctx) { 2204void IHidServer::GetPalmaOperationResult(HLERequestContext& ctx) {
2263 IPC::RequestParser rp{ctx}; 2205 IPC::RequestParser rp{ctx};
2264 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2206 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2265 2207
2266 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2208 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2267 2209
2268 const auto result = GetResourceManager() 2210 const auto result =
2269 ->GetController<Controller_Palma>(HidController::Palma) 2211 GetResourceManager()->GetPalma()->GetPalmaOperationResult(connection_handle);
2270 .GetPalmaOperationResult(connection_handle);
2271 2212
2272 IPC::ResponseBuilder rb{ctx, 2}; 2213 IPC::ResponseBuilder rb{ctx, 2};
2273 rb.Push(result); 2214 rb.Push(result);
@@ -2302,9 +2243,7 @@ void IHidServer::SetIsPalmaAllConnectable(HLERequestContext& ctx) {
2302 "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}", 2243 "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
2303 parameters.is_palma_all_connectable, parameters.applet_resource_user_id); 2244 parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
2304 2245
2305 GetResourceManager() 2246 GetResourceManager()->GetPalma()->SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
2306 ->GetController<Controller_Palma>(HidController::Palma)
2307 .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
2308 2247
2309 IPC::ResponseBuilder rb{ctx, 2}; 2248 IPC::ResponseBuilder rb{ctx, 2};
2310 rb.Push(ResultSuccess); 2249 rb.Push(ResultSuccess);
@@ -2319,13 +2258,11 @@ void IHidServer::SetIsPalmaPairedConnectable(HLERequestContext& ctx) {
2319 2258
2320void IHidServer::PairPalma(HLERequestContext& ctx) { 2259void IHidServer::PairPalma(HLERequestContext& ctx) {
2321 IPC::RequestParser rp{ctx}; 2260 IPC::RequestParser rp{ctx};
2322 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()}; 2261 const auto connection_handle{rp.PopRaw<Palma::PalmaConnectionHandle>()};
2323 2262
2324 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id); 2263 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2325 2264
2326 GetResourceManager() 2265 GetResourceManager()->GetPalma()->PairPalma(connection_handle);
2327 ->GetController<Controller_Palma>(HidController::Palma)
2328 .PairPalma(connection_handle);
2329 2266
2330 IPC::ResponseBuilder rb{ctx, 2}; 2267 IPC::ResponseBuilder rb{ctx, 2};
2331 rb.Push(ResultSuccess); 2268 rb.Push(ResultSuccess);
@@ -2337,9 +2274,7 @@ void IHidServer::SetPalmaBoostMode(HLERequestContext& ctx) {
2337 2274
2338 LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode); 2275 LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
2339 2276
2340 GetResourceManager() 2277 GetResourceManager()->GetPalma()->SetPalmaBoostMode(palma_boost_mode);
2341 ->GetController<Controller_Palma>(HidController::Palma)
2342 .SetPalmaBoostMode(palma_boost_mode);
2343 2278
2344 IPC::ResponseBuilder rb{ctx, 2}; 2279 IPC::ResponseBuilder rb{ctx, 2};
2345 rb.Push(ResultSuccess); 2280 rb.Push(ResultSuccess);
@@ -2376,11 +2311,9 @@ void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
2376void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { 2311void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
2377 IPC::RequestParser rp{ctx}; 2312 IPC::RequestParser rp{ctx};
2378 const auto applet_resource_user_id{rp.Pop<u64>()}; 2313 const auto applet_resource_user_id{rp.Pop<u64>()};
2379 const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()}; 2314 const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()};
2380 2315
2381 GetResourceManager() 2316 GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode);
2382 ->GetController<Controller_NPad>(HidController::NPad)
2383 .SetNpadCommunicationMode(communication_mode);
2384 2317
2385 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}", 2318 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
2386 applet_resource_user_id, communication_mode); 2319 applet_resource_user_id, communication_mode);
@@ -2396,9 +2329,7 @@ void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) {
2396 2329
2397 IPC::ResponseBuilder rb{ctx, 4}; 2330 IPC::ResponseBuilder rb{ctx, 4};
2398 rb.Push(ResultSuccess); 2331 rb.Push(ResultSuccess);
2399 rb.PushEnum(GetResourceManager() 2332 rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadCommunicationMode());
2400 ->GetController<Controller_NPad>(HidController::NPad)
2401 .GetNpadCommunicationMode());
2402} 2333}
2403 2334
2404void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) { 2335void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 6f1902ee5..b56d0347a 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -16,206 +16,206 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
16 resource_manager{resource} { 16 resource_manager{resource} {
17 // clang-format off 17 // clang-format off
18 static const FunctionInfo functions[] = { 18 static const FunctionInfo functions[] = {
19 {31, nullptr, "SendKeyboardLockKeyEvent"}, 19 {31, nullptr, "SendKeyboardLockKeyEvent"},
20 {101, nullptr, "AcquireHomeButtonEventHandle"}, 20 {101, nullptr, "AcquireHomeButtonEventHandle"},
21 {111, nullptr, "ActivateHomeButton"}, 21 {111, nullptr, "ActivateHomeButton"},
22 {121, nullptr, "AcquireSleepButtonEventHandle"}, 22 {121, nullptr, "AcquireSleepButtonEventHandle"},
23 {131, nullptr, "ActivateSleepButton"}, 23 {131, nullptr, "ActivateSleepButton"},
24 {141, nullptr, "AcquireCaptureButtonEventHandle"}, 24 {141, nullptr, "AcquireCaptureButtonEventHandle"},
25 {151, nullptr, "ActivateCaptureButton"}, 25 {151, nullptr, "ActivateCaptureButton"},
26 {161, nullptr, "GetPlatformConfig"}, 26 {161, nullptr, "GetPlatformConfig"},
27 {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"}, 27 {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
28 {211, nullptr, "GetNpadsWithNfc"}, 28 {211, nullptr, "GetNpadsWithNfc"},
29 {212, nullptr, "AcquireNfcActivateEventHandle"}, 29 {212, nullptr, "AcquireNfcActivateEventHandle"},
30 {213, nullptr, "ActivateNfc"}, 30 {213, nullptr, "ActivateNfc"},
31 {214, nullptr, "GetXcdHandleForNpadWithNfc"}, 31 {214, nullptr, "GetXcdHandleForNpadWithNfc"},
32 {215, nullptr, "IsNfcActivated"}, 32 {215, nullptr, "IsNfcActivated"},
33 {230, nullptr, "AcquireIrSensorEventHandle"}, 33 {230, nullptr, "AcquireIrSensorEventHandle"},
34 {231, nullptr, "ActivateIrSensor"}, 34 {231, nullptr, "ActivateIrSensor"},
35 {232, nullptr, "GetIrSensorState"}, 35 {232, nullptr, "GetIrSensorState"},
36 {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, 36 {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
37 {301, nullptr, "ActivateNpadSystem"}, 37 {301, nullptr, "ActivateNpadSystem"},
38 {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"}, 38 {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
39 {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"}, 39 {304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"},
40 {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"}, 40 {305, &IHidSystemServer::DisableAssigningSingleOnSlSrPress, "DisableAssigningSingleOnSlSrPress"},
41 {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"}, 41 {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"},
42 {307, nullptr, "GetNpadSystemExtStyle"}, 42 {307, nullptr, "GetNpadSystemExtStyle"},
43 {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"}, 43 {308, &IHidSystemServer::ApplyNpadSystemCommonPolicyFull, "ApplyNpadSystemCommonPolicyFull"},
44 {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"}, 44 {309, &IHidSystemServer::GetNpadFullKeyGripColor, "GetNpadFullKeyGripColor"},
45 {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"}, 45 {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"},
46 {311, nullptr, "SetNpadPlayerLedBlinkingDevice"}, 46 {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
47 {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"}, 47 {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"},
48 {313, nullptr, "GetNpadCaptureButtonAssignment"}, 48 {313, nullptr, "GetNpadCaptureButtonAssignment"},
49 {314, nullptr, "GetAppletFooterUiType"}, 49 {314, nullptr, "GetAppletFooterUiType"},
50 {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"}, 50 {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"},
51 {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"}, 51 {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"},
52 {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"}, 52 {317, &IHidSystemServer::GetNpadLeftRightInterfaceType, "GetNpadLeftRightInterfaceType"},
53 {318, &IHidSystemServer::HasBattery, "HasBattery"}, 53 {318, &IHidSystemServer::HasBattery, "HasBattery"},
54 {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"}, 54 {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"},
55 {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"}, 55 {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
56 {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"}, 56 {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"},
57 {323, nullptr, "GetXcdHandleForNpadWithIrSensor"}, 57 {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
58 {324, nullptr, "GetUniquePadButtonSet"}, 58 {324, nullptr, "GetUniquePadButtonSet"},
59 {325, nullptr, "GetUniquePadColor"}, 59 {325, nullptr, "GetUniquePadColor"},
60 {326, nullptr, "GetUniquePadAppletDetailedUiType"}, 60 {326, nullptr, "GetUniquePadAppletDetailedUiType"},
61 {327, nullptr, "GetAbstractedPadIdDataFromNpad"}, 61 {327, nullptr, "GetAbstractedPadIdDataFromNpad"},
62 {328, nullptr, "AttachAbstractedPadToNpad"}, 62 {328, nullptr, "AttachAbstractedPadToNpad"},
63 {329, nullptr, "DetachAbstractedPadAll"}, 63 {329, nullptr, "DetachAbstractedPadAll"},
64 {330, nullptr, "CheckAbstractedPadConnection"}, 64 {330, nullptr, "CheckAbstractedPadConnection"},
65 {500, nullptr, "SetAppletResourceUserId"}, 65 {500, nullptr, "SetAppletResourceUserId"},
66 {501, nullptr, "RegisterAppletResourceUserId"}, 66 {501, nullptr, "RegisterAppletResourceUserId"},
67 {502, nullptr, "UnregisterAppletResourceUserId"}, 67 {502, nullptr, "UnregisterAppletResourceUserId"},
68 {503, nullptr, "EnableAppletToGetInput"}, 68 {503, nullptr, "EnableAppletToGetInput"},
69 {504, nullptr, "SetAruidValidForVibration"}, 69 {504, nullptr, "SetAruidValidForVibration"},
70 {505, nullptr, "EnableAppletToGetSixAxisSensor"}, 70 {505, nullptr, "EnableAppletToGetSixAxisSensor"},
71 {506, nullptr, "EnableAppletToGetPadInput"}, 71 {506, nullptr, "EnableAppletToGetPadInput"},
72 {507, nullptr, "EnableAppletToGetTouchScreen"}, 72 {507, nullptr, "EnableAppletToGetTouchScreen"},
73 {510, nullptr, "SetVibrationMasterVolume"}, 73 {510, nullptr, "SetVibrationMasterVolume"},
74 {511, nullptr, "GetVibrationMasterVolume"}, 74 {511, nullptr, "GetVibrationMasterVolume"},
75 {512, nullptr, "BeginPermitVibrationSession"}, 75 {512, nullptr, "BeginPermitVibrationSession"},
76 {513, nullptr, "EndPermitVibrationSession"}, 76 {513, nullptr, "EndPermitVibrationSession"},
77 {514, nullptr, "Unknown514"}, 77 {514, nullptr, "Unknown514"},
78 {520, nullptr, "EnableHandheldHids"}, 78 {520, nullptr, "EnableHandheldHids"},
79 {521, nullptr, "DisableHandheldHids"}, 79 {521, nullptr, "DisableHandheldHids"},
80 {522, nullptr, "SetJoyConRailEnabled"}, 80 {522, nullptr, "SetJoyConRailEnabled"},
81 {523, nullptr, "IsJoyConRailEnabled"}, 81 {523, nullptr, "IsJoyConRailEnabled"},
82 {524, nullptr, "IsHandheldHidsEnabled"}, 82 {524, nullptr, "IsHandheldHidsEnabled"},
83 {525, nullptr, "IsJoyConAttachedOnAllRail"}, 83 {525, nullptr, "IsJoyConAttachedOnAllRail"},
84 {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"}, 84 {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
85 {541, nullptr, "GetPlayReportControllerUsages"}, 85 {541, nullptr, "GetPlayReportControllerUsages"},
86 {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"}, 86 {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
87 {543, nullptr, "GetRegisteredDevicesOld"}, 87 {543, nullptr, "GetRegisteredDevicesOld"},
88 {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"}, 88 {544, &IHidSystemServer::AcquireConnectionTriggerTimeoutEvent, "AcquireConnectionTriggerTimeoutEvent"},
89 {545, nullptr, "SendConnectionTrigger"}, 89 {545, nullptr, "SendConnectionTrigger"},
90 {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"}, 90 {546, &IHidSystemServer::AcquireDeviceRegisteredEventForControllerSupport, "AcquireDeviceRegisteredEventForControllerSupport"},
91 {547, nullptr, "GetAllowedBluetoothLinksCount"}, 91 {547, nullptr, "GetAllowedBluetoothLinksCount"},
92 {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"}, 92 {548, &IHidSystemServer::GetRegisteredDevices, "GetRegisteredDevices"},
93 {549, nullptr, "GetConnectableRegisteredDevices"}, 93 {549, nullptr, "GetConnectableRegisteredDevices"},
94 {700, nullptr, "ActivateUniquePad"}, 94 {700, nullptr, "ActivateUniquePad"},
95 {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"}, 95 {702, &IHidSystemServer::AcquireUniquePadConnectionEventHandle, "AcquireUniquePadConnectionEventHandle"},
96 {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"}, 96 {703, &IHidSystemServer::GetUniquePadIds, "GetUniquePadIds"},
97 {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"}, 97 {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
98 {800, nullptr, "ListSixAxisSensorHandles"}, 98 {800, nullptr, "ListSixAxisSensorHandles"},
99 {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"}, 99 {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
100 {802, nullptr, "ResetSixAxisSensorCalibrationValues"}, 100 {802, nullptr, "ResetSixAxisSensorCalibrationValues"},
101 {803, nullptr, "StartSixAxisSensorUserCalibration"}, 101 {803, nullptr, "StartSixAxisSensorUserCalibration"},
102 {804, nullptr, "CancelSixAxisSensorUserCalibration"}, 102 {804, nullptr, "CancelSixAxisSensorUserCalibration"},
103 {805, nullptr, "GetUniquePadBluetoothAddress"}, 103 {805, nullptr, "GetUniquePadBluetoothAddress"},
104 {806, nullptr, "DisconnectUniquePad"}, 104 {806, nullptr, "DisconnectUniquePad"},
105 {807, nullptr, "GetUniquePadType"}, 105 {807, nullptr, "GetUniquePadType"},
106 {808, nullptr, "GetUniquePadInterface"}, 106 {808, nullptr, "GetUniquePadInterface"},
107 {809, nullptr, "GetUniquePadSerialNumber"}, 107 {809, nullptr, "GetUniquePadSerialNumber"},
108 {810, nullptr, "GetUniquePadControllerNumber"}, 108 {810, nullptr, "GetUniquePadControllerNumber"},
109 {811, nullptr, "GetSixAxisSensorUserCalibrationStage"}, 109 {811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
110 {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"}, 110 {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
111 {821, nullptr, "StartAnalogStickManualCalibration"}, 111 {821, nullptr, "StartAnalogStickManualCalibration"},
112 {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"}, 112 {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
113 {823, nullptr, "CancelAnalogStickManualCalibration"}, 113 {823, nullptr, "CancelAnalogStickManualCalibration"},
114 {824, nullptr, "ResetAnalogStickManualCalibration"}, 114 {824, nullptr, "ResetAnalogStickManualCalibration"},
115 {825, nullptr, "GetAnalogStickState"}, 115 {825, nullptr, "GetAnalogStickState"},
116 {826, nullptr, "GetAnalogStickManualCalibrationStage"}, 116 {826, nullptr, "GetAnalogStickManualCalibrationStage"},
117 {827, nullptr, "IsAnalogStickButtonPressed"}, 117 {827, nullptr, "IsAnalogStickButtonPressed"},
118 {828, nullptr, "IsAnalogStickInReleasePosition"}, 118 {828, nullptr, "IsAnalogStickInReleasePosition"},
119 {829, nullptr, "IsAnalogStickInCircumference"}, 119 {829, nullptr, "IsAnalogStickInCircumference"},
120 {830, nullptr, "SetNotificationLedPattern"}, 120 {830, nullptr, "SetNotificationLedPattern"},
121 {831, nullptr, "SetNotificationLedPatternWithTimeout"}, 121 {831, nullptr, "SetNotificationLedPatternWithTimeout"},
122 {832, nullptr, "PrepareHidsForNotificationWake"}, 122 {832, nullptr, "PrepareHidsForNotificationWake"},
123 {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"}, 123 {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
124 {851, nullptr, "EnableUsbFullKeyController"}, 124 {851, nullptr, "EnableUsbFullKeyController"},
125 {852, nullptr, "IsUsbConnected"}, 125 {852, nullptr, "IsUsbConnected"},
126 {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"}, 126 {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"},
127 {900, nullptr, "ActivateInputDetector"}, 127 {900, nullptr, "ActivateInputDetector"},
128 {901, nullptr, "NotifyInputDetector"}, 128 {901, nullptr, "NotifyInputDetector"},
129 {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"}, 129 {1000, &IHidSystemServer::InitializeFirmwareUpdate, "InitializeFirmwareUpdate"},
130 {1001, nullptr, "GetFirmwareVersion"}, 130 {1001, nullptr, "GetFirmwareVersion"},
131 {1002, nullptr, "GetAvailableFirmwareVersion"}, 131 {1002, nullptr, "GetAvailableFirmwareVersion"},
132 {1003, nullptr, "IsFirmwareUpdateAvailable"}, 132 {1003, nullptr, "IsFirmwareUpdateAvailable"},
133 {1004, nullptr, "CheckFirmwareUpdateRequired"}, 133 {1004, nullptr, "CheckFirmwareUpdateRequired"},
134 {1005, nullptr, "StartFirmwareUpdate"}, 134 {1005, nullptr, "StartFirmwareUpdate"},
135 {1006, nullptr, "AbortFirmwareUpdate"}, 135 {1006, nullptr, "AbortFirmwareUpdate"},
136 {1007, nullptr, "GetFirmwareUpdateState"}, 136 {1007, nullptr, "GetFirmwareUpdateState"},
137 {1008, nullptr, "ActivateAudioControl"}, 137 {1008, nullptr, "ActivateAudioControl"},
138 {1009, nullptr, "AcquireAudioControlEventHandle"}, 138 {1009, nullptr, "AcquireAudioControlEventHandle"},
139 {1010, nullptr, "GetAudioControlStates"}, 139 {1010, nullptr, "GetAudioControlStates"},
140 {1011, nullptr, "DeactivateAudioControl"}, 140 {1011, nullptr, "DeactivateAudioControl"},
141 {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"}, 141 {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
142 {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"}, 142 {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
143 {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"}, 143 {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
144 {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"}, 144 {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
145 {1100, nullptr, "GetHidbusSystemServiceObject"}, 145 {1100, nullptr, "GetHidbusSystemServiceObject"},
146 {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"}, 146 {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
147 {1130, nullptr, "InitializeUsbFirmwareUpdate"}, 147 {1130, nullptr, "InitializeUsbFirmwareUpdate"},
148 {1131, nullptr, "FinalizeUsbFirmwareUpdate"}, 148 {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
149 {1132, nullptr, "CheckUsbFirmwareUpdateRequired"}, 149 {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
150 {1133, nullptr, "StartUsbFirmwareUpdate"}, 150 {1133, nullptr, "StartUsbFirmwareUpdate"},
151 {1134, nullptr, "GetUsbFirmwareUpdateState"}, 151 {1134, nullptr, "GetUsbFirmwareUpdateState"},
152 {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"}, 152 {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"},
153 {1150, nullptr, "SetTouchScreenMagnification"}, 153 {1150, nullptr, "SetTouchScreenMagnification"},
154 {1151, nullptr, "GetTouchScreenFirmwareVersion"}, 154 {1151, nullptr, "GetTouchScreenFirmwareVersion"},
155 {1152, nullptr, "SetTouchScreenDefaultConfiguration"}, 155 {1152, nullptr, "SetTouchScreenDefaultConfiguration"},
156 {1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"}, 156 {1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"},
157 {1154, nullptr, "IsFirmwareAvailableForNotification"}, 157 {1154, nullptr, "IsFirmwareAvailableForNotification"},
158 {1155, nullptr, "SetForceHandheldStyleVibration"}, 158 {1155, nullptr, "SetForceHandheldStyleVibration"},
159 {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"}, 159 {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
160 {1157, nullptr, "CancelConnectionTrigger"}, 160 {1157, nullptr, "CancelConnectionTrigger"},
161 {1200, nullptr, "IsButtonConfigSupported"}, 161 {1200, nullptr, "IsButtonConfigSupported"},
162 {1201, nullptr, "IsButtonConfigEmbeddedSupported"}, 162 {1201, nullptr, "IsButtonConfigEmbeddedSupported"},
163 {1202, nullptr, "DeleteButtonConfig"}, 163 {1202, nullptr, "DeleteButtonConfig"},
164 {1203, nullptr, "DeleteButtonConfigEmbedded"}, 164 {1203, nullptr, "DeleteButtonConfigEmbedded"},
165 {1204, nullptr, "SetButtonConfigEnabled"}, 165 {1204, nullptr, "SetButtonConfigEnabled"},
166 {1205, nullptr, "SetButtonConfigEmbeddedEnabled"}, 166 {1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
167 {1206, nullptr, "IsButtonConfigEnabled"}, 167 {1206, nullptr, "IsButtonConfigEnabled"},
168 {1207, nullptr, "IsButtonConfigEmbeddedEnabled"}, 168 {1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
169 {1208, nullptr, "SetButtonConfigEmbedded"}, 169 {1208, nullptr, "SetButtonConfigEmbedded"},
170 {1209, nullptr, "SetButtonConfigFull"}, 170 {1209, nullptr, "SetButtonConfigFull"},
171 {1210, nullptr, "SetButtonConfigLeft"}, 171 {1210, nullptr, "SetButtonConfigLeft"},
172 {1211, nullptr, "SetButtonConfigRight"}, 172 {1211, nullptr, "SetButtonConfigRight"},
173 {1212, nullptr, "GetButtonConfigEmbedded"}, 173 {1212, nullptr, "GetButtonConfigEmbedded"},
174 {1213, nullptr, "GetButtonConfigFull"}, 174 {1213, nullptr, "GetButtonConfigFull"},
175 {1214, nullptr, "GetButtonConfigLeft"}, 175 {1214, nullptr, "GetButtonConfigLeft"},
176 {1215, nullptr, "GetButtonConfigRight"}, 176 {1215, nullptr, "GetButtonConfigRight"},
177 {1250, nullptr, "IsCustomButtonConfigSupported"}, 177 {1250, nullptr, "IsCustomButtonConfigSupported"},
178 {1251, nullptr, "IsDefaultButtonConfigEmbedded"}, 178 {1251, nullptr, "IsDefaultButtonConfigEmbedded"},
179 {1252, nullptr, "IsDefaultButtonConfigFull"}, 179 {1252, nullptr, "IsDefaultButtonConfigFull"},
180 {1253, nullptr, "IsDefaultButtonConfigLeft"}, 180 {1253, nullptr, "IsDefaultButtonConfigLeft"},
181 {1254, nullptr, "IsDefaultButtonConfigRight"}, 181 {1254, nullptr, "IsDefaultButtonConfigRight"},
182 {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"}, 182 {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
183 {1256, nullptr, "IsButtonConfigStorageFullEmpty"}, 183 {1256, nullptr, "IsButtonConfigStorageFullEmpty"},
184 {1257, nullptr, "IsButtonConfigStorageLeftEmpty"}, 184 {1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
185 {1258, nullptr, "IsButtonConfigStorageRightEmpty"}, 185 {1258, nullptr, "IsButtonConfigStorageRightEmpty"},
186 {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"}, 186 {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
187 {1260, nullptr, "GetButtonConfigStorageFullDeprecated"}, 187 {1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
188 {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"}, 188 {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
189 {1262, nullptr, "GetButtonConfigStorageRightDeprecated"}, 189 {1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
190 {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"}, 190 {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
191 {1264, nullptr, "SetButtonConfigStorageFullDeprecated"}, 191 {1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
192 {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"}, 192 {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
193 {1266, nullptr, "SetButtonConfigStorageRightDeprecated"}, 193 {1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
194 {1267, nullptr, "DeleteButtonConfigStorageEmbedded"}, 194 {1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
195 {1268, nullptr, "DeleteButtonConfigStorageFull"}, 195 {1268, nullptr, "DeleteButtonConfigStorageFull"},
196 {1269, nullptr, "DeleteButtonConfigStorageLeft"}, 196 {1269, nullptr, "DeleteButtonConfigStorageLeft"},
197 {1270, nullptr, "DeleteButtonConfigStorageRight"}, 197 {1270, nullptr, "DeleteButtonConfigStorageRight"},
198 {1271, nullptr, "IsUsingCustomButtonConfig"}, 198 {1271, nullptr, "IsUsingCustomButtonConfig"},
199 {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, 199 {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
200 {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, 200 {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
201 {1274, nullptr, "SetDefaultButtonConfig"}, 201 {1274, nullptr, "SetDefaultButtonConfig"},
202 {1275, nullptr, "SetAllDefaultButtonConfig"}, 202 {1275, nullptr, "SetAllDefaultButtonConfig"},
203 {1276, nullptr, "SetHidButtonConfigEmbedded"}, 203 {1276, nullptr, "SetHidButtonConfigEmbedded"},
204 {1277, nullptr, "SetHidButtonConfigFull"}, 204 {1277, nullptr, "SetHidButtonConfigFull"},
205 {1278, nullptr, "SetHidButtonConfigLeft"}, 205 {1278, nullptr, "SetHidButtonConfigLeft"},
206 {1279, nullptr, "SetHidButtonConfigRight"}, 206 {1279, nullptr, "SetHidButtonConfigRight"},
207 {1280, nullptr, "GetHidButtonConfigEmbedded"}, 207 {1280, nullptr, "GetHidButtonConfigEmbedded"},
208 {1281, nullptr, "GetHidButtonConfigFull"}, 208 {1281, nullptr, "GetHidButtonConfigFull"},
209 {1282, nullptr, "GetHidButtonConfigLeft"}, 209 {1282, nullptr, "GetHidButtonConfigLeft"},
210 {1283, nullptr, "GetHidButtonConfigRight"}, 210 {1283, nullptr, "GetHidButtonConfigRight"},
211 {1284, nullptr, "GetButtonConfigStorageEmbedded"}, 211 {1284, nullptr, "GetButtonConfigStorageEmbedded"},
212 {1285, nullptr, "GetButtonConfigStorageFull"}, 212 {1285, nullptr, "GetButtonConfigStorageFull"},
213 {1286, nullptr, "GetButtonConfigStorageLeft"}, 213 {1286, nullptr, "GetButtonConfigStorageLeft"},
214 {1287, nullptr, "GetButtonConfigStorageRight"}, 214 {1287, nullptr, "GetButtonConfigStorageRight"},
215 {1288, nullptr, "SetButtonConfigStorageEmbedded"}, 215 {1288, nullptr, "SetButtonConfigStorageEmbedded"},
216 {1289, nullptr, "SetButtonConfigStorageFull"}, 216 {1289, nullptr, "SetButtonConfigStorageFull"},
217 {1290, nullptr, "DeleteButtonConfigStorageRight"}, 217 {1290, nullptr, "DeleteButtonConfigStorageRight"},
218 {1291, nullptr, "DeleteButtonConfigStorageRight"}, 218 {1291, nullptr, "DeleteButtonConfigStorageRight"},
219 }; 219 };
220 // clang-format on 220 // clang-format on
221 221
@@ -240,9 +240,7 @@ IHidSystemServer::~IHidSystemServer() {
240void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) { 240void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
241 LOG_WARNING(Service_HID, "called"); 241 LOG_WARNING(Service_HID, "called");
242 242
243 GetResourceManager() 243 GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
244 ->GetController<Controller_NPad>(HidController::NPad)
245 .ApplyNpadSystemCommonPolicy();
246 244
247 IPC::ResponseBuilder rb{ctx, 2}; 245 IPC::ResponseBuilder rb{ctx, 2};
248 rb.Push(ResultSuccess); 246 rb.Push(ResultSuccess);
@@ -273,9 +271,7 @@ void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
273void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) { 271void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
274 LOG_WARNING(Service_HID, "called"); 272 LOG_WARNING(Service_HID, "called");
275 273
276 GetResourceManager() 274 GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
277 ->GetController<Controller_NPad>(HidController::NPad)
278 .ApplyNpadSystemCommonPolicy();
279 275
280 IPC::ResponseBuilder rb{ctx, 2}; 276 IPC::ResponseBuilder rb{ctx, 2};
281 rb.Push(ResultSuccess); 277 rb.Push(ResultSuccess);
@@ -304,10 +300,7 @@ void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
304 LOG_INFO(Service_HID, "(STUBBED) called"); 300 LOG_INFO(Service_HID, "(STUBBED) called");
305 301
306 Core::HID::NpadStyleSet supported_styleset = 302 Core::HID::NpadStyleSet supported_styleset =
307 GetResourceManager() 303 GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
308 ->GetController<Controller_NPad>(HidController::NPad)
309 .GetSupportedStyleSet()
310 .raw;
311 304
312 IPC::ResponseBuilder rb{ctx, 3}; 305 IPC::ResponseBuilder rb{ctx, 3};
313 rb.Push(ResultSuccess); 306 rb.Push(ResultSuccess);
@@ -320,10 +313,7 @@ void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
320 LOG_INFO(Service_HID, "(STUBBED) called"); 313 LOG_INFO(Service_HID, "(STUBBED) called");
321 314
322 Core::HID::NpadStyleSet supported_styleset = 315 Core::HID::NpadStyleSet supported_styleset =
323 GetResourceManager() 316 GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
324 ->GetController<Controller_NPad>(HidController::NPad)
325 .GetSupportedStyleSet()
326 .raw;
327 317
328 IPC::ResponseBuilder rb{ctx, 3}; 318 IPC::ResponseBuilder rb{ctx, 3};
329 rb.Push(ResultSuccess); 319 rb.Push(ResultSuccess);
@@ -337,10 +327,8 @@ void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
337 LOG_DEBUG(Service_HID, "called, npad_id_type={}", 327 LOG_DEBUG(Service_HID, "called, npad_id_type={}",
338 npad_id_type); // Spams a lot when controller applet is running 328 npad_id_type); // Spams a lot when controller applet is running
339 329
340 const Service::HID::Controller_NPad::AppletDetailedUiType detailed_ui_type = 330 const NPad::AppletDetailedUiType detailed_ui_type =
341 GetResourceManager() 331 GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type);
342 ->GetController<Controller_NPad>(HidController::NPad)
343 .GetAppletDetailedUiType(npad_id_type);
344 332
345 IPC::ResponseBuilder rb{ctx, 3}; 333 IPC::ResponseBuilder rb{ctx, 3};
346 rb.Push(ResultSuccess); 334 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/hid/hid_util.h b/src/core/hle/service/hid/hid_util.h
new file mode 100644
index 000000000..b87cc10e3
--- /dev/null
+++ b/src/core/hle/service/hid/hid_util.h
@@ -0,0 +1,146 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hid/hid_types.h"
7#include "core/hle/service/hid/errors.h"
8
9namespace Service::HID {
10
11constexpr bool IsNpadIdValid(const Core::HID::NpadIdType npad_id) {
12 switch (npad_id) {
13 case Core::HID::NpadIdType::Player1:
14 case Core::HID::NpadIdType::Player2:
15 case Core::HID::NpadIdType::Player3:
16 case Core::HID::NpadIdType::Player4:
17 case Core::HID::NpadIdType::Player5:
18 case Core::HID::NpadIdType::Player6:
19 case Core::HID::NpadIdType::Player7:
20 case Core::HID::NpadIdType::Player8:
21 case Core::HID::NpadIdType::Other:
22 case Core::HID::NpadIdType::Handheld:
23 return true;
24 default:
25 return false;
26 }
27}
28
29constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& handle) {
30 const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id));
31 const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
32
33 if (!npad_id) {
34 return InvalidNpadId;
35 }
36 if (!device_index) {
37 return NpadDeviceIndexOutOfRange;
38 }
39
40 return ResultSuccess;
41}
42
43constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) {
44 switch (handle.npad_type) {
45 case Core::HID::NpadStyleIndex::ProController:
46 case Core::HID::NpadStyleIndex::Handheld:
47 case Core::HID::NpadStyleIndex::JoyconDual:
48 case Core::HID::NpadStyleIndex::JoyconLeft:
49 case Core::HID::NpadStyleIndex::JoyconRight:
50 case Core::HID::NpadStyleIndex::GameCube:
51 case Core::HID::NpadStyleIndex::N64:
52 case Core::HID::NpadStyleIndex::SystemExt:
53 case Core::HID::NpadStyleIndex::System:
54 // These support vibration
55 break;
56 default:
57 return VibrationInvalidStyleIndex;
58 }
59
60 if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) {
61 return VibrationInvalidNpadId;
62 }
63
64 if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) {
65 return VibrationDeviceIndexOutOfRange;
66 }
67
68 return ResultSuccess;
69}
70
71/// Converts a Core::HID::NpadIdType to an array index.
72constexpr size_t NpadIdTypeToIndex(Core::HID::NpadIdType npad_id_type) {
73 switch (npad_id_type) {
74 case Core::HID::NpadIdType::Player1:
75 return 0;
76 case Core::HID::NpadIdType::Player2:
77 return 1;
78 case Core::HID::NpadIdType::Player3:
79 return 2;
80 case Core::HID::NpadIdType::Player4:
81 return 3;
82 case Core::HID::NpadIdType::Player5:
83 return 4;
84 case Core::HID::NpadIdType::Player6:
85 return 5;
86 case Core::HID::NpadIdType::Player7:
87 return 6;
88 case Core::HID::NpadIdType::Player8:
89 return 7;
90 case Core::HID::NpadIdType::Handheld:
91 return 8;
92 case Core::HID::NpadIdType::Other:
93 return 9;
94 default:
95 return 8;
96 }
97}
98
99/// Converts an array index to a Core::HID::NpadIdType
100constexpr Core::HID::NpadIdType IndexToNpadIdType(size_t index) {
101 switch (index) {
102 case 0:
103 return Core::HID::NpadIdType::Player1;
104 case 1:
105 return Core::HID::NpadIdType::Player2;
106 case 2:
107 return Core::HID::NpadIdType::Player3;
108 case 3:
109 return Core::HID::NpadIdType::Player4;
110 case 4:
111 return Core::HID::NpadIdType::Player5;
112 case 5:
113 return Core::HID::NpadIdType::Player6;
114 case 6:
115 return Core::HID::NpadIdType::Player7;
116 case 7:
117 return Core::HID::NpadIdType::Player8;
118 case 8:
119 return Core::HID::NpadIdType::Handheld;
120 case 9:
121 return Core::HID::NpadIdType::Other;
122 default:
123 return Core::HID::NpadIdType::Invalid;
124 }
125}
126
127constexpr Core::HID::NpadStyleSet GetStylesetByIndex(std::size_t index) {
128 switch (index) {
129 case 0:
130 return Core::HID::NpadStyleSet::Fullkey;
131 case 1:
132 return Core::HID::NpadStyleSet::Handheld;
133 case 2:
134 return Core::HID::NpadStyleSet::JoyDual;
135 case 3:
136 return Core::HID::NpadStyleSet::JoyLeft;
137 case 4:
138 return Core::HID::NpadStyleSet::JoyRight;
139 case 5:
140 return Core::HID::NpadStyleSet::Palma;
141 default:
142 return Core::HID::NpadStyleSet::None;
143 }
144}
145
146} // namespace Service::HID
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index d383a266d..39b9a4474 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -12,6 +12,7 @@
12#include "core/hle/kernel/k_transfer_memory.h" 12#include "core/hle/kernel/k_transfer_memory.h"
13#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
14#include "core/hle/service/hid/errors.h" 14#include "core/hle/service/hid/errors.h"
15#include "core/hle/service/hid/hid_util.h"
15#include "core/hle/service/hid/irs.h" 16#include "core/hle/service/hid/irs.h"
16#include "core/hle/service/hid/irsensor/clustering_processor.h" 17#include "core/hle/service/hid/irsensor/clustering_processor.h"
17#include "core/hle/service/hid/irsensor/image_transfer_processor.h" 18#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
@@ -320,7 +321,7 @@ void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
320 } 321 }
321 322
322 Core::IrSensor::IrCameraHandle camera_handle{ 323 Core::IrSensor::IrCameraHandle camera_handle{
323 .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)), 324 .npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)),
324 .npad_type = Core::HID::NpadStyleIndex::None, 325 .npad_type = Core::HID::NpadStyleIndex::None,
325 }; 326 };
326 327
@@ -545,7 +546,7 @@ void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) {
545 546
546Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const { 547Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
547 if (camera_handle.npad_id > 548 if (camera_handle.npad_id >
548 static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) { 549 static_cast<u8>(HID::NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
549 return InvalidIrCameraHandle; 550 return InvalidIrCameraHandle;
550 } 551 }
551 if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) { 552 if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
index d6f42c646..e76d4eea9 100644
--- a/src/core/hle/service/hid/resource_manager.cpp
+++ b/src/core/hle/service/hid/resource_manager.cpp
@@ -9,14 +9,15 @@
9#include "core/hle/service/hid/resource_manager.h" 9#include "core/hle/service/hid/resource_manager.h"
10#include "core/hle/service/ipc_helpers.h" 10#include "core/hle/service/ipc_helpers.h"
11 11
12#include "core/hle/service/hid/controllers/console_sixaxis.h" 12#include "core/hle/service/hid/controllers/console_six_axis.h"
13#include "core/hle/service/hid/controllers/controller_base.h"
14#include "core/hle/service/hid/controllers/debug_pad.h" 13#include "core/hle/service/hid/controllers/debug_pad.h"
15#include "core/hle/service/hid/controllers/gesture.h" 14#include "core/hle/service/hid/controllers/gesture.h"
16#include "core/hle/service/hid/controllers/keyboard.h" 15#include "core/hle/service/hid/controllers/keyboard.h"
17#include "core/hle/service/hid/controllers/mouse.h" 16#include "core/hle/service/hid/controllers/mouse.h"
18#include "core/hle/service/hid/controllers/npad.h" 17#include "core/hle/service/hid/controllers/npad.h"
19#include "core/hle/service/hid/controllers/palma.h" 18#include "core/hle/service/hid/controllers/palma.h"
19#include "core/hle/service/hid/controllers/seven_six_axis.h"
20#include "core/hle/service/hid/controllers/six_axis.h"
20#include "core/hle/service/hid/controllers/stubbed.h" 21#include "core/hle/service/hid/controllers/stubbed.h"
21#include "core/hle/service/hid/controllers/touchscreen.h" 22#include "core/hle/service/hid/controllers/touchscreen.h"
22#include "core/hle/service/hid/controllers/xpad.h" 23#include "core/hle/service/hid/controllers/xpad.h"
@@ -42,76 +43,132 @@ void ResourceManager::Initialize() {
42 } 43 }
43 44
44 u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); 45 u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
45 MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory); 46 debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory);
46 MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory); 47 mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory);
47 MakeController<Controller_Mouse>(HidController::Mouse, shared_memory); 48 debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory);
48 MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory); 49 keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory);
49 MakeController<Controller_XPad>(HidController::XPad, shared_memory); 50 unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory);
50 MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory); 51 npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context);
51 MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory); 52 gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory);
52 MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory); 53 touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory);
53 MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory); 54 xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory);
54 MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory); 55
55 MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory); 56 palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context);
56 MakeController<Controller_Gesture>(HidController::Gesture, shared_memory); 57
57 MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory); 58 home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory);
58 MakeController<Controller_Stubbed>(HidController::DebugMouse, shared_memory); 59 sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory);
59 MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory); 60 capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory);
61
62 six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
63 console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory);
64 seven_six_axis = std::make_shared<SevenSixAxis>(system);
65
66 home_button->SetCommonHeaderOffset(0x4C00);
67 sleep_button->SetCommonHeaderOffset(0x4E00);
68 capture_button->SetCommonHeaderOffset(0x5000);
69 unique_pad->SetCommonHeaderOffset(0x5A00);
70 debug_mouse->SetCommonHeaderOffset(0x3DC00);
60 71
61 // Homebrew doesn't try to activate some controllers, so we activate them by default 72 // Homebrew doesn't try to activate some controllers, so we activate them by default
62 GetController<Controller_NPad>(HidController::NPad).Activate(); 73 npad->Activate();
63 GetController<Controller_Touchscreen>(HidController::Touchscreen).Activate(); 74 six_axis->Activate();
64 75 touch_screen->Activate();
65 GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
66 GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
67 GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000);
68 GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200);
69 GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
70 GetController<Controller_Stubbed>(HidController::DebugMouse).SetCommonHeaderOffset(0x3DC00);
71 76
72 system.HIDCore().ReloadInputDevices(); 77 system.HIDCore().ReloadInputDevices();
73 is_initialized = true; 78 is_initialized = true;
74} 79}
80std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
81 return capture_button;
82}
83
84std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const {
85 return console_six_axis;
86}
87
88std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const {
89 return debug_mouse;
90}
91
92std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const {
93 return debug_pad;
94}
95
96std::shared_ptr<Gesture> ResourceManager::GetGesture() const {
97 return gesture;
98}
99
100std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const {
101 return home_button;
102}
103
104std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const {
105 return keyboard;
106}
107
108std::shared_ptr<Mouse> ResourceManager::GetMouse() const {
109 return mouse;
110}
111
112std::shared_ptr<NPad> ResourceManager::GetNpad() const {
113 return npad;
114}
115
116std::shared_ptr<Palma> ResourceManager::GetPalma() const {
117 return palma;
118}
119
120std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const {
121 return seven_six_axis;
122}
123
124std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const {
125 return six_axis;
126}
127
128std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const {
129 return sleep_button;
130}
131
132std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const {
133 return touch_screen;
134}
135
136std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
137 return unique_pad;
138}
75 139
76void ResourceManager::UpdateControllers(std::uintptr_t user_data, 140void ResourceManager::UpdateControllers(std::uintptr_t user_data,
77 std::chrono::nanoseconds ns_late) { 141 std::chrono::nanoseconds ns_late) {
78 auto& core_timing = system.CoreTiming(); 142 auto& core_timing = system.CoreTiming();
79 143 debug_pad->OnUpdate(core_timing);
80 for (const auto& controller : controllers) { 144 unique_pad->OnUpdate(core_timing);
81 // Keyboard has it's own update event 145 gesture->OnUpdate(core_timing);
82 if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) { 146 touch_screen->OnUpdate(core_timing);
83 continue; 147 palma->OnUpdate(core_timing);
84 } 148 home_button->OnUpdate(core_timing);
85 // Mouse has it's own update event 149 sleep_button->OnUpdate(core_timing);
86 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) { 150 capture_button->OnUpdate(core_timing);
87 continue; 151 xpad->OnUpdate(core_timing);
88 }
89 // Npad has it's own update event
90 if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
91 continue;
92 }
93 controller->OnUpdate(core_timing);
94 }
95} 152}
96 153
97void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 154void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
98 auto& core_timing = system.CoreTiming(); 155 auto& core_timing = system.CoreTiming();
99 156 npad->OnUpdate(core_timing);
100 controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
101} 157}
102 158
103void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data, 159void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data,
104 std::chrono::nanoseconds ns_late) { 160 std::chrono::nanoseconds ns_late) {
105 auto& core_timing = system.CoreTiming(); 161 auto& core_timing = system.CoreTiming();
106 162 mouse->OnUpdate(core_timing);
107 controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing); 163 debug_mouse->OnUpdate(core_timing);
108 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing); 164 keyboard->OnUpdate(core_timing);
109} 165}
110 166
111void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 167void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
112 auto& core_timing = system.CoreTiming(); 168 auto& core_timing = system.CoreTiming();
113 169 six_axis->OnUpdate(core_timing);
114 controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing); 170 seven_six_axis->OnUpdate(core_timing);
171 console_six_axis->OnUpdate(core_timing);
115} 172}
116 173
117IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource) 174IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource)
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
index 34dbf36bc..2b6a9b5e6 100644
--- a/src/core/hle/service/hid/resource_manager.h
+++ b/src/core/hle/service/hid/resource_manager.h
@@ -3,10 +3,6 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <chrono>
7
8#include "core/core.h"
9#include "core/hle/service/hid/controllers/controller_base.h"
10#include "core/hle/service/kernel_helpers.h" 6#include "core/hle/service/kernel_helpers.h"
11#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
12 8
@@ -14,74 +10,85 @@ namespace Core::Timing {
14struct EventType; 10struct EventType;
15} 11}
16 12
17namespace Core::HID {
18class HIDCore;
19}
20
21namespace Service::HID { 13namespace Service::HID {
14class Controller_Stubbed;
15class ConsoleSixAxis;
16class DebugPad;
17class Gesture;
18class Keyboard;
19class Mouse;
20class NPad;
21class Palma;
22class SevenSixAxis;
23class SixAxis;
24class TouchScreen;
25class XPad;
26
27using CaptureButton = Controller_Stubbed;
28using DebugMouse = Controller_Stubbed;
29using HomeButton = Controller_Stubbed;
30using SleepButton = Controller_Stubbed;
31using UniquePad = Controller_Stubbed;
22 32
23enum class HidController : std::size_t {
24 DebugPad,
25 Touchscreen,
26 Mouse,
27 Keyboard,
28 XPad,
29 HomeButton,
30 SleepButton,
31 CaptureButton,
32 InputDetector,
33 UniquePad,
34 NPad,
35 Gesture,
36 ConsoleSixAxisSensor,
37 DebugMouse,
38 Palma,
39
40 MaxControllers,
41};
42class ResourceManager { 33class ResourceManager {
34
43public: 35public:
44 explicit ResourceManager(Core::System& system_); 36 explicit ResourceManager(Core::System& system_);
45 ~ResourceManager(); 37 ~ResourceManager();
46 38
47 template <typename T>
48 T& GetController(HidController controller) {
49 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
50 }
51
52 template <typename T>
53 const T& GetController(HidController controller) const {
54 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
55 }
56
57 void Initialize(); 39 void Initialize();
58 40
41 std::shared_ptr<CaptureButton> GetCaptureButton() const;
42 std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
43 std::shared_ptr<DebugMouse> GetDebugMouse() const;
44 std::shared_ptr<DebugPad> GetDebugPad() const;
45 std::shared_ptr<Gesture> GetGesture() const;
46 std::shared_ptr<HomeButton> GetHomeButton() const;
47 std::shared_ptr<Keyboard> GetKeyboard() const;
48 std::shared_ptr<Mouse> GetMouse() const;
49 std::shared_ptr<NPad> GetNpad() const;
50 std::shared_ptr<Palma> GetPalma() const;
51 std::shared_ptr<SevenSixAxis> GetSevenSixAxis() const;
52 std::shared_ptr<SixAxis> GetSixAxis() const;
53 std::shared_ptr<SleepButton> GetSleepButton() const;
54 std::shared_ptr<TouchScreen> GetTouchScreen() const;
55 std::shared_ptr<UniquePad> GetUniquePad() const;
56
59 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 57 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
60 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 58 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
61 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 59 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
62 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 60 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
63 61
64private: 62private:
65 template <typename T>
66 void MakeController(HidController controller, u8* shared_memory) {
67 if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
68 controllers[static_cast<std::size_t>(controller)] =
69 std::make_unique<T>(system, shared_memory);
70 } else {
71 controllers[static_cast<std::size_t>(controller)] =
72 std::make_unique<T>(system.HIDCore(), shared_memory);
73 }
74 }
75
76 template <typename T>
77 void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
78 controllers[static_cast<std::size_t>(controller)] =
79 std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
80 }
81
82 bool is_initialized{false}; 63 bool is_initialized{false};
83 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 64
84 controllers{}; 65 std::shared_ptr<CaptureButton> capture_button = nullptr;
66 std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
67 std::shared_ptr<DebugMouse> debug_mouse = nullptr;
68 std::shared_ptr<DebugPad> debug_pad = nullptr;
69 std::shared_ptr<Gesture> gesture = nullptr;
70 std::shared_ptr<HomeButton> home_button = nullptr;
71 std::shared_ptr<Keyboard> keyboard = nullptr;
72 std::shared_ptr<Mouse> mouse = nullptr;
73 std::shared_ptr<NPad> npad = nullptr;
74 std::shared_ptr<Palma> palma = nullptr;
75 std::shared_ptr<SevenSixAxis> seven_six_axis = nullptr;
76 std::shared_ptr<SixAxis> six_axis = nullptr;
77 std::shared_ptr<SleepButton> sleep_button = nullptr;
78 std::shared_ptr<TouchScreen> touch_screen = nullptr;
79 std::shared_ptr<UniquePad> unique_pad = nullptr;
80 std::shared_ptr<XPad> xpad = nullptr;
81
82 // TODO: Create these resources
83 // std::shared_ptr<AudioControl> audio_control = nullptr;
84 // std::shared_ptr<ButtonConfig> button_config = nullptr;
85 // std::shared_ptr<Config> config = nullptr;
86 // std::shared_ptr<Connection> connection = nullptr;
87 // std::shared_ptr<CustomConfig> custom_config = nullptr;
88 // std::shared_ptr<Digitizer> digitizer = nullptr;
89 // std::shared_ptr<Hdls> hdls = nullptr;
90 // std::shared_ptr<PlayReport> play_report = nullptr;
91 // std::shared_ptr<Rail> rail = nullptr;
85 92
86 Core::System& system; 93 Core::System& system;
87 KernelHelpers::ServiceContext service_context; 94 KernelHelpers::ServiceContext service_context;
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index a71d26157..ad534177d 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -7,6 +7,7 @@
7#include "core/core.h" 7#include "core/core.h"
8#include "core/hid/hid_types.h" 8#include "core/hid/hid_types.h"
9#include "core/hle/kernel/k_event.h" 9#include "core/hle/kernel/k_event.h"
10#include "core/hle/service/hid/hid_util.h"
10#include "core/hle/service/ipc_helpers.h" 11#include "core/hle/service/ipc_helpers.h"
11#include "core/hle/service/nfc/common/device.h" 12#include "core/hle/service/nfc/common/device.h"
12#include "core/hle/service/nfc/common/device_manager.h" 13#include "core/hle/service/nfc/common/device_manager.h"
@@ -24,7 +25,7 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex
24 25
25 for (u32 device_index = 0; device_index < devices.size(); device_index++) { 26 for (u32 device_index = 0; device_index < devices.size(); device_index++) {
26 devices[device_index] = 27 devices[device_index] =
27 std::make_shared<NfcDevice>(Core::HID::IndexToNpadIdType(device_index), system, 28 std::make_shared<NfcDevice>(HID::IndexToNpadIdType(device_index), system,
28 service_context, availability_change_event); 29 service_context, availability_change_event);
29 } 30 }
30 31
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index da140c01c..db30ba598 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -68,10 +68,7 @@ u64 StandardVmCallbacks::HidKeysDown() {
68 return 0; 68 return 0;
69 } 69 }
70 70
71 const auto press_state = 71 const auto press_state = applet_resource->GetNpad()->GetAndResetPressState();
72 applet_resource
73 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)
74 .GetAndResetPressState();
75 return static_cast<u64>(press_state & HID::NpadButton::All); 72 return static_cast<u64>(press_state & HID::NpadButton::All);
76} 73}
77 74
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index cf9266d54..b65b9f2a2 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -4,7 +4,7 @@
4add_subdirectory(host_shaders) 4add_subdirectory(host_shaders)
5 5
6if(LIBVA_FOUND) 6if(LIBVA_FOUND)
7 set_source_files_properties(host1x/codecs/codec.cpp 7 set_source_files_properties(host1x/ffmpeg/ffmpeg.cpp
8 PROPERTIES COMPILE_DEFINITIONS LIBVA_FOUND=1) 8 PROPERTIES COMPILE_DEFINITIONS LIBVA_FOUND=1)
9 list(APPEND FFmpeg_LIBRARIES ${LIBVA_LIBRARIES}) 9 list(APPEND FFmpeg_LIBRARIES ${LIBVA_LIBRARIES})
10endif() 10endif()
@@ -66,6 +66,8 @@ add_library(video_core STATIC
66 host1x/codecs/vp9.cpp 66 host1x/codecs/vp9.cpp
67 host1x/codecs/vp9.h 67 host1x/codecs/vp9.h
68 host1x/codecs/vp9_types.h 68 host1x/codecs/vp9_types.h
69 host1x/ffmpeg/ffmpeg.cpp
70 host1x/ffmpeg/ffmpeg.h
69 host1x/control.cpp 71 host1x/control.cpp
70 host1x/control.h 72 host1x/control.h
71 host1x/host1x.cpp 73 host1x/host1x.cpp
diff --git a/src/video_core/host1x/codecs/codec.cpp b/src/video_core/host1x/codecs/codec.cpp
index dbcf508e5..1030db681 100644
--- a/src/video_core/host1x/codecs/codec.cpp
+++ b/src/video_core/host1x/codecs/codec.cpp
@@ -1,11 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm>
5#include <fstream>
6#include <vector>
7#include "common/assert.h" 4#include "common/assert.h"
8#include "common/scope_exit.h"
9#include "common/settings.h" 5#include "common/settings.h"
10#include "video_core/host1x/codecs/codec.h" 6#include "video_core/host1x/codecs/codec.h"
11#include "video_core/host1x/codecs/h264.h" 7#include "video_core/host1x/codecs/h264.h"
@@ -14,242 +10,17 @@
14#include "video_core/host1x/host1x.h" 10#include "video_core/host1x/host1x.h"
15#include "video_core/memory_manager.h" 11#include "video_core/memory_manager.h"
16 12
17extern "C" {
18#include <libavfilter/buffersink.h>
19#include <libavfilter/buffersrc.h>
20#include <libavutil/opt.h>
21#ifdef LIBVA_FOUND
22// for querying VAAPI driver information
23#include <libavutil/hwcontext_vaapi.h>
24#endif
25}
26
27namespace Tegra { 13namespace Tegra {
28namespace {
29constexpr AVPixelFormat PREFERRED_GPU_FMT = AV_PIX_FMT_NV12;
30constexpr AVPixelFormat PREFERRED_CPU_FMT = AV_PIX_FMT_YUV420P;
31constexpr std::array PREFERRED_GPU_DECODERS = {
32 AV_HWDEVICE_TYPE_CUDA,
33#ifdef _WIN32
34 AV_HWDEVICE_TYPE_D3D11VA,
35 AV_HWDEVICE_TYPE_DXVA2,
36#elif defined(__unix__)
37 AV_HWDEVICE_TYPE_VAAPI,
38 AV_HWDEVICE_TYPE_VDPAU,
39#endif
40 // last resort for Linux Flatpak (w/ NVIDIA)
41 AV_HWDEVICE_TYPE_VULKAN,
42};
43
44void AVPacketDeleter(AVPacket* ptr) {
45 av_packet_free(&ptr);
46}
47
48using AVPacketPtr = std::unique_ptr<AVPacket, decltype(&AVPacketDeleter)>;
49
50AVPixelFormat GetGpuFormat(AVCodecContext* av_codec_ctx, const AVPixelFormat* pix_fmts) {
51 for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) {
52 if (*p == av_codec_ctx->pix_fmt) {
53 return av_codec_ctx->pix_fmt;
54 }
55 }
56 LOG_INFO(Service_NVDRV, "Could not find compatible GPU AV format, falling back to CPU");
57 av_buffer_unref(&av_codec_ctx->hw_device_ctx);
58 av_codec_ctx->pix_fmt = PREFERRED_CPU_FMT;
59 return PREFERRED_CPU_FMT;
60}
61
62// List all the currently available hwcontext in ffmpeg
63std::vector<AVHWDeviceType> ListSupportedContexts() {
64 std::vector<AVHWDeviceType> contexts{};
65 AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
66 do {
67 current_device_type = av_hwdevice_iterate_types(current_device_type);
68 contexts.push_back(current_device_type);
69 } while (current_device_type != AV_HWDEVICE_TYPE_NONE);
70 return contexts;
71}
72
73} // namespace
74
75void AVFrameDeleter(AVFrame* ptr) {
76 av_frame_free(&ptr);
77}
78 14
79Codec::Codec(Host1x::Host1x& host1x_, const Host1x::NvdecCommon::NvdecRegisters& regs) 15Codec::Codec(Host1x::Host1x& host1x_, const Host1x::NvdecCommon::NvdecRegisters& regs)
80 : host1x(host1x_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(host1x)), 16 : host1x(host1x_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(host1x)),
81 vp8_decoder(std::make_unique<Decoder::VP8>(host1x)), 17 vp8_decoder(std::make_unique<Decoder::VP8>(host1x)),
82 vp9_decoder(std::make_unique<Decoder::VP9>(host1x)) {} 18 vp9_decoder(std::make_unique<Decoder::VP9>(host1x)) {}
83 19
84Codec::~Codec() { 20Codec::~Codec() = default;
85 if (!initialized) {
86 return;
87 }
88 // Free libav memory
89 avcodec_free_context(&av_codec_ctx);
90 av_buffer_unref(&av_gpu_decoder);
91
92 if (filters_initialized) {
93 avfilter_graph_free(&av_filter_graph);
94 }
95}
96
97bool Codec::CreateGpuAvDevice() {
98 static constexpr auto HW_CONFIG_METHOD = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX;
99 static const auto supported_contexts = ListSupportedContexts();
100 for (const auto& type : PREFERRED_GPU_DECODERS) {
101 if (std::none_of(supported_contexts.begin(), supported_contexts.end(),
102 [&type](const auto& context) { return context == type; })) {
103 LOG_DEBUG(Service_NVDRV, "{} explicitly unsupported", av_hwdevice_get_type_name(type));
104 continue;
105 }
106 // Avoid memory leak from not cleaning up after av_hwdevice_ctx_create
107 av_buffer_unref(&av_gpu_decoder);
108 const int hwdevice_res = av_hwdevice_ctx_create(&av_gpu_decoder, type, nullptr, nullptr, 0);
109 if (hwdevice_res < 0) {
110 LOG_DEBUG(Service_NVDRV, "{} av_hwdevice_ctx_create failed {}",
111 av_hwdevice_get_type_name(type), hwdevice_res);
112 continue;
113 }
114#ifdef LIBVA_FOUND
115 if (type == AV_HWDEVICE_TYPE_VAAPI) {
116 // we need to determine if this is an impersonated VAAPI driver
117 AVHWDeviceContext* hwctx =
118 static_cast<AVHWDeviceContext*>(static_cast<void*>(av_gpu_decoder->data));
119 AVVAAPIDeviceContext* vactx = static_cast<AVVAAPIDeviceContext*>(hwctx->hwctx);
120 const char* vendor_name = vaQueryVendorString(vactx->display);
121 if (strstr(vendor_name, "VDPAU backend")) {
122 // VDPAU impersonated VAAPI impl's are super buggy, we need to skip them
123 LOG_DEBUG(Service_NVDRV, "Skipping vdapu impersonated VAAPI driver");
124 continue;
125 } else {
126 // according to some user testing, certain vaapi driver (Intel?) could be buggy
127 // so let's log the driver name which may help the developers/supporters
128 LOG_DEBUG(Service_NVDRV, "Using VAAPI driver: {}", vendor_name);
129 }
130 }
131#endif
132 for (int i = 0;; i++) {
133 const AVCodecHWConfig* config = avcodec_get_hw_config(av_codec, i);
134 if (!config) {
135 LOG_DEBUG(Service_NVDRV, "{} decoder does not support device type {}.",
136 av_codec->name, av_hwdevice_get_type_name(type));
137 break;
138 }
139 if ((config->methods & HW_CONFIG_METHOD) != 0 && config->device_type == type) {
140 LOG_INFO(Service_NVDRV, "Using {} GPU decoder", av_hwdevice_get_type_name(type));
141 av_codec_ctx->pix_fmt = config->pix_fmt;
142 return true;
143 }
144 }
145 }
146 return false;
147}
148
149void Codec::InitializeAvCodecContext() {
150 av_codec_ctx = avcodec_alloc_context3(av_codec);
151 av_opt_set(av_codec_ctx->priv_data, "tune", "zerolatency", 0);
152 av_codec_ctx->thread_count = 0;
153 av_codec_ctx->thread_type &= ~FF_THREAD_FRAME;
154}
155
156void Codec::InitializeGpuDecoder() {
157 if (!CreateGpuAvDevice()) {
158 av_buffer_unref(&av_gpu_decoder);
159 return;
160 }
161 auto* hw_device_ctx = av_buffer_ref(av_gpu_decoder);
162 ASSERT_MSG(hw_device_ctx, "av_buffer_ref failed");
163 av_codec_ctx->hw_device_ctx = hw_device_ctx;
164 av_codec_ctx->get_format = GetGpuFormat;
165}
166
167void Codec::InitializeAvFilters(AVFrame* frame) {
168 const AVFilter* buffer_src = avfilter_get_by_name("buffer");
169 const AVFilter* buffer_sink = avfilter_get_by_name("buffersink");
170 AVFilterInOut* inputs = avfilter_inout_alloc();
171 AVFilterInOut* outputs = avfilter_inout_alloc();
172 SCOPE_EXIT({
173 avfilter_inout_free(&inputs);
174 avfilter_inout_free(&outputs);
175 });
176
177 // Don't know how to get the accurate time_base but it doesn't matter for yadif filter
178 // so just use 1/1 to make buffer filter happy
179 std::string args = fmt::format("video_size={}x{}:pix_fmt={}:time_base=1/1", frame->width,
180 frame->height, frame->format);
181
182 av_filter_graph = avfilter_graph_alloc();
183 int ret = avfilter_graph_create_filter(&av_filter_src_ctx, buffer_src, "in", args.c_str(),
184 nullptr, av_filter_graph);
185 if (ret < 0) {
186 LOG_ERROR(Service_NVDRV, "avfilter_graph_create_filter source error: {}", ret);
187 return;
188 }
189
190 ret = avfilter_graph_create_filter(&av_filter_sink_ctx, buffer_sink, "out", nullptr, nullptr,
191 av_filter_graph);
192 if (ret < 0) {
193 LOG_ERROR(Service_NVDRV, "avfilter_graph_create_filter sink error: {}", ret);
194 return;
195 }
196
197 inputs->name = av_strdup("out");
198 inputs->filter_ctx = av_filter_sink_ctx;
199 inputs->pad_idx = 0;
200 inputs->next = nullptr;
201
202 outputs->name = av_strdup("in");
203 outputs->filter_ctx = av_filter_src_ctx;
204 outputs->pad_idx = 0;
205 outputs->next = nullptr;
206
207 const char* description = "yadif=1:-1:0";
208 ret = avfilter_graph_parse_ptr(av_filter_graph, description, &inputs, &outputs, nullptr);
209 if (ret < 0) {
210 LOG_ERROR(Service_NVDRV, "avfilter_graph_parse_ptr error: {}", ret);
211 return;
212 }
213
214 ret = avfilter_graph_config(av_filter_graph, nullptr);
215 if (ret < 0) {
216 LOG_ERROR(Service_NVDRV, "avfilter_graph_config error: {}", ret);
217 return;
218 }
219
220 filters_initialized = true;
221}
222 21
223void Codec::Initialize() { 22void Codec::Initialize() {
224 const AVCodecID codec = [&] { 23 initialized = decode_api.Initialize(current_codec);
225 switch (current_codec) {
226 case Host1x::NvdecCommon::VideoCodec::H264:
227 return AV_CODEC_ID_H264;
228 case Host1x::NvdecCommon::VideoCodec::VP8:
229 return AV_CODEC_ID_VP8;
230 case Host1x::NvdecCommon::VideoCodec::VP9:
231 return AV_CODEC_ID_VP9;
232 default:
233 UNIMPLEMENTED_MSG("Unknown codec {}", current_codec);
234 return AV_CODEC_ID_NONE;
235 }
236 }();
237 av_codec = avcodec_find_decoder(codec);
238
239 InitializeAvCodecContext();
240 if (Settings::values.nvdec_emulation.GetValue() == Settings::NvdecEmulation::Gpu) {
241 InitializeGpuDecoder();
242 }
243 if (const int res = avcodec_open2(av_codec_ctx, av_codec, nullptr); res < 0) {
244 LOG_ERROR(Service_NVDRV, "avcodec_open2() Failed with result {}", res);
245 avcodec_free_context(&av_codec_ctx);
246 av_buffer_unref(&av_gpu_decoder);
247 return;
248 }
249 if (!av_codec_ctx->hw_device_ctx) {
250 LOG_INFO(Service_NVDRV, "Using FFmpeg software decoding");
251 }
252 initialized = true;
253} 24}
254 25
255void Codec::SetTargetCodec(Host1x::NvdecCommon::VideoCodec codec) { 26void Codec::SetTargetCodec(Host1x::NvdecCommon::VideoCodec codec) {
@@ -264,14 +35,18 @@ void Codec::Decode() {
264 if (is_first_frame) { 35 if (is_first_frame) {
265 Initialize(); 36 Initialize();
266 } 37 }
38
267 if (!initialized) { 39 if (!initialized) {
268 return; 40 return;
269 } 41 }
42
43 // Assemble bitstream.
270 bool vp9_hidden_frame = false; 44 bool vp9_hidden_frame = false;
271 const auto& frame_data = [&]() { 45 size_t configuration_size = 0;
46 const auto packet_data = [&]() {
272 switch (current_codec) { 47 switch (current_codec) {
273 case Tegra::Host1x::NvdecCommon::VideoCodec::H264: 48 case Tegra::Host1x::NvdecCommon::VideoCodec::H264:
274 return h264_decoder->ComposeFrame(state, is_first_frame); 49 return h264_decoder->ComposeFrame(state, &configuration_size, is_first_frame);
275 case Tegra::Host1x::NvdecCommon::VideoCodec::VP8: 50 case Tegra::Host1x::NvdecCommon::VideoCodec::VP8:
276 return vp8_decoder->ComposeFrame(state); 51 return vp8_decoder->ComposeFrame(state);
277 case Tegra::Host1x::NvdecCommon::VideoCodec::VP9: 52 case Tegra::Host1x::NvdecCommon::VideoCodec::VP9:
@@ -283,89 +58,35 @@ void Codec::Decode() {
283 return std::span<const u8>{}; 58 return std::span<const u8>{};
284 } 59 }
285 }(); 60 }();
286 AVPacketPtr packet{av_packet_alloc(), AVPacketDeleter}; 61
287 if (!packet) { 62 // Send assembled bitstream to decoder.
288 LOG_ERROR(Service_NVDRV, "av_packet_alloc failed"); 63 if (!decode_api.SendPacket(packet_data, configuration_size)) {
289 return;
290 }
291 packet->data = const_cast<u8*>(frame_data.data());
292 packet->size = static_cast<s32>(frame_data.size());
293 if (const int res = avcodec_send_packet(av_codec_ctx, packet.get()); res != 0) {
294 LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", res);
295 return; 64 return;
296 } 65 }
297 // Only receive/store visible frames 66
67 // Only receive/store visible frames.
298 if (vp9_hidden_frame) { 68 if (vp9_hidden_frame) {
299 return; 69 return;
300 } 70 }
301 AVFramePtr initial_frame{av_frame_alloc(), AVFrameDeleter};
302 AVFramePtr final_frame{nullptr, AVFrameDeleter};
303 ASSERT_MSG(initial_frame, "av_frame_alloc initial_frame failed");
304 if (const int ret = avcodec_receive_frame(av_codec_ctx, initial_frame.get()); ret) {
305 LOG_DEBUG(Service_NVDRV, "avcodec_receive_frame error {}", ret);
306 return;
307 }
308 if (initial_frame->width == 0 || initial_frame->height == 0) {
309 LOG_WARNING(Service_NVDRV, "Zero width or height in frame");
310 return;
311 }
312 bool is_interlaced = initial_frame->interlaced_frame != 0;
313 if (av_codec_ctx->hw_device_ctx) {
314 final_frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
315 ASSERT_MSG(final_frame, "av_frame_alloc final_frame failed");
316 // Can't use AV_PIX_FMT_YUV420P and share code with software decoding in vic.cpp
317 // because Intel drivers crash unless using AV_PIX_FMT_NV12
318 final_frame->format = PREFERRED_GPU_FMT;
319 const int ret = av_hwframe_transfer_data(final_frame.get(), initial_frame.get(), 0);
320 ASSERT_MSG(!ret, "av_hwframe_transfer_data error {}", ret);
321 } else {
322 final_frame = std::move(initial_frame);
323 }
324 if (final_frame->format != PREFERRED_CPU_FMT && final_frame->format != PREFERRED_GPU_FMT) {
325 UNIMPLEMENTED_MSG("Unexpected video format: {}", final_frame->format);
326 return;
327 }
328 if (!is_interlaced) {
329 av_frames.push(std::move(final_frame));
330 } else {
331 if (!filters_initialized) {
332 InitializeAvFilters(final_frame.get());
333 }
334 if (const int ret = av_buffersrc_add_frame_flags(av_filter_src_ctx, final_frame.get(),
335 AV_BUFFERSRC_FLAG_KEEP_REF);
336 ret) {
337 LOG_DEBUG(Service_NVDRV, "av_buffersrc_add_frame_flags error {}", ret);
338 return;
339 }
340 while (true) {
341 auto filter_frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
342 71
343 int ret = av_buffersink_get_frame(av_filter_sink_ctx, filter_frame.get()); 72 // Receive output frames from decoder.
73 decode_api.ReceiveFrames(frames);
344 74
345 if (ret == AVERROR(EAGAIN) || ret == AVERROR(AVERROR_EOF)) 75 while (frames.size() > 10) {
346 break; 76 LOG_DEBUG(HW_GPU, "ReceiveFrames overflow, dropped frame");
347 if (ret < 0) { 77 frames.pop();
348 LOG_DEBUG(Service_NVDRV, "av_buffersink_get_frame error {}", ret);
349 return;
350 }
351
352 av_frames.push(std::move(filter_frame));
353 }
354 }
355 while (av_frames.size() > 10) {
356 LOG_TRACE(Service_NVDRV, "av_frames.push overflow dropped frame");
357 av_frames.pop();
358 } 78 }
359} 79}
360 80
361AVFramePtr Codec::GetCurrentFrame() { 81std::unique_ptr<FFmpeg::Frame> Codec::GetCurrentFrame() {
362 // Sometimes VIC will request more frames than have been decoded. 82 // Sometimes VIC will request more frames than have been decoded.
363 // in this case, return a nullptr and don't overwrite previous frame data 83 // in this case, return a blank frame and don't overwrite previous data.
364 if (av_frames.empty()) { 84 if (frames.empty()) {
365 return AVFramePtr{nullptr, AVFrameDeleter}; 85 return {};
366 } 86 }
367 AVFramePtr frame = std::move(av_frames.front()); 87
368 av_frames.pop(); 88 auto frame = std::move(frames.front());
89 frames.pop();
369 return frame; 90 return frame;
370} 91}
371 92
diff --git a/src/video_core/host1x/codecs/codec.h b/src/video_core/host1x/codecs/codec.h
index 06fe00a4b..f700ae129 100644
--- a/src/video_core/host1x/codecs/codec.h
+++ b/src/video_core/host1x/codecs/codec.h
@@ -4,28 +4,15 @@
4#pragma once 4#pragma once
5 5
6#include <memory> 6#include <memory>
7#include <optional>
7#include <string_view> 8#include <string_view>
8#include <queue> 9#include <queue>
9#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/host1x/ffmpeg/ffmpeg.h"
10#include "video_core/host1x/nvdec_common.h" 12#include "video_core/host1x/nvdec_common.h"
11 13
12extern "C" {
13#if defined(__GNUC__) || defined(__clang__)
14#pragma GCC diagnostic push
15#pragma GCC diagnostic ignored "-Wconversion"
16#endif
17#include <libavcodec/avcodec.h>
18#include <libavfilter/avfilter.h>
19#if defined(__GNUC__) || defined(__clang__)
20#pragma GCC diagnostic pop
21#endif
22}
23
24namespace Tegra { 14namespace Tegra {
25 15
26void AVFrameDeleter(AVFrame* ptr);
27using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>;
28
29namespace Decoder { 16namespace Decoder {
30class H264; 17class H264;
31class VP8; 18class VP8;
@@ -51,7 +38,7 @@ public:
51 void Decode(); 38 void Decode();
52 39
53 /// Returns next decoded frame 40 /// Returns next decoded frame
54 [[nodiscard]] AVFramePtr GetCurrentFrame(); 41 [[nodiscard]] std::unique_ptr<FFmpeg::Frame> GetCurrentFrame();
55 42
56 /// Returns the value of current_codec 43 /// Returns the value of current_codec
57 [[nodiscard]] Host1x::NvdecCommon::VideoCodec GetCurrentCodec() const; 44 [[nodiscard]] Host1x::NvdecCommon::VideoCodec GetCurrentCodec() const;
@@ -60,25 +47,9 @@ public:
60 [[nodiscard]] std::string_view GetCurrentCodecName() const; 47 [[nodiscard]] std::string_view GetCurrentCodecName() const;
61 48
62private: 49private:
63 void InitializeAvCodecContext();
64
65 void InitializeAvFilters(AVFrame* frame);
66
67 void InitializeGpuDecoder();
68
69 bool CreateGpuAvDevice();
70
71 bool initialized{}; 50 bool initialized{};
72 bool filters_initialized{};
73 Host1x::NvdecCommon::VideoCodec current_codec{Host1x::NvdecCommon::VideoCodec::None}; 51 Host1x::NvdecCommon::VideoCodec current_codec{Host1x::NvdecCommon::VideoCodec::None};
74 52 FFmpeg::DecodeApi decode_api;
75 const AVCodec* av_codec{nullptr};
76 AVCodecContext* av_codec_ctx{nullptr};
77 AVBufferRef* av_gpu_decoder{nullptr};
78
79 AVFilterContext* av_filter_src_ctx{nullptr};
80 AVFilterContext* av_filter_sink_ctx{nullptr};
81 AVFilterGraph* av_filter_graph{nullptr};
82 53
83 Host1x::Host1x& host1x; 54 Host1x::Host1x& host1x;
84 const Host1x::NvdecCommon::NvdecRegisters& state; 55 const Host1x::NvdecCommon::NvdecRegisters& state;
@@ -86,7 +57,7 @@ private:
86 std::unique_ptr<Decoder::VP8> vp8_decoder; 57 std::unique_ptr<Decoder::VP8> vp8_decoder;
87 std::unique_ptr<Decoder::VP9> vp9_decoder; 58 std::unique_ptr<Decoder::VP9> vp9_decoder;
88 59
89 std::queue<AVFramePtr> av_frames{}; 60 std::queue<std::unique_ptr<FFmpeg::Frame>> frames{};
90}; 61};
91 62
92} // namespace Tegra 63} // namespace Tegra
diff --git a/src/video_core/host1x/codecs/h264.cpp b/src/video_core/host1x/codecs/h264.cpp
index ece79b1e2..309a7f1d5 100644
--- a/src/video_core/host1x/codecs/h264.cpp
+++ b/src/video_core/host1x/codecs/h264.cpp
@@ -30,7 +30,7 @@ H264::H264(Host1x::Host1x& host1x_) : host1x{host1x_} {}
30H264::~H264() = default; 30H264::~H264() = default;
31 31
32std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state, 32std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state,
33 bool is_first_frame) { 33 size_t* out_configuration_size, bool is_first_frame) {
34 H264DecoderContext context; 34 H264DecoderContext context;
35 host1x.MemoryManager().ReadBlock(state.picture_info_offset, &context, 35 host1x.MemoryManager().ReadBlock(state.picture_info_offset, &context,
36 sizeof(H264DecoderContext)); 36 sizeof(H264DecoderContext));
@@ -39,6 +39,7 @@ std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters
39 if (!is_first_frame && frame_number != 0) { 39 if (!is_first_frame && frame_number != 0) {
40 frame.resize_destructive(context.stream_len); 40 frame.resize_destructive(context.stream_len);
41 host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size()); 41 host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size());
42 *out_configuration_size = 0;
42 return frame; 43 return frame;
43 } 44 }
44 45
@@ -157,6 +158,7 @@ std::span<const u8> H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters
157 frame.resize(encoded_header.size() + context.stream_len); 158 frame.resize(encoded_header.size() + context.stream_len);
158 std::memcpy(frame.data(), encoded_header.data(), encoded_header.size()); 159 std::memcpy(frame.data(), encoded_header.data(), encoded_header.size());
159 160
161 *out_configuration_size = encoded_header.size();
160 host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, 162 host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset,
161 frame.data() + encoded_header.size(), context.stream_len); 163 frame.data() + encoded_header.size(), context.stream_len);
162 164
diff --git a/src/video_core/host1x/codecs/h264.h b/src/video_core/host1x/codecs/h264.h
index d6b556322..1deaf4632 100644
--- a/src/video_core/host1x/codecs/h264.h
+++ b/src/video_core/host1x/codecs/h264.h
@@ -67,6 +67,7 @@ public:
67 67
68 /// Compose the H264 frame for FFmpeg decoding 68 /// Compose the H264 frame for FFmpeg decoding
69 [[nodiscard]] std::span<const u8> ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state, 69 [[nodiscard]] std::span<const u8> ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state,
70 size_t* out_configuration_size,
70 bool is_first_frame = false); 71 bool is_first_frame = false);
71 72
72private: 73private:
diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp
new file mode 100644
index 000000000..dcd07e6d2
--- /dev/null
+++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp
@@ -0,0 +1,419 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/assert.h"
5#include "common/logging/log.h"
6#include "common/scope_exit.h"
7#include "common/settings.h"
8#include "video_core/host1x/ffmpeg/ffmpeg.h"
9
10extern "C" {
11#ifdef LIBVA_FOUND
12// for querying VAAPI driver information
13#include <libavutil/hwcontext_vaapi.h>
14#endif
15}
16
17namespace FFmpeg {
18
19namespace {
20
21constexpr AVPixelFormat PreferredGpuFormat = AV_PIX_FMT_NV12;
22constexpr AVPixelFormat PreferredCpuFormat = AV_PIX_FMT_YUV420P;
23constexpr std::array PreferredGpuDecoders = {
24 AV_HWDEVICE_TYPE_CUDA,
25#ifdef _WIN32
26 AV_HWDEVICE_TYPE_D3D11VA,
27 AV_HWDEVICE_TYPE_DXVA2,
28#elif defined(__unix__)
29 AV_HWDEVICE_TYPE_VAAPI,
30 AV_HWDEVICE_TYPE_VDPAU,
31#endif
32 // last resort for Linux Flatpak (w/ NVIDIA)
33 AV_HWDEVICE_TYPE_VULKAN,
34};
35
36AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) {
37 for (const AVPixelFormat* p = pix_fmts; *p != AV_PIX_FMT_NONE; ++p) {
38 if (*p == codec_context->pix_fmt) {
39 return codec_context->pix_fmt;
40 }
41 }
42
43 LOG_INFO(HW_GPU, "Could not find compatible GPU AV format, falling back to CPU");
44 av_buffer_unref(&codec_context->hw_device_ctx);
45
46 codec_context->pix_fmt = PreferredCpuFormat;
47 return codec_context->pix_fmt;
48}
49
50std::string AVError(int errnum) {
51 char errbuf[AV_ERROR_MAX_STRING_SIZE] = {};
52 av_make_error_string(errbuf, sizeof(errbuf) - 1, errnum);
53 return errbuf;
54}
55
56} // namespace
57
58Packet::Packet(std::span<const u8> data) {
59 m_packet = av_packet_alloc();
60 m_packet->data = const_cast<u8*>(data.data());
61 m_packet->size = static_cast<s32>(data.size());
62}
63
64Packet::~Packet() {
65 av_packet_free(&m_packet);
66}
67
68Frame::Frame() {
69 m_frame = av_frame_alloc();
70}
71
72Frame::~Frame() {
73 av_frame_free(&m_frame);
74}
75
76Decoder::Decoder(Tegra::Host1x::NvdecCommon::VideoCodec codec) {
77 const AVCodecID av_codec = [&] {
78 switch (codec) {
79 case Tegra::Host1x::NvdecCommon::VideoCodec::H264:
80 return AV_CODEC_ID_H264;
81 case Tegra::Host1x::NvdecCommon::VideoCodec::VP8:
82 return AV_CODEC_ID_VP8;
83 case Tegra::Host1x::NvdecCommon::VideoCodec::VP9:
84 return AV_CODEC_ID_VP9;
85 default:
86 UNIMPLEMENTED_MSG("Unknown codec {}", codec);
87 return AV_CODEC_ID_NONE;
88 }
89 }();
90
91 m_codec = avcodec_find_decoder(av_codec);
92}
93
94bool Decoder::SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceType type) const {
95 for (int i = 0;; i++) {
96 const AVCodecHWConfig* config = avcodec_get_hw_config(m_codec, i);
97 if (!config) {
98 LOG_DEBUG(HW_GPU, "{} decoder does not support device type {}", m_codec->name,
99 av_hwdevice_get_type_name(type));
100 break;
101 }
102 if ((config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
103 config->device_type == type) {
104 LOG_INFO(HW_GPU, "Using {} GPU decoder", av_hwdevice_get_type_name(type));
105 *out_pix_fmt = config->pix_fmt;
106 return true;
107 }
108 }
109
110 return false;
111}
112
113std::vector<AVHWDeviceType> HardwareContext::GetSupportedDeviceTypes() {
114 std::vector<AVHWDeviceType> types;
115 AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE;
116
117 while (true) {
118 current_device_type = av_hwdevice_iterate_types(current_device_type);
119 if (current_device_type == AV_HWDEVICE_TYPE_NONE) {
120 return types;
121 }
122
123 types.push_back(current_device_type);
124 }
125}
126
127HardwareContext::~HardwareContext() {
128 av_buffer_unref(&m_gpu_decoder);
129}
130
131bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context,
132 const Decoder& decoder) {
133 const auto supported_types = GetSupportedDeviceTypes();
134 for (const auto type : PreferredGpuDecoders) {
135 AVPixelFormat hw_pix_fmt;
136
137 if (std::ranges::find(supported_types, type) == supported_types.end()) {
138 LOG_DEBUG(HW_GPU, "{} explicitly unsupported", av_hwdevice_get_type_name(type));
139 continue;
140 }
141
142 if (!this->InitializeWithType(type)) {
143 continue;
144 }
145
146 if (decoder.SupportsDecodingOnDevice(&hw_pix_fmt, type)) {
147 decoder_context.InitializeHardwareDecoder(*this, hw_pix_fmt);
148 return true;
149 }
150 }
151
152 return false;
153}
154
155bool HardwareContext::InitializeWithType(AVHWDeviceType type) {
156 av_buffer_unref(&m_gpu_decoder);
157
158 if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0);
159 ret < 0) {
160 LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type),
161 AVError(ret));
162 return false;
163 }
164
165#ifdef LIBVA_FOUND
166 if (type == AV_HWDEVICE_TYPE_VAAPI) {
167 // We need to determine if this is an impersonated VAAPI driver.
168 auto* hwctx = reinterpret_cast<AVHWDeviceContext*>(m_gpu_decoder->data);
169 auto* vactx = static_cast<AVVAAPIDeviceContext*>(hwctx->hwctx);
170 const char* vendor_name = vaQueryVendorString(vactx->display);
171 if (strstr(vendor_name, "VDPAU backend")) {
172 // VDPAU impersonated VAAPI impls are super buggy, we need to skip them.
173 LOG_DEBUG(HW_GPU, "Skipping VDPAU impersonated VAAPI driver");
174 return false;
175 } else {
176 // According to some user testing, certain VAAPI drivers (Intel?) could be buggy.
177 // Log the driver name just in case.
178 LOG_DEBUG(HW_GPU, "Using VAAPI driver: {}", vendor_name);
179 }
180 }
181#endif
182
183 return true;
184}
185
186DecoderContext::DecoderContext(const Decoder& decoder) {
187 m_codec_context = avcodec_alloc_context3(decoder.GetCodec());
188 av_opt_set(m_codec_context->priv_data, "tune", "zerolatency", 0);
189 m_codec_context->thread_count = 0;
190 m_codec_context->thread_type &= ~FF_THREAD_FRAME;
191}
192
193DecoderContext::~DecoderContext() {
194 av_buffer_unref(&m_codec_context->hw_device_ctx);
195 avcodec_free_context(&m_codec_context);
196}
197
198void DecoderContext::InitializeHardwareDecoder(const HardwareContext& context,
199 AVPixelFormat hw_pix_fmt) {
200 m_codec_context->hw_device_ctx = av_buffer_ref(context.GetBufferRef());
201 m_codec_context->get_format = GetGpuFormat;
202 m_codec_context->pix_fmt = hw_pix_fmt;
203}
204
205bool DecoderContext::OpenContext(const Decoder& decoder) {
206 if (const int ret = avcodec_open2(m_codec_context, decoder.GetCodec(), nullptr); ret < 0) {
207 LOG_ERROR(HW_GPU, "avcodec_open2 error: {}", AVError(ret));
208 return false;
209 }
210
211 if (!m_codec_context->hw_device_ctx) {
212 LOG_INFO(HW_GPU, "Using FFmpeg software decoding");
213 }
214
215 return true;
216}
217
218bool DecoderContext::SendPacket(const Packet& packet) {
219 if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0) {
220 LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret));
221 return false;
222 }
223
224 return true;
225}
226
227std::unique_ptr<Frame> DecoderContext::ReceiveFrame(bool* out_is_interlaced) {
228 auto dst_frame = std::make_unique<Frame>();
229
230 const auto ReceiveImpl = [&](AVFrame* frame) {
231 if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0) {
232 LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret));
233 return false;
234 }
235
236 *out_is_interlaced = frame->interlaced_frame != 0;
237 return true;
238 };
239
240 if (m_codec_context->hw_device_ctx) {
241 // If we have a hardware context, make a separate frame here to receive the
242 // hardware result before sending it to the output.
243 Frame intermediate_frame;
244
245 if (!ReceiveImpl(intermediate_frame.GetFrame())) {
246 return {};
247 }
248
249 dst_frame->SetFormat(PreferredGpuFormat);
250 if (const int ret =
251 av_hwframe_transfer_data(dst_frame->GetFrame(), intermediate_frame.GetFrame(), 0);
252 ret < 0) {
253 LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret));
254 return {};
255 }
256 } else {
257 // Otherwise, decode the frame as normal.
258 if (!ReceiveImpl(dst_frame->GetFrame())) {
259 return {};
260 }
261 }
262
263 return dst_frame;
264}
265
266DeinterlaceFilter::DeinterlaceFilter(const Frame& frame) {
267 const AVFilter* buffer_src = avfilter_get_by_name("buffer");
268 const AVFilter* buffer_sink = avfilter_get_by_name("buffersink");
269 AVFilterInOut* inputs = avfilter_inout_alloc();
270 AVFilterInOut* outputs = avfilter_inout_alloc();
271 SCOPE_EXIT({
272 avfilter_inout_free(&inputs);
273 avfilter_inout_free(&outputs);
274 });
275
276 // Don't know how to get the accurate time_base but it doesn't matter for yadif filter
277 // so just use 1/1 to make buffer filter happy
278 std::string args = fmt::format("video_size={}x{}:pix_fmt={}:time_base=1/1", frame.GetWidth(),
279 frame.GetHeight(), static_cast<int>(frame.GetPixelFormat()));
280
281 m_filter_graph = avfilter_graph_alloc();
282 int ret = avfilter_graph_create_filter(&m_source_context, buffer_src, "in", args.c_str(),
283 nullptr, m_filter_graph);
284 if (ret < 0) {
285 LOG_ERROR(HW_GPU, "avfilter_graph_create_filter source error: {}", AVError(ret));
286 return;
287 }
288
289 ret = avfilter_graph_create_filter(&m_sink_context, buffer_sink, "out", nullptr, nullptr,
290 m_filter_graph);
291 if (ret < 0) {
292 LOG_ERROR(HW_GPU, "avfilter_graph_create_filter sink error: {}", AVError(ret));
293 return;
294 }
295
296 inputs->name = av_strdup("out");
297 inputs->filter_ctx = m_sink_context;
298 inputs->pad_idx = 0;
299 inputs->next = nullptr;
300
301 outputs->name = av_strdup("in");
302 outputs->filter_ctx = m_source_context;
303 outputs->pad_idx = 0;
304 outputs->next = nullptr;
305
306 const char* description = "yadif=1:-1:0";
307 ret = avfilter_graph_parse_ptr(m_filter_graph, description, &inputs, &outputs, nullptr);
308 if (ret < 0) {
309 LOG_ERROR(HW_GPU, "avfilter_graph_parse_ptr error: {}", AVError(ret));
310 return;
311 }
312
313 ret = avfilter_graph_config(m_filter_graph, nullptr);
314 if (ret < 0) {
315 LOG_ERROR(HW_GPU, "avfilter_graph_config error: {}", AVError(ret));
316 return;
317 }
318
319 m_initialized = true;
320}
321
322bool DeinterlaceFilter::AddSourceFrame(const Frame& frame) {
323 if (const int ret = av_buffersrc_add_frame_flags(m_source_context, frame.GetFrame(),
324 AV_BUFFERSRC_FLAG_KEEP_REF);
325 ret < 0) {
326 LOG_ERROR(HW_GPU, "av_buffersrc_add_frame_flags error: {}", AVError(ret));
327 return false;
328 }
329
330 return true;
331}
332
333std::unique_ptr<Frame> DeinterlaceFilter::DrainSinkFrame() {
334 auto dst_frame = std::make_unique<Frame>();
335 const int ret = av_buffersink_get_frame(m_sink_context, dst_frame->GetFrame());
336
337 if (ret == AVERROR(EAGAIN) || ret == AVERROR(AVERROR_EOF)) {
338 return {};
339 }
340
341 if (ret < 0) {
342 LOG_ERROR(HW_GPU, "av_buffersink_get_frame error: {}", AVError(ret));
343 return {};
344 }
345
346 return dst_frame;
347}
348
349DeinterlaceFilter::~DeinterlaceFilter() {
350 avfilter_graph_free(&m_filter_graph);
351}
352
353void DecodeApi::Reset() {
354 m_deinterlace_filter.reset();
355 m_hardware_context.reset();
356 m_decoder_context.reset();
357 m_decoder.reset();
358}
359
360bool DecodeApi::Initialize(Tegra::Host1x::NvdecCommon::VideoCodec codec) {
361 this->Reset();
362 m_decoder.emplace(codec);
363 m_decoder_context.emplace(*m_decoder);
364
365 // Enable GPU decoding if requested.
366 if (Settings::values.nvdec_emulation.GetValue() == Settings::NvdecEmulation::Gpu) {
367 m_hardware_context.emplace();
368 m_hardware_context->InitializeForDecoder(*m_decoder_context, *m_decoder);
369 }
370
371 // Open the decoder context.
372 if (!m_decoder_context->OpenContext(*m_decoder)) {
373 this->Reset();
374 return false;
375 }
376
377 return true;
378}
379
380bool DecodeApi::SendPacket(std::span<const u8> packet_data, size_t configuration_size) {
381 FFmpeg::Packet packet(packet_data);
382 return m_decoder_context->SendPacket(packet);
383}
384
385void DecodeApi::ReceiveFrames(std::queue<std::unique_ptr<Frame>>& frame_queue) {
386 // Receive raw frame from decoder.
387 bool is_interlaced;
388 auto frame = m_decoder_context->ReceiveFrame(&is_interlaced);
389 if (!frame) {
390 return;
391 }
392
393 if (!is_interlaced) {
394 // If the frame is not interlaced, we can pend it now.
395 frame_queue.push(std::move(frame));
396 } else {
397 // Create the deinterlacer if needed.
398 if (!m_deinterlace_filter) {
399 m_deinterlace_filter.emplace(*frame);
400 }
401
402 // Add the frame we just received.
403 if (!m_deinterlace_filter->AddSourceFrame(*frame)) {
404 return;
405 }
406
407 // Pend output fields.
408 while (true) {
409 auto filter_frame = m_deinterlace_filter->DrainSinkFrame();
410 if (!filter_frame) {
411 break;
412 }
413
414 frame_queue.push(std::move(filter_frame));
415 }
416 }
417}
418
419} // namespace FFmpeg
diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.h b/src/video_core/host1x/ffmpeg/ffmpeg.h
new file mode 100644
index 000000000..1de0bbd83
--- /dev/null
+++ b/src/video_core/host1x/ffmpeg/ffmpeg.h
@@ -0,0 +1,213 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <optional>
8#include <span>
9#include <vector>
10#include <queue>
11
12#include "common/common_funcs.h"
13#include "common/common_types.h"
14#include "video_core/host1x/nvdec_common.h"
15
16extern "C" {
17#if defined(__GNUC__) || defined(__clang__)
18#pragma GCC diagnostic push
19#pragma GCC diagnostic ignored "-Wconversion"
20#endif
21
22#include <libavcodec/avcodec.h>
23#include <libavfilter/avfilter.h>
24#include <libavfilter/buffersink.h>
25#include <libavfilter/buffersrc.h>
26#include <libavutil/avutil.h>
27#include <libavutil/opt.h>
28
29#if defined(__GNUC__) || defined(__clang__)
30#pragma GCC diagnostic pop
31#endif
32}
33
34namespace FFmpeg {
35
36class Packet;
37class Frame;
38class Decoder;
39class HardwareContext;
40class DecoderContext;
41class DeinterlaceFilter;
42
43// Wraps an AVPacket, a container for compressed bitstream data.
44class Packet {
45public:
46 YUZU_NON_COPYABLE(Packet);
47 YUZU_NON_MOVEABLE(Packet);
48
49 explicit Packet(std::span<const u8> data);
50 ~Packet();
51
52 AVPacket* GetPacket() const {
53 return m_packet;
54 }
55
56private:
57 AVPacket* m_packet{};
58};
59
60// Wraps an AVFrame, a container for audio and video stream data.
61class Frame {
62public:
63 YUZU_NON_COPYABLE(Frame);
64 YUZU_NON_MOVEABLE(Frame);
65
66 explicit Frame();
67 ~Frame();
68
69 int GetWidth() const {
70 return m_frame->width;
71 }
72
73 int GetHeight() const {
74 return m_frame->height;
75 }
76
77 AVPixelFormat GetPixelFormat() const {
78 return static_cast<AVPixelFormat>(m_frame->format);
79 }
80
81 int GetStride(int plane) const {
82 return m_frame->linesize[plane];
83 }
84
85 int* GetStrides() const {
86 return m_frame->linesize;
87 }
88
89 u8* GetData(int plane) const {
90 return m_frame->data[plane];
91 }
92
93 u8** GetPlanes() const {
94 return m_frame->data;
95 }
96
97 void SetFormat(int format) {
98 m_frame->format = format;
99 }
100
101 AVFrame* GetFrame() const {
102 return m_frame;
103 }
104
105private:
106 AVFrame* m_frame{};
107};
108
109// Wraps an AVCodec, a type containing information about a codec.
110class Decoder {
111public:
112 YUZU_NON_COPYABLE(Decoder);
113 YUZU_NON_MOVEABLE(Decoder);
114
115 explicit Decoder(Tegra::Host1x::NvdecCommon::VideoCodec codec);
116 ~Decoder() = default;
117
118 bool SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceType type) const;
119
120 const AVCodec* GetCodec() const {
121 return m_codec;
122 }
123
124private:
125 const AVCodec* m_codec{};
126};
127
128// Wraps AVBufferRef for an accelerated decoder.
129class HardwareContext {
130public:
131 YUZU_NON_COPYABLE(HardwareContext);
132 YUZU_NON_MOVEABLE(HardwareContext);
133
134 static std::vector<AVHWDeviceType> GetSupportedDeviceTypes();
135
136 explicit HardwareContext() = default;
137 ~HardwareContext();
138
139 bool InitializeForDecoder(DecoderContext& decoder_context, const Decoder& decoder);
140
141 AVBufferRef* GetBufferRef() const {
142 return m_gpu_decoder;
143 }
144
145private:
146 bool InitializeWithType(AVHWDeviceType type);
147
148 AVBufferRef* m_gpu_decoder{};
149};
150
151// Wraps an AVCodecContext.
152class DecoderContext {
153public:
154 YUZU_NON_COPYABLE(DecoderContext);
155 YUZU_NON_MOVEABLE(DecoderContext);
156
157 explicit DecoderContext(const Decoder& decoder);
158 ~DecoderContext();
159
160 void InitializeHardwareDecoder(const HardwareContext& context, AVPixelFormat hw_pix_fmt);
161 bool OpenContext(const Decoder& decoder);
162 bool SendPacket(const Packet& packet);
163 std::unique_ptr<Frame> ReceiveFrame(bool* out_is_interlaced);
164
165 AVCodecContext* GetCodecContext() const {
166 return m_codec_context;
167 }
168
169private:
170 AVCodecContext* m_codec_context{};
171};
172
173// Wraps an AVFilterGraph.
174class DeinterlaceFilter {
175public:
176 YUZU_NON_COPYABLE(DeinterlaceFilter);
177 YUZU_NON_MOVEABLE(DeinterlaceFilter);
178
179 explicit DeinterlaceFilter(const Frame& frame);
180 ~DeinterlaceFilter();
181
182 bool AddSourceFrame(const Frame& frame);
183 std::unique_ptr<Frame> DrainSinkFrame();
184
185private:
186 AVFilterGraph* m_filter_graph{};
187 AVFilterContext* m_source_context{};
188 AVFilterContext* m_sink_context{};
189 bool m_initialized{};
190};
191
192class DecodeApi {
193public:
194 YUZU_NON_COPYABLE(DecodeApi);
195 YUZU_NON_MOVEABLE(DecodeApi);
196
197 DecodeApi() = default;
198 ~DecodeApi() = default;
199
200 bool Initialize(Tegra::Host1x::NvdecCommon::VideoCodec codec);
201 void Reset();
202
203 bool SendPacket(std::span<const u8> packet_data, size_t configuration_size);
204 void ReceiveFrames(std::queue<std::unique_ptr<Frame>>& frame_queue);
205
206private:
207 std::optional<FFmpeg::Decoder> m_decoder;
208 std::optional<FFmpeg::DecoderContext> m_decoder_context;
209 std::optional<FFmpeg::HardwareContext> m_hardware_context;
210 std::optional<FFmpeg::DeinterlaceFilter> m_deinterlace_filter;
211};
212
213} // namespace FFmpeg
diff --git a/src/video_core/host1x/nvdec.cpp b/src/video_core/host1x/nvdec.cpp
index a4bd5b79f..b8f5866d3 100644
--- a/src/video_core/host1x/nvdec.cpp
+++ b/src/video_core/host1x/nvdec.cpp
@@ -28,7 +28,7 @@ void Nvdec::ProcessMethod(u32 method, u32 argument) {
28 } 28 }
29} 29}
30 30
31AVFramePtr Nvdec::GetFrame() { 31std::unique_ptr<FFmpeg::Frame> Nvdec::GetFrame() {
32 return codec->GetCurrentFrame(); 32 return codec->GetCurrentFrame();
33} 33}
34 34
diff --git a/src/video_core/host1x/nvdec.h b/src/video_core/host1x/nvdec.h
index 3949d5181..ddddb8d28 100644
--- a/src/video_core/host1x/nvdec.h
+++ b/src/video_core/host1x/nvdec.h
@@ -23,7 +23,7 @@ public:
23 void ProcessMethod(u32 method, u32 argument); 23 void ProcessMethod(u32 method, u32 argument);
24 24
25 /// Return most recently decoded frame 25 /// Return most recently decoded frame
26 [[nodiscard]] AVFramePtr GetFrame(); 26 [[nodiscard]] std::unique_ptr<FFmpeg::Frame> GetFrame();
27 27
28private: 28private:
29 /// Invoke codec to decode a frame 29 /// Invoke codec to decode a frame
diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp
index 10d7ef884..2a5eba415 100644
--- a/src/video_core/host1x/vic.cpp
+++ b/src/video_core/host1x/vic.cpp
@@ -82,27 +82,26 @@ void Vic::Execute() {
82 return; 82 return;
83 } 83 }
84 const VicConfig config{host1x.MemoryManager().Read<u64>(config_struct_address + 0x20)}; 84 const VicConfig config{host1x.MemoryManager().Read<u64>(config_struct_address + 0x20)};
85 const AVFramePtr frame_ptr = nvdec_processor->GetFrame(); 85 auto frame = nvdec_processor->GetFrame();
86 const auto* frame = frame_ptr.get();
87 if (!frame) { 86 if (!frame) {
88 return; 87 return;
89 } 88 }
90 const u64 surface_width = config.surface_width_minus1 + 1; 89 const u64 surface_width = config.surface_width_minus1 + 1;
91 const u64 surface_height = config.surface_height_minus1 + 1; 90 const u64 surface_height = config.surface_height_minus1 + 1;
92 if (static_cast<u64>(frame->width) != surface_width || 91 if (static_cast<u64>(frame->GetWidth()) != surface_width ||
93 static_cast<u64>(frame->height) != surface_height) { 92 static_cast<u64>(frame->GetHeight()) != surface_height) {
94 // TODO: Properly support multiple video streams with differing frame dimensions 93 // TODO: Properly support multiple video streams with differing frame dimensions
95 LOG_WARNING(Service_NVDRV, "Frame dimensions {}x{} don't match surface dimensions {}x{}", 94 LOG_WARNING(Service_NVDRV, "Frame dimensions {}x{} don't match surface dimensions {}x{}",
96 frame->width, frame->height, surface_width, surface_height); 95 frame->GetWidth(), frame->GetHeight(), surface_width, surface_height);
97 } 96 }
98 switch (config.pixel_format) { 97 switch (config.pixel_format) {
99 case VideoPixelFormat::RGBA8: 98 case VideoPixelFormat::RGBA8:
100 case VideoPixelFormat::BGRA8: 99 case VideoPixelFormat::BGRA8:
101 case VideoPixelFormat::RGBX8: 100 case VideoPixelFormat::RGBX8:
102 WriteRGBFrame(frame, config); 101 WriteRGBFrame(std::move(frame), config);
103 break; 102 break;
104 case VideoPixelFormat::YUV420: 103 case VideoPixelFormat::YUV420:
105 WriteYUVFrame(frame, config); 104 WriteYUVFrame(std::move(frame), config);
106 break; 105 break;
107 default: 106 default:
108 UNIMPLEMENTED_MSG("Unknown video pixel format {:X}", config.pixel_format.Value()); 107 UNIMPLEMENTED_MSG("Unknown video pixel format {:X}", config.pixel_format.Value());
@@ -110,10 +109,14 @@ void Vic::Execute() {
110 } 109 }
111} 110}
112 111
113void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) { 112void Vic::WriteRGBFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config) {
114 LOG_TRACE(Service_NVDRV, "Writing RGB Frame"); 113 LOG_TRACE(Service_NVDRV, "Writing RGB Frame");
115 114
116 if (!scaler_ctx || frame->width != scaler_width || frame->height != scaler_height) { 115 const auto frame_width = frame->GetWidth();
116 const auto frame_height = frame->GetHeight();
117 const auto frame_format = frame->GetPixelFormat();
118
119 if (!scaler_ctx || frame_width != scaler_width || frame_height != scaler_height) {
117 const AVPixelFormat target_format = [pixel_format = config.pixel_format]() { 120 const AVPixelFormat target_format = [pixel_format = config.pixel_format]() {
118 switch (pixel_format) { 121 switch (pixel_format) {
119 case VideoPixelFormat::RGBA8: 122 case VideoPixelFormat::RGBA8:
@@ -129,27 +132,26 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
129 132
130 sws_freeContext(scaler_ctx); 133 sws_freeContext(scaler_ctx);
131 // Frames are decoded into either YUV420 or NV12 formats. Convert to desired RGB format 134 // Frames are decoded into either YUV420 or NV12 formats. Convert to desired RGB format
132 scaler_ctx = sws_getContext(frame->width, frame->height, 135 scaler_ctx = sws_getContext(frame_width, frame_height, frame_format, frame_width,
133 static_cast<AVPixelFormat>(frame->format), frame->width, 136 frame_height, target_format, 0, nullptr, nullptr, nullptr);
134 frame->height, target_format, 0, nullptr, nullptr, nullptr); 137 scaler_width = frame_width;
135 scaler_width = frame->width; 138 scaler_height = frame_height;
136 scaler_height = frame->height;
137 converted_frame_buffer.reset(); 139 converted_frame_buffer.reset();
138 } 140 }
139 if (!converted_frame_buffer) { 141 if (!converted_frame_buffer) {
140 const size_t frame_size = frame->width * frame->height * 4; 142 const size_t frame_size = frame_width * frame_height * 4;
141 converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(frame_size)), av_free}; 143 converted_frame_buffer = AVMallocPtr{static_cast<u8*>(av_malloc(frame_size)), av_free};
142 } 144 }
143 const std::array<int, 4> converted_stride{frame->width * 4, frame->height * 4, 0, 0}; 145 const std::array<int, 4> converted_stride{frame_width * 4, frame_height * 4, 0, 0};
144 u8* const converted_frame_buf_addr{converted_frame_buffer.get()}; 146 u8* const converted_frame_buf_addr{converted_frame_buffer.get()};
145 sws_scale(scaler_ctx, frame->data, frame->linesize, 0, frame->height, &converted_frame_buf_addr, 147 sws_scale(scaler_ctx, frame->GetPlanes(), frame->GetStrides(), 0, frame_height,
146 converted_stride.data()); 148 &converted_frame_buf_addr, converted_stride.data());
147 149
148 // Use the minimum of surface/frame dimensions to avoid buffer overflow. 150 // Use the minimum of surface/frame dimensions to avoid buffer overflow.
149 const u32 surface_width = static_cast<u32>(config.surface_width_minus1) + 1; 151 const u32 surface_width = static_cast<u32>(config.surface_width_minus1) + 1;
150 const u32 surface_height = static_cast<u32>(config.surface_height_minus1) + 1; 152 const u32 surface_height = static_cast<u32>(config.surface_height_minus1) + 1;
151 const u32 width = std::min(surface_width, static_cast<u32>(frame->width)); 153 const u32 width = std::min(surface_width, static_cast<u32>(frame_width));
152 const u32 height = std::min(surface_height, static_cast<u32>(frame->height)); 154 const u32 height = std::min(surface_height, static_cast<u32>(frame_height));
153 const u32 blk_kind = static_cast<u32>(config.block_linear_kind); 155 const u32 blk_kind = static_cast<u32>(config.block_linear_kind);
154 if (blk_kind != 0) { 156 if (blk_kind != 0) {
155 // swizzle pitch linear to block linear 157 // swizzle pitch linear to block linear
@@ -169,23 +171,23 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
169 } 171 }
170} 172}
171 173
172void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) { 174void Vic::WriteYUVFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config) {
173 LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame"); 175 LOG_TRACE(Service_NVDRV, "Writing YUV420 Frame");
174 176
175 const std::size_t surface_width = config.surface_width_minus1 + 1; 177 const std::size_t surface_width = config.surface_width_minus1 + 1;
176 const std::size_t surface_height = config.surface_height_minus1 + 1; 178 const std::size_t surface_height = config.surface_height_minus1 + 1;
177 const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL; 179 const std::size_t aligned_width = (surface_width + 0xff) & ~0xffUL;
178 // Use the minimum of surface/frame dimensions to avoid buffer overflow. 180 // Use the minimum of surface/frame dimensions to avoid buffer overflow.
179 const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->width)); 181 const auto frame_width = std::min(surface_width, static_cast<size_t>(frame->GetWidth()));
180 const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->height)); 182 const auto frame_height = std::min(surface_height, static_cast<size_t>(frame->GetHeight()));
181 183
182 const auto stride = static_cast<size_t>(frame->linesize[0]); 184 const auto stride = static_cast<size_t>(frame->GetStride(0));
183 185
184 luma_buffer.resize_destructive(aligned_width * surface_height); 186 luma_buffer.resize_destructive(aligned_width * surface_height);
185 chroma_buffer.resize_destructive(aligned_width * surface_height / 2); 187 chroma_buffer.resize_destructive(aligned_width * surface_height / 2);
186 188
187 // Populate luma buffer 189 // Populate luma buffer
188 const u8* luma_src = frame->data[0]; 190 const u8* luma_src = frame->GetData(0);
189 for (std::size_t y = 0; y < frame_height; ++y) { 191 for (std::size_t y = 0; y < frame_height; ++y) {
190 const std::size_t src = y * stride; 192 const std::size_t src = y * stride;
191 const std::size_t dst = y * aligned_width; 193 const std::size_t dst = y * aligned_width;
@@ -196,16 +198,16 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
196 198
197 // Chroma 199 // Chroma
198 const std::size_t half_height = frame_height / 2; 200 const std::size_t half_height = frame_height / 2;
199 const auto half_stride = static_cast<size_t>(frame->linesize[1]); 201 const auto half_stride = static_cast<size_t>(frame->GetStride(1));
200 202
201 switch (frame->format) { 203 switch (frame->GetPixelFormat()) {
202 case AV_PIX_FMT_YUV420P: { 204 case AV_PIX_FMT_YUV420P: {
203 // Frame from FFmpeg software 205 // Frame from FFmpeg software
204 // Populate chroma buffer from both channels with interleaving. 206 // Populate chroma buffer from both channels with interleaving.
205 const std::size_t half_width = frame_width / 2; 207 const std::size_t half_width = frame_width / 2;
206 u8* chroma_buffer_data = chroma_buffer.data(); 208 u8* chroma_buffer_data = chroma_buffer.data();
207 const u8* chroma_b_src = frame->data[1]; 209 const u8* chroma_b_src = frame->GetData(1);
208 const u8* chroma_r_src = frame->data[2]; 210 const u8* chroma_r_src = frame->GetData(2);
209 for (std::size_t y = 0; y < half_height; ++y) { 211 for (std::size_t y = 0; y < half_height; ++y) {
210 const std::size_t src = y * half_stride; 212 const std::size_t src = y * half_stride;
211 const std::size_t dst = y * aligned_width; 213 const std::size_t dst = y * aligned_width;
@@ -219,7 +221,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
219 case AV_PIX_FMT_NV12: { 221 case AV_PIX_FMT_NV12: {
220 // Frame from VA-API hardware 222 // Frame from VA-API hardware
221 // This is already interleaved so just copy 223 // This is already interleaved so just copy
222 const u8* chroma_src = frame->data[1]; 224 const u8* chroma_src = frame->GetData(1);
223 for (std::size_t y = 0; y < half_height; ++y) { 225 for (std::size_t y = 0; y < half_height; ++y) {
224 const std::size_t src = y * stride; 226 const std::size_t src = y * stride;
225 const std::size_t dst = y * aligned_width; 227 const std::size_t dst = y * aligned_width;
diff --git a/src/video_core/host1x/vic.h b/src/video_core/host1x/vic.h
index 3d9753047..6c868f062 100644
--- a/src/video_core/host1x/vic.h
+++ b/src/video_core/host1x/vic.h
@@ -39,9 +39,9 @@ public:
39private: 39private:
40 void Execute(); 40 void Execute();
41 41
42 void WriteRGBFrame(const AVFrame* frame, const VicConfig& config); 42 void WriteRGBFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config);
43 43
44 void WriteYUVFrame(const AVFrame* frame, const VicConfig& config); 44 void WriteYUVFrame(std::unique_ptr<FFmpeg::Frame> frame, const VicConfig& config);
45 45
46 Host1x& host1x; 46 Host1x& host1x;
47 std::shared_ptr<Tegra::Host1x::Nvdec> nvdec_processor; 47 std::shared_ptr<Tegra::Host1x::Nvdec> nvdec_processor;
diff --git a/src/video_core/query_cache/query_cache.h b/src/video_core/query_cache/query_cache.h
index 78b42b518..efa9adf7a 100644
--- a/src/video_core/query_cache/query_cache.h
+++ b/src/video_core/query_cache/query_cache.h
@@ -266,7 +266,7 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
266 return; 266 return;
267 } 267 }
268 if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] { 268 if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] {
269 UNREACHABLE(); 269 ASSERT(false);
270 return; 270 return;
271 } 271 }
272 query_base->value += streamer->GetAmmendValue(); 272 query_base->value += streamer->GetAmmendValue();
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index b251c9045..90278052a 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -252,6 +252,7 @@ file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*)
252if (ENABLE_QT_TRANSLATION) 252if (ENABLE_QT_TRANSLATION)
253 set(YUZU_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend") 253 set(YUZU_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend")
254 option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF) 254 option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF)
255 option(WORKAROUND_BROKEN_LUPDATE "Run lupdate directly through CMake if Qt's convenience wrappers don't work" OFF)
255 256
256 # Update source TS file if enabled 257 # Update source TS file if enabled
257 if (GENERATE_QT_TRANSLATION) 258 if (GENERATE_QT_TRANSLATION)
@@ -259,19 +260,51 @@ if (ENABLE_QT_TRANSLATION)
259 # these calls to qt_create_translation also creates a rule to generate en.qm which conflicts with providing english plurals 260 # these calls to qt_create_translation also creates a rule to generate en.qm which conflicts with providing english plurals
260 # so we have to set a OUTPUT_LOCATION so that we don't have multiple rules to generate en.qm 261 # so we have to set a OUTPUT_LOCATION so that we don't have multiple rules to generate en.qm
261 set_source_files_properties(${YUZU_QT_LANGUAGES}/en.ts PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations") 262 set_source_files_properties(${YUZU_QT_LANGUAGES}/en.ts PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations")
262 qt_create_translation(QM_FILES 263 if (WORKAROUND_BROKEN_LUPDATE)
263 ${SRCS} 264 add_custom_command(OUTPUT ${YUZU_QT_LANGUAGES}/en.ts
264 ${UIS} 265 COMMAND lupdate
265 ${YUZU_QT_LANGUAGES}/en.ts 266 -source-language en_US
266 OPTIONS 267 -target-language en_US
267 -source-language en_US 268 ${SRCS}
268 -target-language en_US 269 ${UIS}
269 ) 270 -ts ${YUZU_QT_LANGUAGES}/en.ts
271 DEPENDS
272 ${SRCS}
273 ${UIS}
274 WORKING_DIRECTORY
275 ${CMAKE_CURRENT_SOURCE_DIR}
276 )
277 else()
278 qt_create_translation(QM_FILES
279 ${SRCS}
280 ${UIS}
281 ${YUZU_QT_LANGUAGES}/en.ts
282 OPTIONS
283 -source-language en_US
284 -target-language en_US
285 )
286 endif()
270 287
271 # Generate plurals into dist/english_plurals/generated_en.ts so it can be used to revise dist/english_plurals/en.ts 288 # Generate plurals into dist/english_plurals/generated_en.ts so it can be used to revise dist/english_plurals/en.ts
272 set(GENERATED_PLURALS_FILE ${PROJECT_SOURCE_DIR}/dist/english_plurals/generated_en.ts) 289 set(GENERATED_PLURALS_FILE ${PROJECT_SOURCE_DIR}/dist/english_plurals/generated_en.ts)
273 set_source_files_properties(${GENERATED_PLURALS_FILE} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/plurals") 290 set_source_files_properties(${GENERATED_PLURALS_FILE} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/plurals")
274 qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US) 291 if (WORKAROUND_BROKEN_LUPDATE)
292 add_custom_command(OUTPUT ${GENERATED_PLURALS_FILE}
293 COMMAND lupdate
294 -source-language en_US
295 -target-language en_US
296 ${SRCS}
297 ${UIS}
298 -ts ${GENERATED_PLURALS_FILE}
299 DEPENDS
300 ${SRCS}
301 ${UIS}
302 WORKING_DIRECTORY
303 ${CMAKE_CURRENT_SOURCE_DIR}
304 )
305 else()
306 qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US)
307 endif()
275 308
276 add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts ${GENERATED_PLURALS_FILE}) 309 add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts ${GENERATED_PLURALS_FILE})
277 endif() 310 endif()
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index 1434b1a56..a7b5def32 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -1,17 +1,18 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/time_zone.h"
5#include "yuzu/configuration/shared_translation.h" 4#include "yuzu/configuration/shared_translation.h"
6 5
7#include <map> 6#include <map>
8#include <memory> 7#include <memory>
9#include <tuple> 8#include <tuple>
10#include <utility> 9#include <utility>
10#include <QCoreApplication>
11#include <QWidget> 11#include <QWidget>
12#include "common/settings.h" 12#include "common/settings.h"
13#include "common/settings_enums.h" 13#include "common/settings_enums.h"
14#include "common/settings_setting.h" 14#include "common/settings_setting.h"
15#include "common/time_zone.h"
15#include "yuzu/uisettings.h" 16#include "yuzu/uisettings.h"
16 17
17namespace ConfigurationShared { 18namespace ConfigurationShared {
@@ -21,123 +22,135 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
21 const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); }; 22 const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); };
22 23
23#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \ 24#define INSERT(SETTINGS, ID, NAME, TOOLTIP) \
24 translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{tr((NAME)), tr((TOOLTIP))}}) 25 translations->insert(std::pair{SETTINGS::values.ID.Id(), std::pair{(NAME), (TOOLTIP)}})
25 26
26 // A setting can be ignored by giving it a blank name 27 // A setting can be ignored by giving it a blank name
27 28
28 // Audio 29 // Audio
29 INSERT(Settings, sink_id, "Output Engine:", ""); 30 INSERT(Settings, sink_id, tr("Output Engine:"), QStringLiteral());
30 INSERT(Settings, audio_output_device_id, "Output Device:", ""); 31 INSERT(Settings, audio_output_device_id, tr("Output Device:"), QStringLiteral());
31 INSERT(Settings, audio_input_device_id, "Input Device:", ""); 32 INSERT(Settings, audio_input_device_id, tr("Input Device:"), QStringLiteral());
32 INSERT(Settings, audio_muted, "Mute audio", ""); 33 INSERT(Settings, audio_muted, tr("Mute audio"), QStringLiteral());
33 INSERT(Settings, volume, "Volume:", ""); 34 INSERT(Settings, volume, tr("Volume:"), QStringLiteral());
34 INSERT(Settings, dump_audio_commands, "", ""); 35 INSERT(Settings, dump_audio_commands, QStringLiteral(), QStringLiteral());
35 INSERT(UISettings, mute_when_in_background, "Mute audio when in background", ""); 36 INSERT(UISettings, mute_when_in_background, tr("Mute audio when in background"),
37 QStringLiteral());
36 38
37 // Core 39 // Core
38 INSERT(Settings, use_multi_core, "Multicore CPU Emulation", ""); 40 INSERT(Settings, use_multi_core, tr("Multicore CPU Emulation"), QStringLiteral());
39 INSERT(Settings, memory_layout_mode, "Memory Layout", ""); 41 INSERT(Settings, memory_layout_mode, tr("Memory Layout"), QStringLiteral());
40 INSERT(Settings, use_speed_limit, "", ""); 42 INSERT(Settings, use_speed_limit, QStringLiteral(), QStringLiteral());
41 INSERT(Settings, speed_limit, "Limit Speed Percent", ""); 43 INSERT(Settings, speed_limit, tr("Limit Speed Percent"), QStringLiteral());
42 44
43 // Cpu 45 // Cpu
44 INSERT(Settings, cpu_accuracy, "Accuracy:", ""); 46 INSERT(Settings, cpu_accuracy, tr("Accuracy:"), QStringLiteral());
45 47
46 // Cpu Debug 48 // Cpu Debug
47 49
48 // Cpu Unsafe 50 // Cpu Unsafe
49 INSERT(Settings, cpuopt_unsafe_unfuse_fma,
50 "Unfuse FMA (improve performance on CPUs without FMA)",
51 "This option improves speed by reducing accuracy of fused-multiply-add instructions on "
52 "CPUs without native FMA support.");
53 INSERT(Settings, cpuopt_unsafe_reduce_fp_error, "Faster FRSQRTE and FRECPE",
54 "This option improves the speed of some approximate floating-point functions by using "
55 "less accurate native approximations.");
56 INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr, "Faster ASIMD instructions (32 bits only)",
57 "This option improves the speed of 32 bits ASIMD floating-point functions by running "
58 "with incorrect rounding modes.");
59 INSERT(Settings, cpuopt_unsafe_inaccurate_nan, "Inaccurate NaN handling",
60 "This option improves speed by removing NaN checking. Please note this also reduces "
61 "accuracy of certain floating-point instructions.");
62 INSERT( 51 INSERT(
63 Settings, cpuopt_unsafe_fastmem_check, "Disable address space checks", 52 Settings, cpuopt_unsafe_unfuse_fma,
64 "This option improves speed by eliminating a safety check before every memory read/write " 53 tr("Unfuse FMA (improve performance on CPUs without FMA)"),
65 "in guest. Disabling it may allow a game to read/write the emulator's memory."); 54 tr("This option improves speed by reducing accuracy of fused-multiply-add instructions on "
66 INSERT(Settings, cpuopt_unsafe_ignore_global_monitor, "Ignore global monitor", 55 "CPUs without native FMA support."));
67 "This option improves speed by relying only on the semantics of cmpxchg to ensure " 56 INSERT(
57 Settings, cpuopt_unsafe_reduce_fp_error, tr("Faster FRSQRTE and FRECPE"),
58 tr("This option improves the speed of some approximate floating-point functions by using "
59 "less accurate native approximations."));
60 INSERT(Settings, cpuopt_unsafe_ignore_standard_fpcr,
61 tr("Faster ASIMD instructions (32 bits only)"),
62 tr("This option improves the speed of 32 bits ASIMD floating-point functions by running "
63 "with incorrect rounding modes."));
64 INSERT(Settings, cpuopt_unsafe_inaccurate_nan, tr("Inaccurate NaN handling"),
65 tr("This option improves speed by removing NaN checking. Please note this also reduces "
66 "accuracy of certain floating-point instructions."));
67 INSERT(Settings, cpuopt_unsafe_fastmem_check, tr("Disable address space checks"),
68 tr("This option improves speed by eliminating a safety check before every memory "
69 "read/write "
70 "in guest. Disabling it may allow a game to read/write the emulator's memory."));
71 INSERT(
72 Settings, cpuopt_unsafe_ignore_global_monitor, tr("Ignore global monitor"),
73 tr("This option improves speed by relying only on the semantics of cmpxchg to ensure "
68 "safety of exclusive access instructions. Please note this may result in deadlocks and " 74 "safety of exclusive access instructions. Please note this may result in deadlocks and "
69 "other race conditions."); 75 "other race conditions."));
70 76
71 // Renderer 77 // Renderer
72 INSERT(Settings, renderer_backend, "API:", ""); 78 INSERT(Settings, renderer_backend, tr("API:"), QStringLiteral());
73 INSERT(Settings, vulkan_device, "Device:", ""); 79 INSERT(Settings, vulkan_device, tr("Device:"), QStringLiteral());
74 INSERT(Settings, shader_backend, "Shader Backend:", ""); 80 INSERT(Settings, shader_backend, tr("Shader Backend:"), QStringLiteral());
75 INSERT(Settings, resolution_setup, "Resolution:", ""); 81 INSERT(Settings, resolution_setup, tr("Resolution:"), QStringLiteral());
76 INSERT(Settings, scaling_filter, "Window Adapting Filter:", ""); 82 INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral());
77 INSERT(Settings, fsr_sharpening_slider, "FSR Sharpness:", ""); 83 INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"), QStringLiteral());
78 INSERT(Settings, anti_aliasing, "Anti-Aliasing Method:", ""); 84 INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"), QStringLiteral());
79 INSERT(Settings, fullscreen_mode, "Fullscreen Mode:", ""); 85 INSERT(Settings, fullscreen_mode, tr("Fullscreen Mode:"), QStringLiteral());
80 INSERT(Settings, aspect_ratio, "Aspect Ratio:", ""); 86 INSERT(Settings, aspect_ratio, tr("Aspect Ratio:"), QStringLiteral());
81 INSERT(Settings, use_disk_shader_cache, "Use disk pipeline cache", ""); 87 INSERT(Settings, use_disk_shader_cache, tr("Use disk pipeline cache"), QStringLiteral());
82 INSERT(Settings, use_asynchronous_gpu_emulation, "Use asynchronous GPU emulation", ""); 88 INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"),
83 INSERT(Settings, nvdec_emulation, "NVDEC emulation:", ""); 89 QStringLiteral());
84 INSERT(Settings, accelerate_astc, "ASTC Decoding Method:", ""); 90 INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), QStringLiteral());
85 INSERT(Settings, astc_recompression, "ASTC Recompression Method:", ""); 91 INSERT(Settings, accelerate_astc, tr("ASTC Decoding Method:"), QStringLiteral());
86 INSERT(Settings, vsync_mode, "VSync Mode:", 92 INSERT(Settings, astc_recompression, tr("ASTC Recompression Method:"), QStringLiteral());
87 "FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen " 93 INSERT(
94 Settings, vsync_mode, tr("VSync Mode:"),
95 tr("FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen "
88 "refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from " 96 "refresh rate.\nFIFO Relaxed is similar to FIFO but allows tearing as it recovers from "
89 "a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop " 97 "a slow down.\nMailbox can have lower latency than FIFO and does not tear but may drop "
90 "frames.\nImmediate (no synchronization) just presents whatever is available and can " 98 "frames.\nImmediate (no synchronization) just presents whatever is available and can "
91 "exhibit tearing."); 99 "exhibit tearing."));
92 INSERT(Settings, bg_red, "", ""); 100 INSERT(Settings, bg_red, QStringLiteral(), QStringLiteral());
93 INSERT(Settings, bg_green, "", ""); 101 INSERT(Settings, bg_green, QStringLiteral(), QStringLiteral());
94 INSERT(Settings, bg_blue, "", ""); 102 INSERT(Settings, bg_blue, QStringLiteral(), QStringLiteral());
95 103
96 // Renderer (Advanced Graphics) 104 // Renderer (Advanced Graphics)
97 INSERT(Settings, async_presentation, "Enable asynchronous presentation (Vulkan only)", ""); 105 INSERT(Settings, async_presentation, tr("Enable asynchronous presentation (Vulkan only)"),
98 INSERT(Settings, renderer_force_max_clock, "Force maximum clocks (Vulkan only)", 106 QStringLiteral());
99 "Runs work in the background while waiting for graphics commands to keep the GPU from " 107 INSERT(
100 "lowering its clock speed."); 108 Settings, renderer_force_max_clock, tr("Force maximum clocks (Vulkan only)"),
101 INSERT(Settings, max_anisotropy, "Anisotropic Filtering:", ""); 109 tr("Runs work in the background while waiting for graphics commands to keep the GPU from "
102 INSERT(Settings, gpu_accuracy, "Accuracy Level:", ""); 110 "lowering its clock speed."));
103 INSERT(Settings, use_asynchronous_shaders, "Use asynchronous shader building (Hack)", 111 INSERT(Settings, max_anisotropy, tr("Anisotropic Filtering:"), QStringLiteral());
104 "Enables asynchronous shader compilation, which may reduce shader stutter. This feature " 112 INSERT(Settings, gpu_accuracy, tr("Accuracy Level:"), QStringLiteral());
105 "is experimental."); 113 INSERT(
106 INSERT(Settings, use_fast_gpu_time, "Use Fast GPU Time (Hack)", 114 Settings, use_asynchronous_shaders, tr("Use asynchronous shader building (Hack)"),
107 "Enables Fast GPU Time. This option will force most games to run at their highest " 115 tr("Enables asynchronous shader compilation, which may reduce shader stutter. This feature "
108 "native resolution."); 116 "is experimental."));
109 INSERT(Settings, use_vulkan_driver_pipeline_cache, "Use Vulkan pipeline cache", 117 INSERT(Settings, use_fast_gpu_time, tr("Use Fast GPU Time (Hack)"),
110 "Enables GPU vendor-specific pipeline cache. This option can improve shader loading " 118 tr("Enables Fast GPU Time. This option will force most games to run at their highest "
111 "time significantly in cases where the Vulkan driver does not store pipeline cache " 119 "native resolution."));
112 "files internally."); 120 INSERT(Settings, use_vulkan_driver_pipeline_cache, tr("Use Vulkan pipeline cache"),
113 INSERT(Settings, enable_compute_pipelines, "Enable Compute Pipelines (Intel Vulkan Only)", 121 tr("Enables GPU vendor-specific pipeline cache. This option can improve shader loading "
114 "Enable compute pipelines, required by some games.\nThis setting only exists for Intel " 122 "time significantly in cases where the Vulkan driver does not store pipeline cache "
123 "files internally."));
124 INSERT(
125 Settings, enable_compute_pipelines, tr("Enable Compute Pipelines (Intel Vulkan Only)"),
126 tr("Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
115 "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled " 127 "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled "
116 "on all other drivers."); 128 "on all other drivers."));
117 INSERT(Settings, use_reactive_flushing, "Enable Reactive Flushing", 129 INSERT(
118 "Uses reactive flushing instead of predictive flushing, allowing more accurate memory " 130 Settings, use_reactive_flushing, tr("Enable Reactive Flushing"),
119 "syncing."); 131 tr("Uses reactive flushing instead of predictive flushing, allowing more accurate memory "
120 INSERT(Settings, use_video_framerate, "Sync to framerate of video playback", 132 "syncing."));
121 "Run the game at normal speed during video playback, even when the framerate is " 133 INSERT(Settings, use_video_framerate, tr("Sync to framerate of video playback"),
122 "unlocked."); 134 tr("Run the game at normal speed during video playback, even when the framerate is "
123 INSERT(Settings, barrier_feedback_loops, "Barrier feedback loops", 135 "unlocked."));
124 "Improves rendering of transparency effects in specific games."); 136 INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
137 tr("Improves rendering of transparency effects in specific games."));
125 138
126 // Renderer (Debug) 139 // Renderer (Debug)
127 140
128 // System 141 // System
129 INSERT(Settings, rng_seed, "RNG Seed", ""); 142 INSERT(Settings, rng_seed, tr("RNG Seed"), QStringLiteral());
130 INSERT(Settings, rng_seed_enabled, "", ""); 143 INSERT(Settings, rng_seed_enabled, QStringLiteral(), QStringLiteral());
131 INSERT(Settings, device_name, "Device Name", ""); 144 INSERT(Settings, device_name, tr("Device Name"), QStringLiteral());
132 INSERT(Settings, custom_rtc, "Custom RTC", ""); 145 INSERT(Settings, custom_rtc, tr("Custom RTC"), QStringLiteral());
133 INSERT(Settings, custom_rtc_enabled, "", ""); 146 INSERT(Settings, custom_rtc_enabled, QStringLiteral(), QStringLiteral());
134 INSERT(Settings, language_index, 147 INSERT(Settings, language_index, tr("Language:"),
135 "Language:", "Note: this can be overridden when region setting is auto-select"); 148 tr("Note: this can be overridden when region setting is auto-select"));
136 INSERT(Settings, region_index, "Region:", ""); 149 INSERT(Settings, region_index, tr("Region:"), QStringLiteral());
137 INSERT(Settings, time_zone_index, "Time Zone:", ""); 150 INSERT(Settings, time_zone_index, tr("Time Zone:"), QStringLiteral());
138 INSERT(Settings, sound_index, "Sound Output Mode:", ""); 151 INSERT(Settings, sound_index, tr("Sound Output Mode:"), QStringLiteral());
139 INSERT(Settings, use_docked_mode, "Console Mode:", ""); 152 INSERT(Settings, use_docked_mode, tr("Console Mode:"), QStringLiteral());
140 INSERT(Settings, current_user, "", ""); 153 INSERT(Settings, current_user, QStringLiteral(), QStringLiteral());
141 154
142 // Controls 155 // Controls
143 156
@@ -154,11 +167,14 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
154 // Ui 167 // Ui
155 168
156 // Ui General 169 // Ui General
157 INSERT(UISettings, select_user_on_boot, "Prompt for user on game boot", ""); 170 INSERT(UISettings, select_user_on_boot, tr("Prompt for user on game boot"), QStringLiteral());
158 INSERT(UISettings, pause_when_in_background, "Pause emulation when in background", ""); 171 INSERT(UISettings, pause_when_in_background, tr("Pause emulation when in background"),
159 INSERT(UISettings, confirm_before_stopping, "Confirm before stopping emulation", ""); 172 QStringLiteral());
160 INSERT(UISettings, hide_mouse, "Hide mouse on inactivity", ""); 173 INSERT(UISettings, confirm_before_stopping, tr("Confirm before stopping emulation"),
161 INSERT(UISettings, controller_applet_disabled, "Disable controller applet", ""); 174 QStringLiteral());
175 INSERT(UISettings, hide_mouse, tr("Hide mouse on inactivity"), QStringLiteral());
176 INSERT(UISettings, controller_applet_disabled, tr("Disable controller applet"),
177 QStringLiteral());
162 178
163 // Ui Debugging 179 // Ui Debugging
164 180
@@ -178,140 +194,141 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
178 return parent->tr(text, context); 194 return parent->tr(text, context);
179 }; 195 };
180 196
181#define PAIR(ENUM, VALUE, TRANSLATION) \ 197#define PAIR(ENUM, VALUE, TRANSLATION) {static_cast<u32>(Settings::ENUM::VALUE), (TRANSLATION)}
182 { static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION) }
183#define CTX_PAIR(ENUM, VALUE, TRANSLATION, CONTEXT) \
184 { static_cast<u32>(Settings::ENUM::VALUE), tr(TRANSLATION, CONTEXT) }
185 198
186 // Intentionally skipping VSyncMode to let the UI fill that one out 199 // Intentionally skipping VSyncMode to let the UI fill that one out
187 200
188 translations->insert({Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(), 201 translations->insert({Settings::EnumMetadata<Settings::AstcDecodeMode>::Index(),
189 { 202 {
190 PAIR(AstcDecodeMode, Cpu, "CPU"), 203 PAIR(AstcDecodeMode, Cpu, tr("CPU")),
191 PAIR(AstcDecodeMode, Gpu, "GPU"), 204 PAIR(AstcDecodeMode, Gpu, tr("GPU")),
192 PAIR(AstcDecodeMode, CpuAsynchronous, "CPU Asynchronous"), 205 PAIR(AstcDecodeMode, CpuAsynchronous, tr("CPU Asynchronous")),
193 }});
194 translations->insert({Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
195 {
196 PAIR(AstcRecompression, Uncompressed, "Uncompressed (Best quality)"),
197 PAIR(AstcRecompression, Bc1, "BC1 (Low quality)"),
198 PAIR(AstcRecompression, Bc3, "BC3 (Medium quality)"),
199 }}); 206 }});
207 translations->insert(
208 {Settings::EnumMetadata<Settings::AstcRecompression>::Index(),
209 {
210 PAIR(AstcRecompression, Uncompressed, tr("Uncompressed (Best quality)")),
211 PAIR(AstcRecompression, Bc1, tr("BC1 (Low quality)")),
212 PAIR(AstcRecompression, Bc3, tr("BC3 (Medium quality)")),
213 }});
200 translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(), 214 translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(),
201 { 215 {
202#ifdef HAS_OPENGL 216#ifdef HAS_OPENGL
203 PAIR(RendererBackend, OpenGL, "OpenGL"), 217 PAIR(RendererBackend, OpenGL, tr("OpenGL")),
204#endif 218#endif
205 PAIR(RendererBackend, Vulkan, "Vulkan"), 219 PAIR(RendererBackend, Vulkan, tr("Vulkan")),
206 PAIR(RendererBackend, Null, "Null"), 220 PAIR(RendererBackend, Null, tr("Null")),
207 }});
208 translations->insert({Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
209 {
210 PAIR(ShaderBackend, Glsl, "GLSL"),
211 PAIR(ShaderBackend, Glasm, "GLASM (Assembly Shaders, NVIDIA Only)"),
212 PAIR(ShaderBackend, SpirV, "SPIR-V (Experimental, Mesa Only)"),
213 }}); 221 }});
222 translations->insert(
223 {Settings::EnumMetadata<Settings::ShaderBackend>::Index(),
224 {
225 PAIR(ShaderBackend, Glsl, tr("GLSL")),
226 PAIR(ShaderBackend, Glasm, tr("GLASM (Assembly Shaders, NVIDIA Only)")),
227 PAIR(ShaderBackend, SpirV, tr("SPIR-V (Experimental, Mesa Only)")),
228 }});
214 translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(), 229 translations->insert({Settings::EnumMetadata<Settings::GpuAccuracy>::Index(),
215 { 230 {
216 PAIR(GpuAccuracy, Normal, "Normal"), 231 PAIR(GpuAccuracy, Normal, tr("Normal")),
217 PAIR(GpuAccuracy, High, "High"), 232 PAIR(GpuAccuracy, High, tr("High")),
218 PAIR(GpuAccuracy, Extreme, "Extreme"), 233 PAIR(GpuAccuracy, Extreme, tr("Extreme")),
219 }});
220 translations->insert({Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),
221 {
222 PAIR(CpuAccuracy, Auto, "Auto"),
223 PAIR(CpuAccuracy, Accurate, "Accurate"),
224 PAIR(CpuAccuracy, Unsafe, "Unsafe"),
225 PAIR(CpuAccuracy, Paranoid, "Paranoid (disables most optimizations)"),
226 }}); 234 }});
235 translations->insert(
236 {Settings::EnumMetadata<Settings::CpuAccuracy>::Index(),
237 {
238 PAIR(CpuAccuracy, Auto, tr("Auto")),
239 PAIR(CpuAccuracy, Accurate, tr("Accurate")),
240 PAIR(CpuAccuracy, Unsafe, tr("Unsafe")),
241 PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")),
242 }});
227 translations->insert({Settings::EnumMetadata<Settings::FullscreenMode>::Index(), 243 translations->insert({Settings::EnumMetadata<Settings::FullscreenMode>::Index(),
228 { 244 {
229 PAIR(FullscreenMode, Borderless, "Borderless Windowed"), 245 PAIR(FullscreenMode, Borderless, tr("Borderless Windowed")),
230 PAIR(FullscreenMode, Exclusive, "Exclusive Fullscreen"), 246 PAIR(FullscreenMode, Exclusive, tr("Exclusive Fullscreen")),
231 }}); 247 }});
232 translations->insert({Settings::EnumMetadata<Settings::NvdecEmulation>::Index(), 248 translations->insert({Settings::EnumMetadata<Settings::NvdecEmulation>::Index(),
233 { 249 {
234 PAIR(NvdecEmulation, Off, "No Video Output"), 250 PAIR(NvdecEmulation, Off, tr("No Video Output")),
235 PAIR(NvdecEmulation, Cpu, "CPU Video Decoding"), 251 PAIR(NvdecEmulation, Cpu, tr("CPU Video Decoding")),
236 PAIR(NvdecEmulation, Gpu, "GPU Video Decoding (Default)"), 252 PAIR(NvdecEmulation, Gpu, tr("GPU Video Decoding (Default)")),
237 }});
238 translations->insert({Settings::EnumMetadata<Settings::ResolutionSetup>::Index(),
239 {
240 PAIR(ResolutionSetup, Res1_2X, "0.5X (360p/540p) [EXPERIMENTAL]"),
241 PAIR(ResolutionSetup, Res3_4X, "0.75X (540p/810p) [EXPERIMENTAL]"),
242 PAIR(ResolutionSetup, Res1X, "1X (720p/1080p)"),
243 PAIR(ResolutionSetup, Res3_2X, "1.5X (1080p/1620p) [EXPERIMENTAL]"),
244 PAIR(ResolutionSetup, Res2X, "2X (1440p/2160p)"),
245 PAIR(ResolutionSetup, Res3X, "3X (2160p/3240p)"),
246 PAIR(ResolutionSetup, Res4X, "4X (2880p/4320p)"),
247 PAIR(ResolutionSetup, Res5X, "5X (3600p/5400p)"),
248 PAIR(ResolutionSetup, Res6X, "6X (4320p/6480p)"),
249 PAIR(ResolutionSetup, Res7X, "7X (5040p/7560p)"),
250 PAIR(ResolutionSetup, Res8X, "8X (5760p/8640p)"),
251 }}); 253 }});
254 translations->insert(
255 {Settings::EnumMetadata<Settings::ResolutionSetup>::Index(),
256 {
257 PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")),
258 PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")),
259 PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")),
260 PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")),
261 PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")),
262 PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")),
263 PAIR(ResolutionSetup, Res4X, tr("4X (2880p/4320p)")),
264 PAIR(ResolutionSetup, Res5X, tr("5X (3600p/5400p)")),
265 PAIR(ResolutionSetup, Res6X, tr("6X (4320p/6480p)")),
266 PAIR(ResolutionSetup, Res7X, tr("7X (5040p/7560p)")),
267 PAIR(ResolutionSetup, Res8X, tr("8X (5760p/8640p)")),
268 }});
252 translations->insert({Settings::EnumMetadata<Settings::ScalingFilter>::Index(), 269 translations->insert({Settings::EnumMetadata<Settings::ScalingFilter>::Index(),
253 { 270 {
254 PAIR(ScalingFilter, NearestNeighbor, "Nearest Neighbor"), 271 PAIR(ScalingFilter, NearestNeighbor, tr("Nearest Neighbor")),
255 PAIR(ScalingFilter, Bilinear, "Bilinear"), 272 PAIR(ScalingFilter, Bilinear, tr("Bilinear")),
256 PAIR(ScalingFilter, Bicubic, "Bicubic"), 273 PAIR(ScalingFilter, Bicubic, tr("Bicubic")),
257 PAIR(ScalingFilter, Gaussian, "Gaussian"), 274 PAIR(ScalingFilter, Gaussian, tr("Gaussian")),
258 PAIR(ScalingFilter, ScaleForce, "ScaleForce"), 275 PAIR(ScalingFilter, ScaleForce, tr("ScaleForce")),
259 PAIR(ScalingFilter, Fsr, "AMD FidelityFX™️ Super Resolution"), 276 PAIR(ScalingFilter, Fsr, tr("AMD FidelityFX™️ Super Resolution")),
260 }}); 277 }});
261 translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(), 278 translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
262 { 279 {
263 PAIR(AntiAliasing, None, "None"), 280 PAIR(AntiAliasing, None, tr("None")),
264 PAIR(AntiAliasing, Fxaa, "FXAA"), 281 PAIR(AntiAliasing, Fxaa, tr("FXAA")),
265 PAIR(AntiAliasing, Smaa, "SMAA"), 282 PAIR(AntiAliasing, Smaa, tr("SMAA")),
266 }}); 283 }});
267 translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(), 284 translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(),
268 { 285 {
269 PAIR(AspectRatio, R16_9, "Default (16:9)"), 286 PAIR(AspectRatio, R16_9, tr("Default (16:9)")),
270 PAIR(AspectRatio, R4_3, "Force 4:3"), 287 PAIR(AspectRatio, R4_3, tr("Force 4:3")),
271 PAIR(AspectRatio, R21_9, "Force 21:9"), 288 PAIR(AspectRatio, R21_9, tr("Force 21:9")),
272 PAIR(AspectRatio, R16_10, "Force 16:10"), 289 PAIR(AspectRatio, R16_10, tr("Force 16:10")),
273 PAIR(AspectRatio, Stretch, "Stretch to Window"), 290 PAIR(AspectRatio, Stretch, tr("Stretch to Window")),
274 }}); 291 }});
275 translations->insert({Settings::EnumMetadata<Settings::AnisotropyMode>::Index(), 292 translations->insert({Settings::EnumMetadata<Settings::AnisotropyMode>::Index(),
276 { 293 {
277 PAIR(AnisotropyMode, Automatic, "Automatic"), 294 PAIR(AnisotropyMode, Automatic, tr("Automatic")),
278 PAIR(AnisotropyMode, Default, "Default"), 295 PAIR(AnisotropyMode, Default, tr("Default")),
279 PAIR(AnisotropyMode, X2, "2x"), 296 PAIR(AnisotropyMode, X2, tr("2x")),
280 PAIR(AnisotropyMode, X4, "4x"), 297 PAIR(AnisotropyMode, X4, tr("4x")),
281 PAIR(AnisotropyMode, X8, "8x"), 298 PAIR(AnisotropyMode, X8, tr("8x")),
282 PAIR(AnisotropyMode, X16, "16x"), 299 PAIR(AnisotropyMode, X16, tr("16x")),
283 }}); 300 }});
284 translations->insert( 301 translations->insert(
285 {Settings::EnumMetadata<Settings::Language>::Index(), 302 {Settings::EnumMetadata<Settings::Language>::Index(),
286 { 303 {
287 PAIR(Language, Japanese, "Japanese (日本語)"), 304 PAIR(Language, Japanese, tr("Japanese (日本語)")),
288 PAIR(Language, EnglishAmerican, "American English"), 305 PAIR(Language, EnglishAmerican, tr("American English")),
289 PAIR(Language, French, "French (français)"), 306 PAIR(Language, French, tr("French (français)")),
290 PAIR(Language, German, "German (Deutsch)"), 307 PAIR(Language, German, tr("German (Deutsch)")),
291 PAIR(Language, Italian, "Italian (italiano)"), 308 PAIR(Language, Italian, tr("Italian (italiano)")),
292 PAIR(Language, Spanish, "Spanish (español)"), 309 PAIR(Language, Spanish, tr("Spanish (español)")),
293 PAIR(Language, Chinese, "Chinese"), 310 PAIR(Language, Chinese, tr("Chinese")),
294 PAIR(Language, Korean, "Korean (한국어)"), 311 PAIR(Language, Korean, tr("Korean (한국어)")),
295 PAIR(Language, Dutch, "Dutch (Nederlands)"), 312 PAIR(Language, Dutch, tr("Dutch (Nederlands)")),
296 PAIR(Language, Portuguese, "Portuguese (português)"), 313 PAIR(Language, Portuguese, tr("Portuguese (português)")),
297 PAIR(Language, Russian, "Russian (Русский)"), 314 PAIR(Language, Russian, tr("Russian (Русский)")),
298 PAIR(Language, Taiwanese, "Taiwanese"), 315 PAIR(Language, Taiwanese, tr("Taiwanese")),
299 PAIR(Language, EnglishBritish, "British English"), 316 PAIR(Language, EnglishBritish, tr("British English")),
300 PAIR(Language, FrenchCanadian, "Canadian French"), 317 PAIR(Language, FrenchCanadian, tr("Canadian French")),
301 PAIR(Language, SpanishLatin, "Latin American Spanish"), 318 PAIR(Language, SpanishLatin, tr("Latin American Spanish")),
302 PAIR(Language, ChineseSimplified, "Simplified Chinese"), 319 PAIR(Language, ChineseSimplified, tr("Simplified Chinese")),
303 PAIR(Language, ChineseTraditional, "Traditional Chinese (正體中文)"), 320 PAIR(Language, ChineseTraditional, tr("Traditional Chinese (正體中文)")),
304 PAIR(Language, PortugueseBrazilian, "Brazilian Portuguese (português do Brasil)"), 321 PAIR(Language, PortugueseBrazilian, tr("Brazilian Portuguese (português do Brasil)")),
305 }}); 322 }});
306 translations->insert({Settings::EnumMetadata<Settings::Region>::Index(), 323 translations->insert({Settings::EnumMetadata<Settings::Region>::Index(),
307 { 324 {
308 PAIR(Region, Japan, "Japan"), 325 PAIR(Region, Japan, tr("Japan")),
309 PAIR(Region, Usa, "USA"), 326 PAIR(Region, Usa, tr("USA")),
310 PAIR(Region, Europe, "Europe"), 327 PAIR(Region, Europe, tr("Europe")),
311 PAIR(Region, Australia, "Australia"), 328 PAIR(Region, Australia, tr("Australia")),
312 PAIR(Region, China, "China"), 329 PAIR(Region, China, tr("China")),
313 PAIR(Region, Korea, "Korea"), 330 PAIR(Region, Korea, tr("Korea")),
314 PAIR(Region, Taiwan, "Taiwan"), 331 PAIR(Region, Taiwan, tr("Taiwan")),
315 }}); 332 }});
316 translations->insert( 333 translations->insert(
317 {Settings::EnumMetadata<Settings::TimeZone>::Index(), 334 {Settings::EnumMetadata<Settings::TimeZone>::Index(),
@@ -323,72 +340,74 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
323 {static_cast<u32>(Settings::TimeZone::Default), 340 {static_cast<u32>(Settings::TimeZone::Default),
324 tr("Default (%1)", "Default time zone") 341 tr("Default (%1)", "Default time zone")
325 .arg(QString::fromStdString(Common::TimeZone::GetDefaultTimeZone()))}, 342 .arg(QString::fromStdString(Common::TimeZone::GetDefaultTimeZone()))},
326 PAIR(TimeZone, Cet, "CET"), 343 PAIR(TimeZone, Cet, tr("CET")),
327 PAIR(TimeZone, Cst6Cdt, "CST6CDT"), 344 PAIR(TimeZone, Cst6Cdt, tr("CST6CDT")),
328 PAIR(TimeZone, Cuba, "Cuba"), 345 PAIR(TimeZone, Cuba, tr("Cuba")),
329 PAIR(TimeZone, Eet, "EET"), 346 PAIR(TimeZone, Eet, tr("EET")),
330 PAIR(TimeZone, Egypt, "Egypt"), 347 PAIR(TimeZone, Egypt, tr("Egypt")),
331 PAIR(TimeZone, Eire, "Eire"), 348 PAIR(TimeZone, Eire, tr("Eire")),
332 PAIR(TimeZone, Est, "EST"), 349 PAIR(TimeZone, Est, tr("EST")),
333 PAIR(TimeZone, Est5Edt, "EST5EDT"), 350 PAIR(TimeZone, Est5Edt, tr("EST5EDT")),
334 PAIR(TimeZone, Gb, "GB"), 351 PAIR(TimeZone, Gb, tr("GB")),
335 PAIR(TimeZone, GbEire, "GB-Eire"), 352 PAIR(TimeZone, GbEire, tr("GB-Eire")),
336 PAIR(TimeZone, Gmt, "GMT"), 353 PAIR(TimeZone, Gmt, tr("GMT")),
337 PAIR(TimeZone, GmtPlusZero, "GMT+0"), 354 PAIR(TimeZone, GmtPlusZero, tr("GMT+0")),
338 PAIR(TimeZone, GmtMinusZero, "GMT-0"), 355 PAIR(TimeZone, GmtMinusZero, tr("GMT-0")),
339 PAIR(TimeZone, GmtZero, "GMT0"), 356 PAIR(TimeZone, GmtZero, tr("GMT0")),
340 PAIR(TimeZone, Greenwich, "Greenwich"), 357 PAIR(TimeZone, Greenwich, tr("Greenwich")),
341 PAIR(TimeZone, Hongkong, "Hongkong"), 358 PAIR(TimeZone, Hongkong, tr("Hongkong")),
342 PAIR(TimeZone, Hst, "HST"), 359 PAIR(TimeZone, Hst, tr("HST")),
343 PAIR(TimeZone, Iceland, "Iceland"), 360 PAIR(TimeZone, Iceland, tr("Iceland")),
344 PAIR(TimeZone, Iran, "Iran"), 361 PAIR(TimeZone, Iran, tr("Iran")),
345 PAIR(TimeZone, Israel, "Israel"), 362 PAIR(TimeZone, Israel, tr("Israel")),
346 PAIR(TimeZone, Jamaica, "Jamaica"), 363 PAIR(TimeZone, Jamaica, tr("Jamaica")),
347 PAIR(TimeZone, Japan, "Japan"), 364 PAIR(TimeZone, Japan, tr("Japan")),
348 PAIR(TimeZone, Kwajalein, "Kwajalein"), 365 PAIR(TimeZone, Kwajalein, tr("Kwajalein")),
349 PAIR(TimeZone, Libya, "Libya"), 366 PAIR(TimeZone, Libya, tr("Libya")),
350 PAIR(TimeZone, Met, "MET"), 367 PAIR(TimeZone, Met, tr("MET")),
351 PAIR(TimeZone, Mst, "MST"), 368 PAIR(TimeZone, Mst, tr("MST")),
352 PAIR(TimeZone, Mst7Mdt, "MST7MDT"), 369 PAIR(TimeZone, Mst7Mdt, tr("MST7MDT")),
353 PAIR(TimeZone, Navajo, "Navajo"), 370 PAIR(TimeZone, Navajo, tr("Navajo")),
354 PAIR(TimeZone, Nz, "NZ"), 371 PAIR(TimeZone, Nz, tr("NZ")),
355 PAIR(TimeZone, NzChat, "NZ-CHAT"), 372 PAIR(TimeZone, NzChat, tr("NZ-CHAT")),
356 PAIR(TimeZone, Poland, "Poland"), 373 PAIR(TimeZone, Poland, tr("Poland")),
357 PAIR(TimeZone, Portugal, "Portugal"), 374 PAIR(TimeZone, Portugal, tr("Portugal")),
358 PAIR(TimeZone, Prc, "PRC"), 375 PAIR(TimeZone, Prc, tr("PRC")),
359 PAIR(TimeZone, Pst8Pdt, "PST8PDT"), 376 PAIR(TimeZone, Pst8Pdt, tr("PST8PDT")),
360 PAIR(TimeZone, Roc, "ROC"), 377 PAIR(TimeZone, Roc, tr("ROC")),
361 PAIR(TimeZone, Rok, "ROK"), 378 PAIR(TimeZone, Rok, tr("ROK")),
362 PAIR(TimeZone, Singapore, "Singapore"), 379 PAIR(TimeZone, Singapore, tr("Singapore")),
363 PAIR(TimeZone, Turkey, "Turkey"), 380 PAIR(TimeZone, Turkey, tr("Turkey")),
364 PAIR(TimeZone, Uct, "UCT"), 381 PAIR(TimeZone, Uct, tr("UCT")),
365 PAIR(TimeZone, Universal, "Universal"), 382 PAIR(TimeZone, Universal, tr("Universal")),
366 PAIR(TimeZone, Utc, "UTC"), 383 PAIR(TimeZone, Utc, tr("UTC")),
367 PAIR(TimeZone, WSu, "W-SU"), 384 PAIR(TimeZone, WSu, tr("W-SU")),
368 PAIR(TimeZone, Wet, "WET"), 385 PAIR(TimeZone, Wet, tr("WET")),
369 PAIR(TimeZone, Zulu, "Zulu"), 386 PAIR(TimeZone, Zulu, tr("Zulu")),
370 }}); 387 }});
371 translations->insert({Settings::EnumMetadata<Settings::AudioMode>::Index(), 388 translations->insert({Settings::EnumMetadata<Settings::AudioMode>::Index(),
372 { 389 {
373 PAIR(AudioMode, Mono, "Mono"), 390 PAIR(AudioMode, Mono, tr("Mono")),
374 PAIR(AudioMode, Stereo, "Stereo"), 391 PAIR(AudioMode, Stereo, tr("Stereo")),
375 PAIR(AudioMode, Surround, "Surround"), 392 PAIR(AudioMode, Surround, tr("Surround")),
376 }}); 393 }});
377 translations->insert({Settings::EnumMetadata<Settings::MemoryLayout>::Index(), 394 translations->insert({Settings::EnumMetadata<Settings::MemoryLayout>::Index(),
378 { 395 {
379 PAIR(MemoryLayout, Memory_4Gb, "4GB DRAM (Default)"), 396 PAIR(MemoryLayout, Memory_4Gb, tr("4GB DRAM (Default)")),
380 PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"), 397 PAIR(MemoryLayout, Memory_6Gb, tr("6GB DRAM (Unsafe)")),
381 PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"), 398 PAIR(MemoryLayout, Memory_8Gb, tr("8GB DRAM (Unsafe)")),
399 }});
400 translations->insert({Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
401 {
402 PAIR(ConsoleMode, Docked, tr("Docked")),
403 PAIR(ConsoleMode, Handheld, tr("Handheld")),
382 }}); 404 }});
383 translations->insert(
384 {Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
385 {PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}});
386 translations->insert( 405 translations->insert(
387 {Settings::EnumMetadata<Settings::ConfirmStop>::Index(), 406 {Settings::EnumMetadata<Settings::ConfirmStop>::Index(),
388 { 407 {
389 PAIR(ConfirmStop, Ask_Always, "Always ask (Default)"), 408 PAIR(ConfirmStop, Ask_Always, tr("Always ask (Default)")),
390 PAIR(ConfirmStop, Ask_Based_On_Game, "Only if game specifies not to stop"), 409 PAIR(ConfirmStop, Ask_Based_On_Game, tr("Only if game specifies not to stop")),
391 PAIR(ConfirmStop, Ask_Never, "Never ask"), 410 PAIR(ConfirmStop, Ask_Never, tr("Never ask")),
392 }}); 411 }});
393 412
394#undef PAIR 413#undef PAIR
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp
index ea8d7add4..941683a43 100644
--- a/src/yuzu/configuration/shared_widget.cpp
+++ b/src/yuzu/configuration/shared_widget.cpp
@@ -194,7 +194,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
194 return group; 194 return group;
195 } 195 }
196 196
197 const auto get_selected = [=]() -> int { 197 const auto get_selected = [this]() -> int {
198 for (const auto& [id, button] : radio_buttons) { 198 for (const auto& [id, button] : radio_buttons) {
199 if (button->isChecked()) { 199 if (button->isChecked()) {
200 return id; 200 return id;
@@ -203,7 +203,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
203 return -1; 203 return -1;
204 }; 204 };
205 205
206 const auto set_index = [=](u32 value) { 206 const auto set_index = [this](u32 value) {
207 for (const auto& [id, button] : radio_buttons) { 207 for (const auto& [id, button] : radio_buttons) {
208 button->setChecked(id == value); 208 button->setChecked(id == value);
209 } 209 }
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index ad3eada94..dc006832e 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -479,6 +479,6 @@ void GameListWorker::run() {
479 } 479 }
480 } 480 }
481 481
482 RecordEvent([=](GameList* game_list) { game_list->DonePopulating(watch_list); }); 482 RecordEvent([this](GameList* game_list) { game_list->DonePopulating(watch_list); });
483 processing_completed.Set(); 483 processing_completed.Set();
484} 484}