summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-11-18 05:02:27 +0100
committerGitHub <noreply@github.com>2020-11-18 05:02:27 +0100
commitabda36636245c416a75774165d2a5b49610952fc (patch)
tree0bf3bab90e2155a3a16ffa21eabbc2a4c8f9d39d /src/core
parentMerge pull request #4933 from lioncash/nodisc-gpu (diff)
parentsdl_impl: Pump SDL Events at 1000 Hz (diff)
downloadyuzu-abda36636245c416a75774165d2a5b49610952fc.tar
yuzu-abda36636245c416a75774165d2a5b49610952fc.tar.gz
yuzu-abda36636245c416a75774165d2a5b49610952fc.tar.bz2
yuzu-abda36636245c416a75774165d2a5b49610952fc.tar.lz
yuzu-abda36636245c416a75774165d2a5b49610952fc.tar.xz
yuzu-abda36636245c416a75774165d2a5b49610952fc.tar.zst
yuzu-abda36636245c416a75774165d2a5b49610952fc.zip
Diffstat (limited to '')
-rw-r--r--src/core/frontend/applets/controller.cpp8
-rw-r--r--src/core/frontend/framebuffer_layout.cpp2
-rw-r--r--src/core/frontend/input.h9
-rw-r--r--src/core/hle/service/am/am.cpp4
-rw-r--r--src/core/hle/service/am/applets/controller.cpp4
-rw-r--r--src/core/hle/service/apm/controller.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp270
-rw-r--r--src/core/hle/service/hid/controllers/npad.h131
-rw-r--r--src/core/hle/service/hid/hid.cpp703
-rw-r--r--src/core/hle/service/hid/hid.h37
-rw-r--r--src/core/hle/service/vi/vi.cpp2
-rw-r--r--src/core/settings.cpp8
-rw-r--r--src/core/settings.h58
-rw-r--r--src/core/telemetry_session.cpp2
14 files changed, 857 insertions, 384 deletions
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 5582091f4..03bbedf8b 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -27,19 +27,19 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
->GetAppletResource()
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
- auto& players = Settings::values.players;
+ auto& players = Settings::values.players.GetValue();
const std::size_t min_supported_players =
parameters.enable_single_mode ? 1 : parameters.min_players;
// Disconnect Handheld first.
- npad.DisconnectNPadAtIndex(8);
+ npad.DisconnectNpadAtIndex(8);
// Deduce the best configuration based on the input parameters.
for (std::size_t index = 0; index < players.size() - 2; ++index) {
// First, disconnect all controllers regardless of the value of keep_controllers_connected.
// This makes it easy to connect the desired controllers.
- npad.DisconnectNPadAtIndex(index);
+ npad.DisconnectNpadAtIndex(index);
// Only connect the minimum number of required players.
if (index >= min_supported_players) {
@@ -66,7 +66,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
npad.MapSettingsTypeToNPad(Settings::ControllerType::RightJoycon), index);
}
} else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld &&
- !Settings::values.use_docked_mode) {
+ !Settings::values.use_docked_mode.GetValue()) {
// We should *never* reach here under any normal circumstances.
npad.AddNewControllerAt(npad.MapSettingsTypeToNPad(Settings::ControllerType::Handheld),
index);
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 1acc82497..b9a270a55 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -47,7 +47,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) {
u32 width, height;
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
width = ScreenDocked::Width * res_scale;
height = ScreenDocked::Height * res_scale;
} else {
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index 277b70e53..25ac5af46 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -33,7 +33,7 @@ public:
virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const {
return {};
}
- virtual bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const {
+ virtual bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const {
return {};
}
};
@@ -122,6 +122,13 @@ using ButtonDevice = InputDevice<bool>;
using AnalogDevice = InputDevice<std::tuple<float, float>>;
/**
+ * A vibration device is an input device that returns an unsigned byte as status.
+ * It represents whether the vibration device supports vibration or not.
+ * If the status returns 1, it supports vibration. Otherwise, it does not support vibration.
+ */
+using VibrationDevice = InputDevice<u8>;
+
+/**
* A motion status is an object that returns a tuple of accelerometer state vector,
* gyroscope state vector, rotation state vector and orientation state matrix.
*
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 2ce742e35..eb097738a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -751,7 +751,7 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) *
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) *
@@ -824,7 +824,7 @@ void IStorage::Open(Kernel::HLERequestContext& ctx) {
}
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
- const bool use_docked_mode{Settings::values.use_docked_mode};
+ const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()};
LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index a0152b4ea..3ca63f020 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -25,7 +25,7 @@ namespace Service::AM::Applets {
static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text,
std::vector<IdentificationColor> identification_colors, std::vector<ExplainText> text) {
- HID::Controller_NPad::NPadType npad_style_set;
+ HID::Controller_NPad::NpadStyleSet npad_style_set;
npad_style_set.raw = private_arg.style_set;
return {
@@ -222,7 +222,7 @@ void Controller::Execute() {
void Controller::ConfigurationComplete() {
ControllerSupportResultInfo result_info{};
- const auto& players = Settings::values.players;
+ const auto& players = Settings::values.players.GetValue();
// If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
// Otherwise, only count connected players from P1-P8.
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp
index 25a886238..ce993bad3 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/controller.cpp
@@ -69,7 +69,8 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
}
PerformanceMode Controller::GetCurrentPerformanceMode() const {
- return Settings::values.use_docked_mode ? PerformanceMode::Docked : PerformanceMode::Handheld;
+ return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Docked
+ : PerformanceMode::Handheld;
}
PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index e311bc18c..e2539ded8 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -117,7 +117,10 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
}
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
-Controller_NPad::~Controller_NPad() = default;
+
+Controller_NPad::~Controller_NPad() {
+ OnRelease();
+}
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
const auto controller_type = connected_controllers[controller_idx].type;
@@ -139,7 +142,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
controller.properties.is_vertical.Assign(1);
controller.properties.use_plus.Assign(1);
controller.properties.use_minus.Assign(1);
- controller.pad_assignment = NPadAssignments::Single;
+ controller.pad_assignment = NpadAssignments::Single;
break;
case NPadControllerType::Handheld:
controller.joy_styles.handheld.Assign(1);
@@ -147,7 +150,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
controller.properties.is_vertical.Assign(1);
controller.properties.use_plus.Assign(1);
controller.properties.use_minus.Assign(1);
- controller.pad_assignment = NPadAssignments::Dual;
+ controller.pad_assignment = NpadAssignments::Dual;
break;
case NPadControllerType::JoyDual:
controller.joy_styles.joycon_dual.Assign(1);
@@ -156,26 +159,26 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
controller.properties.is_vertical.Assign(1);
controller.properties.use_plus.Assign(1);
controller.properties.use_minus.Assign(1);
- controller.pad_assignment = NPadAssignments::Dual;
+ controller.pad_assignment = NpadAssignments::Dual;
break;
case NPadControllerType::JoyLeft:
controller.joy_styles.joycon_left.Assign(1);
controller.device_type.joycon_left.Assign(1);
controller.properties.is_horizontal.Assign(1);
controller.properties.use_minus.Assign(1);
- controller.pad_assignment = NPadAssignments::Single;
+ controller.pad_assignment = NpadAssignments::Single;
break;
case NPadControllerType::JoyRight:
controller.joy_styles.joycon_right.Assign(1);
controller.device_type.joycon_right.Assign(1);
controller.properties.is_horizontal.Assign(1);
controller.properties.use_plus.Assign(1);
- controller.pad_assignment = NPadAssignments::Single;
+ controller.pad_assignment = NpadAssignments::Single;
break;
case NPadControllerType::Pokeball:
controller.joy_styles.pokeball.Assign(1);
controller.device_type.pokeball.Assign(1);
- controller.pad_assignment = NPadAssignments::Single;
+ controller.pad_assignment = NpadAssignments::Single;
break;
}
@@ -184,11 +187,14 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
controller.single_color.button_color = 0;
controller.dual_color_error = ColorReadError::ReadOk;
- controller.left_color.body_color = Settings::values.players[controller_idx].body_color_left;
- controller.left_color.button_color = Settings::values.players[controller_idx].button_color_left;
- controller.right_color.body_color = Settings::values.players[controller_idx].body_color_right;
+ controller.left_color.body_color =
+ Settings::values.players.GetValue()[controller_idx].body_color_left;
+ controller.left_color.button_color =
+ Settings::values.players.GetValue()[controller_idx].button_color_left;
+ controller.right_color.body_color =
+ Settings::values.players.GetValue()[controller_idx].body_color_right;
controller.right_color.button_color =
- Settings::values.players[controller_idx].button_color_right;
+ Settings::values.players.GetValue()[controller_idx].button_color_right;
controller.battery_level[0] = BATTERY_FULL;
controller.battery_level[1] = BATTERY_FULL;
@@ -199,7 +205,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
void Controller_NPad::OnInit() {
auto& kernel = system.Kernel();
- for (std::size_t i = 0; i < styleset_changed_events.size(); i++) {
+ for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair(
kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
}
@@ -208,6 +214,8 @@ void Controller_NPad::OnInit() {
return;
}
+ OnLoadInputDevices();
+
if (style.raw == 0) {
// We want to support all controllers
style.handheld.Assign(1);
@@ -218,12 +226,27 @@ void Controller_NPad::OnInit() {
style.pokeball.Assign(1);
}
- std::transform(Settings::values.players.begin(), Settings::values.players.end(),
- connected_controllers.begin(), [](const Settings::PlayerInput& player) {
+ std::transform(Settings::values.players.GetValue().begin(),
+ Settings::values.players.GetValue().end(), connected_controllers.begin(),
+ [](const Settings::PlayerInput& player) {
return ControllerHolder{MapSettingsTypeToNPad(player.controller_type),
player.connected};
});
+ // Connect the Player 1 or Handheld controller if none are connected.
+ if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
+ [](const ControllerHolder& controller) { return controller.is_connected; })) {
+ const auto controller =
+ MapSettingsTypeToNPad(Settings::values.players.GetValue()[0].controller_type);
+ if (controller == NPadControllerType::Handheld) {
+ Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
+ connected_controllers[HANDHELD_INDEX] = {controller, true};
+ } else {
+ Settings::values.players.GetValue()[0].connected = true;
+ connected_controllers[0] = {controller, true};
+ }
+ }
+
// Account for handheld
if (connected_controllers[HANDHELD_INDEX].is_connected) {
connected_controllers[HANDHELD_INDEX].type = NPadControllerType::Handheld;
@@ -242,7 +265,7 @@ void Controller_NPad::OnInit() {
}
void Controller_NPad::OnLoadInputDevices() {
- const auto& players = Settings::values.players;
+ const auto& players = Settings::values.players.GetValue();
for (std::size_t i = 0; i < players.size(); ++i) {
std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
@@ -250,13 +273,26 @@ void Controller_NPad::OnLoadInputDevices() {
std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>);
+ std::transform(players[i].vibrations.begin() +
+ Settings::NativeVibration::VIBRATION_HID_BEGIN,
+ players[i].vibrations.begin() + Settings::NativeVibration::VIBRATION_HID_END,
+ vibrations[i].begin(), Input::CreateDevice<Input::VibrationDevice>);
std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END,
motions[i].begin(), Input::CreateDevice<Input::MotionDevice>);
+ for (std::size_t device_idx = 0; device_idx < vibrations[i].size(); ++device_idx) {
+ InitializeVibrationDeviceAtIndex(i, device_idx);
+ }
}
}
-void Controller_NPad::OnRelease() {}
+void Controller_NPad::OnRelease() {
+ for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) {
+ for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) {
+ VibrateControllerAtIndex(npad_idx, device_idx, {});
+ }
+ }
+}
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
const auto controller_idx = NPadIdToIndex(npad_id);
@@ -339,7 +375,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
if (!IsControllerActivated()) {
return;
}
- for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
+ for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) {
auto& npad = shared_memory_entries[i];
const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states,
&npad.handheld_states,
@@ -481,7 +517,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
if (!IsControllerActivated()) {
return;
}
- for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
+ for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) {
auto& npad = shared_memory_entries[i];
const auto& controller_type = connected_controllers[i].type;
@@ -515,7 +551,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
// Try to read sixaxis sensor states
std::array<MotionDevice, 2> motion_devices;
- if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
+ if (sixaxis_sensors_enabled && Settings::values.motion_enabled.GetValue()) {
sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_devices.size(); ++e) {
const auto& device = motions[i][e];
@@ -601,15 +637,15 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
shared_memory_entries.size() * sizeof(NPadEntry));
}
-void Controller_NPad::SetSupportedStyleSet(NPadType style_set) {
+void Controller_NPad::SetSupportedStyleSet(NpadStyleSet style_set) {
style.raw = style_set.raw;
}
-Controller_NPad::NPadType Controller_NPad::GetSupportedStyleSet() const {
+Controller_NPad::NpadStyleSet Controller_NPad::GetSupportedStyleSet() const {
return style;
}
-void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) {
+void Controller_NPad::SetSupportedNpadIdTypes(u8* data, std::size_t length) {
ASSERT(length > 0 && (length % sizeof(u32)) == 0);
supported_npad_id_types.clear();
supported_npad_id_types.resize(length / sizeof(u32));
@@ -621,7 +657,7 @@ void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length)
std::memcpy(data, supported_npad_id_types.data(), supported_npad_id_types.size());
}
-std::size_t Controller_NPad::GetSupportedNPadIdTypesSize() const {
+std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
return supported_npad_id_types.size();
}
@@ -641,7 +677,7 @@ Controller_NPad::NpadHandheldActivationMode Controller_NPad::GetNpadHandheldActi
return handheld_activation_mode;
}
-void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) {
+void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) {
const std::size_t npad_index = NPadIdToIndex(npad_id);
ASSERT(npad_index < shared_memory_entries.size());
if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) {
@@ -649,35 +685,140 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode)
}
}
-void Controller_NPad::VibrateController(const std::vector<u32>& controllers,
- const std::vector<Vibration>& vibrations) {
- LOG_TRACE(Service_HID, "called");
-
- if (!Settings::values.vibration_enabled || !can_controllers_vibrate) {
- return;
+bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
+ const VibrationValue& vibration_value) {
+ if (!connected_controllers[npad_index].is_connected || !vibrations[npad_index][device_index]) {
+ return false;
}
- bool success = true;
- for (std::size_t i = 0; i < controllers.size(); ++i) {
- if (!connected_controllers[i].is_connected) {
- continue;
+
+ const auto& player = Settings::values.players.GetValue()[npad_index];
+
+ if (!player.vibration_enabled) {
+ if (latest_vibration_values[npad_index][device_index].amp_low != 0.0f ||
+ latest_vibration_values[npad_index][device_index].amp_high != 0.0f) {
+ // Send an empty vibration to stop any vibrations.
+ vibrations[npad_index][device_index]->SetRumblePlay(0.0f, 160.0f, 0.0f, 320.0f);
+ // Then reset the vibration value to its default value.
+ latest_vibration_values[npad_index][device_index] = {};
}
- using namespace Settings::NativeButton;
- const auto& button_state = buttons[i];
- if (button_state[A - BUTTON_HID_BEGIN]) {
- if (button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
- vibrations[0].amp_high, vibrations[0].amp_low, vibrations[0].freq_high,
- vibrations[0].freq_low)) {
- success = false;
- }
+
+ return false;
+ }
+
+ if (!Settings::values.enable_accurate_vibrations.GetValue()) {
+ using std::chrono::duration_cast;
+ using std::chrono::milliseconds;
+ using std::chrono::steady_clock;
+
+ const auto now = steady_clock::now();
+
+ // Filter out non-zero vibrations that are within 10ms of each other.
+ if ((vibration_value.amp_low != 0.0f || vibration_value.amp_high != 0.0f) &&
+ duration_cast<milliseconds>(now - last_vibration_timepoints[npad_index][device_index]) <
+ milliseconds(10)) {
+ return false;
}
+
+ last_vibration_timepoints[npad_index][device_index] = now;
+ }
+
+ auto& vibration = vibrations[npad_index][device_index];
+ const auto player_vibration_strength = static_cast<f32>(player.vibration_strength);
+ const auto amp_low =
+ std::min(vibration_value.amp_low * player_vibration_strength / 100.0f, 1.0f);
+ const auto amp_high =
+ std::min(vibration_value.amp_high * player_vibration_strength / 100.0f, 1.0f);
+ return vibration->SetRumblePlay(amp_low, vibration_value.freq_low, amp_high,
+ vibration_value.freq_high);
+}
+
+void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
+ const VibrationValue& vibration_value) {
+ if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
+ return;
+ }
+
+ const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
+ const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
+
+ if (!vibration_devices_mounted[npad_index][device_index] ||
+ !connected_controllers[npad_index].is_connected) {
+ return;
}
- if (success) {
- last_processed_vibration = vibrations.back();
+
+ if (vibration_device_handle.device_index == DeviceIndex::None) {
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
+ return;
+ }
+
+ // Some games try to send mismatched parameters in the device handle, block these.
+ if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft &&
+ (vibration_device_handle.npad_type == NpadType::JoyconRight ||
+ vibration_device_handle.device_index == DeviceIndex::Right)) ||
+ (connected_controllers[npad_index].type == NPadControllerType::JoyRight &&
+ (vibration_device_handle.npad_type == NpadType::JoyconLeft ||
+ vibration_device_handle.device_index == DeviceIndex::Left))) {
+ return;
+ }
+
+ // Filter out vibrations with equivalent values to reduce unnecessary state changes.
+ if (vibration_value.amp_low == latest_vibration_values[npad_index][device_index].amp_low &&
+ vibration_value.amp_high == latest_vibration_values[npad_index][device_index].amp_high) {
+ return;
+ }
+
+ if (VibrateControllerAtIndex(npad_index, device_index, vibration_value)) {
+ latest_vibration_values[npad_index][device_index] = vibration_value;
}
}
-Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
- return last_processed_vibration;
+void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
+ const std::vector<VibrationValue>& vibration_values) {
+ if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
+ return;
+ }
+
+ ASSERT_OR_EXECUTE_MSG(
+ vibration_device_handles.size() == vibration_values.size(), { return; },
+ "The amount of device handles does not match with the amount of vibration values,"
+ "this is undefined behavior!");
+
+ for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) {
+ VibrateController(vibration_device_handles[i], vibration_values[i]);
+ }
+}
+
+Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
+ const DeviceHandle& vibration_device_handle) const {
+ const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
+ const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
+ return latest_vibration_values[npad_index][device_index];
+}
+
+void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
+ const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
+ const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
+ InitializeVibrationDeviceAtIndex(npad_index, device_index);
+}
+
+void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index,
+ std::size_t device_index) {
+ if (vibrations[npad_index][device_index]) {
+ vibration_devices_mounted[npad_index][device_index] =
+ vibrations[npad_index][device_index]->GetStatus() == 1;
+ } else {
+ vibration_devices_mounted[npad_index][device_index] = false;
+ }
+}
+
+void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
+ permit_vibration_session_enabled = permit_vibration_session;
+}
+
+bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const {
+ const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
+ const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
+ return vibration_devices_mounted[npad_index][device_index];
}
std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const {
@@ -696,31 +837,38 @@ void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::siz
void Controller_NPad::UpdateControllerAt(NPadControllerType controller, std::size_t npad_index,
bool connected) {
if (!connected) {
- DisconnectNPadAtIndex(npad_index);
+ DisconnectNpadAtIndex(npad_index);
return;
}
if (controller == NPadControllerType::Handheld) {
- Settings::values.players[HANDHELD_INDEX].controller_type =
+ Settings::values.players.GetValue()[HANDHELD_INDEX].controller_type =
MapNPadToSettingsType(controller);
- Settings::values.players[HANDHELD_INDEX].connected = true;
+ Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
connected_controllers[HANDHELD_INDEX] = {controller, true};
InitNewlyAddedController(HANDHELD_INDEX);
return;
}
- Settings::values.players[npad_index].controller_type = MapNPadToSettingsType(controller);
- Settings::values.players[npad_index].connected = true;
+ Settings::values.players.GetValue()[npad_index].controller_type =
+ MapNPadToSettingsType(controller);
+ Settings::values.players.GetValue()[npad_index].connected = true;
connected_controllers[npad_index] = {controller, true};
InitNewlyAddedController(npad_index);
}
-void Controller_NPad::DisconnectNPad(u32 npad_id) {
- DisconnectNPadAtIndex(NPadIdToIndex(npad_id));
+void Controller_NPad::DisconnectNpad(u32 npad_id) {
+ DisconnectNpadAtIndex(NPadIdToIndex(npad_id));
}
-void Controller_NPad::DisconnectNPadAtIndex(std::size_t npad_index) {
- Settings::values.players[npad_index].connected = false;
+void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
+ for (std::size_t device_idx = 0; device_idx < vibrations[npad_index].size(); ++device_idx) {
+ // Send an empty vibration to stop any vibrations.
+ VibrateControllerAtIndex(npad_index, device_idx, {});
+ vibration_devices_mounted[npad_index][device_idx] = false;
+ }
+
+ Settings::values.players.GetValue()[npad_index].connected = false;
connected_controllers[npad_index].is_connected = false;
auto& controller = shared_memory_entries[npad_index];
@@ -758,7 +906,7 @@ void Controller_NPad::MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2) {
(connected_controllers[npad_index_2].type == NPadControllerType::JoyLeft &&
connected_controllers[npad_index_1].type == NPadControllerType::JoyRight)) {
// Disconnect the joycon at the second id and connect the dual joycon at the first index.
- DisconnectNPad(npad_id_2);
+ DisconnectNpad(npad_id_2);
AddNewControllerAt(NPadControllerType::JoyDual, npad_index_1);
}
}
@@ -830,14 +978,6 @@ void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_prot
unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled;
}
-void Controller_NPad::SetVibrationEnabled(bool can_vibrate) {
- can_controllers_vibrate = can_vibrate;
-}
-
-bool Controller_NPad::IsVibrationEnabled() const {
- return can_controllers_vibrate;
-}
-
void Controller_NPad::ClearAllConnectedControllers() {
for (auto& controller : connected_controllers) {
if (controller.is_connected && controller.type != NPadControllerType::None) {
@@ -882,7 +1022,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
return false;
}
// Handheld should not be supported in docked mode
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
return false;
}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index fd5c5a6eb..160dcbbe3 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -39,28 +39,30 @@ public:
// Called when input devices should be loaded
void OnLoadInputDevices() override;
- struct NPadType {
- union {
- u32_le raw{};
-
- BitField<0, 1, u32> pro_controller;
- BitField<1, 1, u32> handheld;
- BitField<2, 1, u32> joycon_dual;
- BitField<3, 1, u32> joycon_left;
- BitField<4, 1, u32> joycon_right;
+ enum class NPadControllerType {
+ None,
+ ProController,
+ Handheld,
+ JoyDual,
+ JoyLeft,
+ JoyRight,
+ Pokeball,
+ };
- BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible
- };
+ enum class NpadType : u8 {
+ ProController = 3,
+ Handheld = 4,
+ JoyconDual = 5,
+ JoyconLeft = 6,
+ JoyconRight = 7,
+ Pokeball = 9,
};
- static_assert(sizeof(NPadType) == 4, "NPadType is an invalid size");
- struct Vibration {
- f32 amp_low;
- f32 freq_low;
- f32 amp_high;
- f32 freq_high;
+ enum class DeviceIndex : u8 {
+ Left = 0,
+ Right = 1,
+ None = 2,
};
- static_assert(sizeof(Vibration) == 0x10, "Vibration is an invalid size");
enum class GyroscopeZeroDriftMode : u32 {
Loose = 0,
@@ -73,7 +75,7 @@ public:
Horizontal = 1,
};
- enum class NPadAssignments : u32_le {
+ enum class NpadAssignments : u32 {
Dual = 0,
Single = 1,
};
@@ -84,15 +86,36 @@ public:
None = 2,
};
- enum class NPadControllerType {
- None,
- ProController,
- Handheld,
- JoyDual,
- JoyLeft,
- JoyRight,
- Pokeball,
+ struct DeviceHandle {
+ NpadType npad_type{};
+ u8 npad_id{};
+ DeviceIndex device_index{};
+ INSERT_PADDING_BYTES(1);
+ };
+ static_assert(sizeof(DeviceHandle) == 4, "DeviceHandle is an invalid size");
+
+ struct NpadStyleSet {
+ union {
+ u32_le raw{};
+
+ BitField<0, 1, u32> pro_controller;
+ BitField<1, 1, u32> handheld;
+ BitField<2, 1, u32> joycon_dual;
+ BitField<3, 1, u32> joycon_left;
+ BitField<4, 1, u32> joycon_right;
+
+ BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible
+ };
+ };
+ static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
+
+ struct VibrationValue {
+ f32 amp_low{0.0f};
+ f32 freq_low{160.0f};
+ f32 amp_high{0.0f};
+ f32 freq_high{320.0f};
};
+ static_assert(sizeof(VibrationValue) == 0x10, "Vibration is an invalid size");
struct LedPattern {
explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
@@ -110,12 +133,12 @@ public:
};
};
- void SetSupportedStyleSet(NPadType style_set);
- NPadType GetSupportedStyleSet() const;
+ void SetSupportedStyleSet(NpadStyleSet style_set);
+ NpadStyleSet GetSupportedStyleSet() const;
- void SetSupportedNPadIdTypes(u8* data, std::size_t length);
+ void SetSupportedNpadIdTypes(u8* data, std::size_t length);
void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
- std::size_t GetSupportedNPadIdTypesSize() const;
+ std::size_t GetSupportedNpadIdTypesSize() const;
void SetHoldType(NpadHoldType joy_hold_type);
NpadHoldType GetHoldType() const;
@@ -123,12 +146,26 @@ public:
void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
- void SetNpadMode(u32 npad_id, NPadAssignments assignment_mode);
+ void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
+
+ bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
+ const VibrationValue& vibration_value);
+
+ void VibrateController(const DeviceHandle& vibration_device_handle,
+ const VibrationValue& vibration_value);
+
+ void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
+ const std::vector<VibrationValue>& vibration_values);
+
+ VibrationValue GetLastVibration(const DeviceHandle& vibration_device_handle) const;
+
+ void InitializeVibrationDevice(const DeviceHandle& vibration_device_handle);
+
+ void InitializeVibrationDeviceAtIndex(std::size_t npad_index, std::size_t device_index);
- void VibrateController(const std::vector<u32>& controllers,
- const std::vector<Vibration>& vibrations);
+ void SetPermitVibrationSession(bool permit_vibration_session);
- Vibration GetLastVibration() const;
+ bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const;
std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
void SignalStyleSetChangedEvent(u32 npad_id) const;
@@ -138,8 +175,8 @@ public:
// Adds a new controller at an index with connection status.
void UpdateControllerAt(NPadControllerType controller, std::size_t npad_index, bool connected);
- void DisconnectNPad(u32 npad_id);
- void DisconnectNPadAtIndex(std::size_t index);
+ void DisconnectNpad(u32 npad_id);
+ void DisconnectNpadAtIndex(std::size_t index);
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode drift_mode);
GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
@@ -148,8 +185,6 @@ public:
LedPattern GetLedPattern(u32 npad_id);
bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const;
void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id);
- void SetVibrationEnabled(bool can_vibrate);
- bool IsVibrationEnabled() const;
void ClearAllConnectedControllers();
void DisconnectAllConnectedControllers();
void ConnectAllDisconnectedControllers();
@@ -324,8 +359,8 @@ private:
};
struct NPadEntry {
- NPadType joy_styles;
- NPadAssignments pad_assignment;
+ NpadStyleSet joy_styles;
+ NpadAssignments pad_assignment;
ColorReadError single_color_error;
ControllerColor single_color;
@@ -368,7 +403,7 @@ private:
u32 press_state{};
- NPadType style{};
+ NpadStyleSet style{};
std::array<NPadEntry, 10> shared_memory_entries{};
using ButtonArray = std::array<
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>,
@@ -376,22 +411,28 @@ private:
using StickArray = std::array<
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>,
10>;
+ using VibrationArray = std::array<std::array<std::unique_ptr<Input::VibrationDevice>,
+ Settings::NativeVibration::NUM_VIBRATIONS_HID>,
+ 10>;
using MotionArray = std::array<
- std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTION_HID>,
+ std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
10>;
ButtonArray buttons;
StickArray sticks;
+ VibrationArray vibrations;
MotionArray motions;
std::vector<u32> supported_npad_id_types{};
NpadHoldType hold_type{NpadHoldType::Vertical};
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
// Each controller should have their own styleset changed event
std::array<Kernel::EventPair, 10> styleset_changed_events;
- Vibration last_processed_vibration{};
+ std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
+ std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
+ bool permit_vibration_session_enabled{false};
+ std::array<std::array<bool, 2>, 10> vibration_devices_mounted{};
std::array<ControllerHolder, 10> connected_controllers{};
std::array<bool, 10> unintended_home_button_input_protection{};
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
- bool can_controllers_vibrate{true};
bool sixaxis_sensors_enabled{true};
bool sixaxis_at_rest{true};
std::array<ControllerPad, 10> npad_pad_states{};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 50f709b25..902516b29 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -139,20 +139,34 @@ void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
public:
- IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
+ explicit IActiveVibrationDeviceList(std::shared_ptr<IAppletResource> applet_resource_)
+ : ServiceFramework("IActiveVibrationDeviceList"), applet_resource(applet_resource_) {
+ // clang-format off
static const FunctionInfo functions[] = {
- {0, &IActiveVibrationDeviceList::ActivateVibrationDevice, "ActivateVibrationDevice"},
+ {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
};
+ // clang-format on
+
RegisterHandlers(functions);
}
private:
- void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
+ void InitializeVibrationDevice(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .InitializeVibrationDevice(vibration_device_handle);
+
+ LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
+ vibration_device_handle.npad_type, vibration_device_handle.npad_id,
+ vibration_device_handle.device_index);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
+
+ std::shared_ptr<IAppletResource> applet_resource;
};
std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
@@ -241,7 +255,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{208, nullptr, "GetActualVibrationGcErmCommand"},
{209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
{210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
- {211, nullptr, "IsVibrationDeviceMounted"},
+ {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
{300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
{301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
{302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
@@ -320,142 +334,152 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IAppletResource>(applet_resource);
}
-void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
+void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto basic_xpad_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", basic_xpad_id,
- applet_resource_user_id);
+ applet_resource->ActivateController(HidController::DebugPad);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- applet_resource->ActivateController(HidController::XPad);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) {
+void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(0);
-}
+ applet_resource->ActivateController(HidController::Touchscreen);
-void Hid::ActivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(true);
- LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
+void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(false);
- LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ applet_resource->ActivateController(HidController::Mouse);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
+void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->ActivateController(HidController::Keyboard);
+
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- applet_resource->ActivateController(HidController::DebugPad);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
+void Hid::SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto flags{rp.Pop<u32>()};
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
- applet_resource->ActivateController(HidController::Touchscreen);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
+void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ u32 basic_xpad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->ActivateController(HidController::XPad);
+
+ LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
+ parameters.basic_xpad_id, parameters.applet_resource_user_id);
- applet_resource->ActivateController(HidController::Mouse);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
+void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
- applet_resource->ActivateController(HidController::Keyboard);
- IPC::ResponseBuilder rb{ctx, 2};
+ IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
+ rb.Push(0);
}
-void Hid::SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx) {
+void Hid::ActivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto flags{rp.Pop<u32>()};
- LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
+ const auto parameters{rp.PopRaw<Parameters>()};
-void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto unknown{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(true);
- LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown,
- applet_resource_user_id);
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
- applet_resource->ActivateController(HidController::Gesture);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
- // Should have no effect with how our npad sets up the data
+void Hid::DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto unknown{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(false);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
- applet_resource->ActivateController(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(true);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -463,11 +487,20 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).SetSixAxisEnabled(false);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -475,12 +508,21 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- [[maybe_unused]] const auto enable{rp.Pop<bool>()};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ bool enable_sixaxis_sensor_fusion{};
+ INSERT_PADDING_BYTES(3);
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
+ "device_index={}, applet_resource_user_id={}",
+ parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
+ parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -488,14 +530,17 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto drift_mode{rp.Pop<u32>()};
+ const auto sixaxis_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()};
+ const auto drift_mode{rp.PopEnum<Controller_NPad::GyroscopeZeroDriftMode>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetGyroscopeZeroDriftMode(Controller_NPad::GyroscopeZeroDriftMode{drift_mode});
+ .SetGyroscopeZeroDriftMode(drift_mode);
- LOG_DEBUG(Service_HID, "called, handle={}, drift_mode={}, applet_resource_user_id={}", handle,
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
+ "applet_resource_user_id={}",
+ sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
drift_mode, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -504,29 +549,42 @@ void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
- LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(
- static_cast<u32>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetGyroscopeZeroDriftMode()));
+ rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .GetGyroscopeZeroDriftMode());
}
void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetGyroscopeZeroDriftMode(Controller_NPad::GyroscopeZeroDriftMode::Standard);
- LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -534,11 +592,18 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
- LOG_DEBUG(Service_HID, "called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
@@ -546,15 +611,34 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
.IsSixAxisSensorAtRest());
}
+void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ u32 unknown{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->ActivateController(HidController::Gesture);
+
+ LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", parameters.unknown,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto supported_styleset{rp.Pop<u32>()};
- LOG_DEBUG(Service_HID, "called, supported_styleset={}", supported_styleset);
-
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetSupportedStyleSet({supported_styleset});
+ LOG_DEBUG(Service_HID, "called, supported_styleset={}", supported_styleset);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -565,21 +649,22 @@ void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
-
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(controller.GetSupportedStyleSet().raw);
+ rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .GetSupportedStyleSet()
+ .raw);
}
void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetSupportedNpadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
+
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetSupportedNPadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -588,48 +673,62 @@ void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->ActivateController(HidController::NPad);
+
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
- applet_resource->ActivateController(HidController::NPad);
}
void Hid::DeactivateNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->DeactivateController(HidController::NPad);
+
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
- applet_resource->DeactivateController(HidController::NPad);
}
void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto unknown{rp.Pop<u64>()};
+ struct Parameters {
+ u32 npad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ u64 unknown{};
+ };
- LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", npad_id,
- applet_resource_user_id, unknown);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
+ parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetStyleSetChangedEvent(npad_id));
+ .GetStyleSetChangedEvent(parameters.npad_id));
}
void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ u32 npad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .DisconnectNpad(parameters.npad_id);
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
- applet_resource->GetController<Controller_NPad>(HidController::NPad).DisconnectNPad(npad_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -642,22 +741,41 @@ void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetLedPattern(npad_id)
- .raw);
+ rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .GetLedPattern(npad_id)
+ .raw);
+}
+
+void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
+ // Should have no effect with how our npad sets up the data
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ u32 unknown{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->ActivateController(HidController::NPad);
+
+ LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", parameters.unknown,
+ parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
}
void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto hold_type{rp.Pop<u64>()};
+ const auto hold_type{rp.PopEnum<Controller_NPad::NpadHoldType>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
applet_resource_user_id, hold_type);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.SetHoldType(Controller_NPad::NpadHoldType{hold_type});
-
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -668,22 +786,26 @@ void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- const auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push<u64>(static_cast<u64>(controller.GetHoldType()));
+ rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad).GetHoldType());
}
void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ u32 npad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetNpadMode(parameters.npad_id, Controller_NPad::NpadAssignments::Single);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
+ LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
+ parameters.npad_id, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -692,16 +814,22 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
// TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault
IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto npad_joy_device_type{rp.Pop<u64>()};
+ struct Parameters {
+ u32 npad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ u64 npad_joy_device_type{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetNpadMode(parameters.npad_id, Controller_NPad::NpadAssignments::Single);
LOG_WARNING(Service_HID,
"(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
- npad_id, applet_resource_user_id, npad_joy_device_type);
-
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
+ parameters.npad_id, parameters.applet_resource_user_id,
+ parameters.npad_joy_device_type);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -709,14 +837,19 @@ void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ u32 npad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
- LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
- applet_resource_user_id);
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetNpadMode(parameters.npad_id, Controller_NPad::NpadAssignments::Dual);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
+ LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
+ parameters.npad_id, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -728,12 +861,12 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
const auto npad_id_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
+
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
-
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
@@ -742,9 +875,9 @@ void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).StartLRAssignmentMode();
+
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.StartLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -754,9 +887,9 @@ void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
+ applet_resource->GetController<Controller_NPad>(HidController::NPad).StopLRAssignmentMode();
+
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.StopLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -765,13 +898,13 @@ void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto mode{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, mode={}", applet_resource_user_id,
- mode);
+ const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .SetNpadHandheldActivationMode(Controller_NPad::NpadHandheldActivationMode{mode});
+ .SetNpadHandheldActivationMode(activation_mode);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
+ applet_resource_user_id, activation_mode);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -785,23 +918,24 @@ void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push<u64>(
- static_cast<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .GetNpadHandheldActivationMode()));
+ rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .GetNpadHandheldActivationMode());
}
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto npad_1{rp.Pop<u32>()};
- const auto npad_2{rp.Pop<u32>()};
+ const auto npad_id_1{rp.Pop<u32>()};
+ const auto npad_id_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
- applet_resource_user_id, npad_1, npad_2);
+ const bool res = applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SwapNpadAssignment(npad_id_1, npad_id_2);
+
+ LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
+ npad_id_1, npad_id_2, applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 2};
- if (controller.SwapNpadAssignment(npad_1, npad_2)) {
+ if (res) {
rb.Push(RESULT_SUCCESS);
} else {
LOG_ERROR(Service_HID, "Npads are not connected!");
@@ -811,144 +945,219 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
void Hid::IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ u32 npad_id{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
+ parameters.npad_id, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push<bool>(controller.IsUnintendedHomeButtonInputProtectionEnabled(npad_id));
+ rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id));
}
void Hid::EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto unintended_home_button_input_protection{rp.Pop<bool>()};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ bool unintended_home_button_input_protection{};
+ INSERT_PADDING_BYTES(3);
+ u32 npad_id{};
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetUnintendedHomeButtonInputProtectionEnabled(
+ parameters.unintended_home_button_input_protection, parameters.npad_id);
LOG_WARNING(Service_HID,
"(STUBBED) called, unintended_home_button_input_protection={}, npad_id={},"
"applet_resource_user_id={}",
- npad_id, unintended_home_button_input_protection, applet_resource_user_id);
-
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.SetUnintendedHomeButtonInputProtectionEnabled(
- unintended_home_button_input_protection, npad_id);
+ parameters.unintended_home_button_input_protection, parameters.npad_id,
+ parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
+void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto vibration_device_handle{rp.PopRaw<Controller_NPad::DeviceHandle>()};
+
+ VibrationDeviceInfo vibration_device_info;
+
+ vibration_device_info.type = VibrationDeviceType::LinearResonantActuator;
+
+ switch (vibration_device_handle.device_index) {
+ case Controller_NPad::DeviceIndex::Left:
+ vibration_device_info.position = VibrationDevicePosition::Left;
+ break;
+ case Controller_NPad::DeviceIndex::Right:
+ vibration_device_info.position = VibrationDevicePosition::Right;
+ break;
+ case Controller_NPad::DeviceIndex::None:
+ default:
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
+ vibration_device_info.position = VibrationDevicePosition::None;
+ break;
+ }
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
+ vibration_device_info.type, vibration_device_info.position);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw(vibration_device_info);
+}
+
+void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Controller_NPad::DeviceHandle vibration_device_handle{};
+ Controller_NPad::VibrationValue vibration_value{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .VibrateController(parameters.vibration_device_handle, parameters.vibration_value);
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
- applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(true);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
+void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Controller_NPad::DeviceHandle vibration_device_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .GetLastVibration(parameters.vibration_device_handle));
+}
+
+void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
- applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(false);
- IPC::ResponseBuilder rb{ctx, 2};
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IActiveVibrationDeviceList>(applet_resource);
}
-void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
+void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto controller{rp.Pop<u32>()};
- const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto can_vibrate{rp.Pop<bool>()};
- LOG_DEBUG(Service_HID, "called, controller={}, applet_resource_user_id={}", controller,
- applet_resource_user_id);
+ Settings::values.vibration_enabled.SetValue(can_vibrate);
+
+ LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
+}
- applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .VibrateController({controller}, {vibration_values});
+void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_HID, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(Settings::values.vibration_enabled.GetValue());
}
void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
-
- const auto controllers = ctx.ReadBuffer(0);
+ const auto handles = ctx.ReadBuffer(0);
const auto vibrations = ctx.ReadBuffer(1);
- std::vector<u32> controller_list(controllers.size() / sizeof(u32));
- std::vector<Controller_NPad::Vibration> vibration_list(vibrations.size() /
- sizeof(Controller_NPad::Vibration));
+ std::vector<Controller_NPad::DeviceHandle> vibration_device_handles(
+ handles.size() / sizeof(Controller_NPad::DeviceHandle));
+ std::vector<Controller_NPad::VibrationValue> vibration_values(
+ vibrations.size() / sizeof(Controller_NPad::VibrationValue));
- std::memcpy(controller_list.data(), controllers.data(), controllers.size());
- std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size());
+ std::memcpy(vibration_device_handles.data(), handles.data(), handles.size());
+ std::memcpy(vibration_values.data(), vibrations.data(), vibrations.size());
applet_resource->GetController<Controller_NPad>(HidController::NPad)
- .VibrateController(controller_list, vibration_list);
+ .VibrateControllers(vibration_device_handles, vibration_values);
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
-void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
+void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto controller_id{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
- applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 6};
- rb.Push(RESULT_SUCCESS);
- rb.PushRaw<Controller_NPad::Vibration>(
- applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
-}
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetPermitVibrationSession(true);
-void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "called");
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- IPC::ResponseBuilder rb{ctx, 4};
+ IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(1);
- rb.Push<u32>(0);
}
-void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
+void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
+ applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .SetPermitVibrationSession(false);
+
LOG_DEBUG(Service_HID, "called");
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IActiveVibrationDeviceList>();
}
-void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
+void Hid::IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto can_vibrate{rp.Pop<bool>()};
- Settings::values.vibration_enabled = can_vibrate;
+ struct Parameters {
+ Controller_NPad::DeviceHandle vibration_device_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
+ const auto parameters{rp.PopRaw<Parameters>()};
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
-
-void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_HID, "called");
+ LOG_DEBUG(Service_HID,
+ "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.vibration_device_handle.npad_type,
+ parameters.vibration_device_handle.npad_id,
+ parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push(Settings::values.vibration_enabled);
+ rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
+ .IsVibrationDeviceMounted(parameters.vibration_device_handle));
}
void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
@@ -964,11 +1173,19 @@ void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -976,11 +1193,19 @@ void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
void Hid::StopConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto handle{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
+ struct Parameters {
+ Controller_NPad::DeviceHandle sixaxis_handle{};
+ INSERT_PADDING_WORDS(1);
+ u64 applet_resource_user_id{};
+ };
- LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
- applet_resource_user_id);
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(
+ Service_HID,
+ "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
+ parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
+ parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index fd0372b18..c8e4a4b55 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -86,17 +86,15 @@ public:
private:
void CreateAppletResource(Kernel::HLERequestContext& ctx);
- void ActivateXpad(Kernel::HLERequestContext& ctx);
- void GetXpadIDs(Kernel::HLERequestContext& ctx);
- void ActivateSixAxisSensor(Kernel::HLERequestContext& ctx);
- void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx);
void ActivateDebugPad(Kernel::HLERequestContext& ctx);
void ActivateTouchScreen(Kernel::HLERequestContext& ctx);
void ActivateMouse(Kernel::HLERequestContext& ctx);
void ActivateKeyboard(Kernel::HLERequestContext& ctx);
void SendKeyboardLockKeyEvent(Kernel::HLERequestContext& ctx);
- void ActivateGesture(Kernel::HLERequestContext& ctx);
- void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
+ void ActivateXpad(Kernel::HLERequestContext& ctx);
+ void GetXpadIDs(Kernel::HLERequestContext& ctx);
+ void ActivateSixAxisSensor(Kernel::HLERequestContext& ctx);
+ void DeactivateSixAxisSensor(Kernel::HLERequestContext& ctx);
void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
void EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx);
@@ -104,6 +102,7 @@ private:
void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx);
+ void ActivateGesture(Kernel::HLERequestContext& ctx);
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx);
@@ -112,6 +111,7 @@ private:
void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx);
void DisconnectNpad(Kernel::HLERequestContext& ctx);
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx);
+ void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
@@ -125,15 +125,16 @@ private:
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
void IsUnintendedHomeButtonInputProtectionEnabled(Kernel::HLERequestContext& ctx);
void EnableUnintendedHomeButtonInputProtection(Kernel::HLERequestContext& ctx);
- void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
- void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
+ void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
void SendVibrationValue(Kernel::HLERequestContext& ctx);
- void SendVibrationValues(Kernel::HLERequestContext& ctx);
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
- void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
void PermitVibration(Kernel::HLERequestContext& ctx);
void IsVibrationPermitted(Kernel::HLERequestContext& ctx);
+ void SendVibrationValues(Kernel::HLERequestContext& ctx);
+ void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
+ void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
+ void IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx);
void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
void StopConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
@@ -146,6 +147,22 @@ private:
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
+ enum class VibrationDeviceType : u32 {
+ LinearResonantActuator = 1,
+ };
+
+ enum class VibrationDevicePosition : u32 {
+ None = 0,
+ Left = 1,
+ Right = 2,
+ };
+
+ struct VibrationDeviceInfo {
+ VibrationDeviceType type{};
+ VibrationDevicePosition position{};
+ };
+ static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size.");
+
std::shared_ptr<IAppletResource> applet_resource;
Core::System& system;
};
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 5b0e371fe..55e00dd93 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -771,7 +771,7 @@ private:
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) *
static_cast<u32>(Settings::values.resolution_factor.GetValue()));
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) *
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 0587b9374..aadbc3932 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -49,7 +49,7 @@ void LogSettings() {
};
LOG_INFO(Config, "yuzu Configuration:");
- log_setting("Controls_UseDockedMode", values.use_docked_mode);
+ log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue());
log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
log_setting("System_CurrentUser", values.current_user);
log_setting("System_LanguageIndex", values.language_index.GetValue());
@@ -145,6 +145,12 @@ void RestoreGlobalState() {
values.rng_seed.SetGlobal(true);
values.custom_rtc.SetGlobal(true);
values.sound_index.SetGlobal(true);
+
+ // Controls
+ values.players.SetGlobal(true);
+ values.use_docked_mode.SetGlobal(true);
+ values.vibration_enabled.SetGlobal(true);
+ values.motion_enabled.SetGlobal(true);
}
void Sanitize() {
diff --git a/src/core/settings.h b/src/core/settings.h
index 28616a574..476c3fdf3 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -65,6 +65,38 @@ private:
Type local{};
};
+/**
+ * The InputSetting class allows for getting a reference to either the global or local members.
+ * This is required as we cannot easily modify the values of user-defined types within containers
+ * using the SetValue() member function found in the Setting class. The primary purpose of this
+ * class is to store an array of 10 PlayerInput structs for both the global and local (per-game)
+ * setting and allows for easily accessing and modifying both settings.
+ */
+template <typename Type>
+class InputSetting final {
+public:
+ InputSetting() = default;
+ explicit InputSetting(Type val) : global{val} {}
+ ~InputSetting() = default;
+ void SetGlobal(bool to_global) {
+ use_global = to_global;
+ }
+ bool UsingGlobal() const {
+ return use_global;
+ }
+ Type& GetValue(bool need_global = false) {
+ if (use_global || need_global) {
+ return global;
+ }
+ return local;
+ }
+
+private:
+ bool use_global = true;
+ Type global{};
+ Type local{};
+};
+
struct TouchFromButtonMap {
std::string name;
std::vector<std::string> buttons;
@@ -133,9 +165,18 @@ struct Values {
Setting<s32> sound_index;
// Controls
- std::array<PlayerInput, 10> players;
+ InputSetting<std::array<PlayerInput, 10>> players;
+
+ Setting<bool> use_docked_mode;
- bool use_docked_mode;
+ Setting<bool> vibration_enabled;
+ Setting<bool> enable_accurate_vibrations;
+
+ Setting<bool> motion_enabled;
+ std::string motion_device;
+ std::string udp_input_address;
+ u16 udp_input_port;
+ u8 udp_pad_index;
bool mouse_enabled;
std::string mouse_device;
@@ -149,20 +190,15 @@ struct Values {
ButtonsRaw debug_pad_buttons;
AnalogsRaw debug_pad_analogs;
- bool vibration_enabled;
-
- bool motion_enabled;
- std::string motion_device;
- std::string touch_device;
TouchscreenInput touchscreen;
- std::atomic_bool is_device_reload_pending{true};
+
bool use_touch_from_button;
+ std::string touch_device;
int touch_from_button_map_index;
- std::string udp_input_address;
- u16 udp_input_port;
- u8 udp_pad_index;
std::vector<TouchFromButtonMap> touch_from_button_maps;
+ std::atomic_bool is_device_reload_pending{true};
+
// Data Storage
bool use_virtual_sd;
bool gamecard_inserted;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index ebc19e18a..e0908186b 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -213,7 +213,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
Settings::values.use_assembly_shaders.GetValue());
AddField(field_type, "Renderer_UseAsynchronousShaders",
Settings::values.use_asynchronous_shaders.GetValue());
- AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode);
+ AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue());
}
bool TelemetrySession::SubmitTestcase() {