summaryrefslogtreecommitdiffstats
path: root/src/hid_core/resources
diff options
context:
space:
mode:
authorNarr the Reg <juangerman-13@hotmail.com>2024-01-11 05:06:54 +0100
committergerman77 <juangerman-13@hotmail.com>2024-01-16 06:15:40 +0100
commit2cacb9d48c98603176e52ecc94f2374a934797fb (patch)
tree12badf5b4eede22b22dece03a9074197ec631a1e /src/hid_core/resources
parentMerge pull request #12686 from szepeviktor/typos3 (diff)
downloadyuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.gz
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.bz2
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.lz
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.xz
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.zst
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.zip
Diffstat (limited to 'src/hid_core/resources')
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp2
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h6
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_pad.cpp13
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_pad.h6
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp42
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h12
-rw-r--r--src/hid_core/resources/applet_resource.cpp19
-rw-r--r--src/hid_core/resources/applet_resource.h1
-rw-r--r--src/hid_core/resources/npad/npad.cpp292
-rw-r--r--src/hid_core/resources/npad/npad.h59
-rw-r--r--src/hid_core/resources/npad/npad_types.h6
-rw-r--r--src/hid_core/resources/npad/npad_vibration.cpp4
-rw-r--r--src/hid_core/resources/npad/npad_vibration.h2
-rw-r--r--src/hid_core/resources/vibration/gc_vibration_device.cpp56
-rw-r--r--src/hid_core/resources/vibration/gc_vibration_device.h10
-rw-r--r--src/hid_core/resources/vibration/n64_vibration_device.cpp57
-rw-r--r--src/hid_core/resources/vibration/n64_vibration_device.h8
-rw-r--r--src/hid_core/resources/vibration/vibration_base.cpp4
-rw-r--r--src/hid_core/resources/vibration/vibration_base.h10
-rw-r--r--src/hid_core/resources/vibration/vibration_device.cpp72
-rw-r--r--src/hid_core/resources/vibration/vibration_device.h16
21 files changed, 413 insertions, 284 deletions
diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp
index d4e4181bf..e399edfd7 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp
+++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp
@@ -115,7 +115,7 @@ Result NpadAbstractIrSensorHandler::GetXcdHandleForNpadWithIrSensor(u64& handle)
if (sensor_state < NpadIrSensorState::Available) {
return ResultIrSensorIsNotReady;
}
- handle = xcd_handle;
+ // handle = xcd_handle;
return ResultSuccess;
}
diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h
index fe8e005af..997811511 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h
+++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h
@@ -7,6 +7,10 @@
#include "core/hle/result.h"
#include "hid_core/hid_types.h"
+namespace Core::HID {
+class EmulatedController;
+}
+
namespace Kernel {
class KEvent;
class KReadableEvent;
@@ -50,7 +54,7 @@ private:
s32 ref_counter{};
Kernel::KEvent* ir_sensor_event{nullptr};
- u64 xcd_handle{};
+ Core::HID::EmulatedController* xcd_handle{};
NpadIrSensorState sensor_state{};
};
} // namespace Service::HID
diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp
index 2c7691d7c..435b095f0 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp
+++ b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "hid_core/hid_core.h"
#include "hid_core/hid_result.h"
#include "hid_core/resources/abstracted_pad/abstract_pad.h"
#include "hid_core/resources/applet_resource.h"
@@ -16,7 +17,7 @@ void AbstractPad::SetExternals(AppletResourceHolder* applet_resource,
CaptureButtonResource* capture_button_resource,
HomeButtonResource* home_button_resource,
SixAxisResource* sixaxis_resource, PalmaResource* palma_resource,
- VibrationHandler* vibration) {
+ NpadVibration* vibration, Core::HID::HIDCore* core) {
applet_resource_holder = applet_resource;
properties_handler.SetAppletResource(applet_resource_holder);
@@ -35,13 +36,14 @@ void AbstractPad::SetExternals(AppletResourceHolder* applet_resource,
mcu_handler.SetAbstractPadHolder(&abstract_pad_holder);
mcu_handler.SetPropertiesHandler(&properties_handler);
- std::array<NpadVibrationDevice*, 2> vibration_devices{&vibration_left, &vibration_right};
vibration_handler.SetAppletResource(applet_resource_holder);
vibration_handler.SetAbstractPadHolder(&abstract_pad_holder);
vibration_handler.SetPropertiesHandler(&properties_handler);
vibration_handler.SetN64Vibration(&vibration_n64);
- vibration_handler.SetVibration(vibration_devices);
+ vibration_handler.SetVibration(&vibration_left, &vibration_right);
vibration_handler.SetGcVibration(&vibration_gc);
+ vibration_handler.SetVibrationHandler(vibration);
+ vibration_handler.SetHidCore(core);
sixaxis_handler.SetAppletResource(applet_resource_holder);
sixaxis_handler.SetAbstractPadHolder(&abstract_pad_holder);
@@ -239,11 +241,6 @@ NpadVibrationDevice* AbstractPad::GetVibrationDevice(Core::HID::DeviceIndex devi
return &vibration_left;
}
-void AbstractPad::GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list) {
- list.emplace_back(&vibration_left);
- list.emplace_back(&vibration_right);
-}
-
NpadGcVibrationDevice* AbstractPad::GetGCVibrationDevice() {
return &vibration_gc;
}
diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.h b/src/hid_core/resources/abstracted_pad/abstract_pad.h
index cbdf84af7..329792457 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_pad.h
+++ b/src/hid_core/resources/abstracted_pad/abstract_pad.h
@@ -32,7 +32,6 @@ class AppletResource;
class SixAxisResource;
class PalmaResource;
class NPadResource;
-class AbstractPad;
class NpadLastActiveHandler;
class NpadIrNfcHandler;
class UniquePads;
@@ -44,7 +43,6 @@ class NpadGcVibration;
class CaptureButtonResource;
class HomeButtonResource;
-class VibrationHandler;
struct HandheldConfig;
@@ -57,7 +55,8 @@ public:
void SetExternals(AppletResourceHolder* applet_resource,
CaptureButtonResource* capture_button_resource,
HomeButtonResource* home_button_resource, SixAxisResource* sixaxis_resource,
- PalmaResource* palma_resource, VibrationHandler* vibration);
+ PalmaResource* palma_resource, NpadVibration* vibration,
+ Core::HID::HIDCore* core);
void SetNpadId(Core::HID::NpadIdType npad_id);
Result Activate();
@@ -78,7 +77,6 @@ public:
NpadN64VibrationDevice* GetN64VibrationDevice();
NpadVibrationDevice* GetVibrationDevice(Core::HID::DeviceIndex device_index);
- void GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list);
NpadGcVibrationDevice* GetGCVibrationDevice();
Core::HID::NpadIdType GetLastActiveNpad();
diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp
index a00d6c9de..ca64b0a43 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp
+++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp
@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "hid_core/frontend/emulated_controller.h"
+#include "hid_core/hid_core.h"
#include "hid_core/hid_result.h"
#include "hid_core/hid_util.h"
#include "hid_core/resources/abstracted_pad/abstract_pad_holder.h"
@@ -30,14 +32,22 @@ void NpadAbstractVibrationHandler::SetPropertiesHandler(NpadAbstractPropertiesHa
properties_handler = handler;
}
+void NpadAbstractVibrationHandler::SetVibrationHandler(NpadVibration* handler) {
+ vibration_handler = handler;
+}
+
+void NpadAbstractVibrationHandler::SetHidCore(Core::HID::HIDCore* core) {
+ hid_core = core;
+}
+
void NpadAbstractVibrationHandler::SetN64Vibration(NpadN64VibrationDevice* n64_device) {
n64_vibration_device = n64_device;
}
-void NpadAbstractVibrationHandler::SetVibration(std::span<NpadVibrationDevice*> device) {
- for (std::size_t i = 0; i < device.size() && i < vibration_device.size(); i++) {
- vibration_device[i] = device[i];
- }
+void NpadAbstractVibrationHandler::SetVibration(NpadVibrationDevice* left_device,
+ NpadVibrationDevice* right_device) {
+ left_vibration_device = left_device;
+ right_vibration_device = right_device;
}
void NpadAbstractVibrationHandler::SetGcVibration(NpadGcVibrationDevice* gc_device) {
@@ -69,5 +79,29 @@ void NpadAbstractVibrationHandler::UpdateVibrationState() {
if (!is_handheld_hid_enabled && is_force_handheld_style_vibration) {
// TODO
}
+
+ // TODO: This function isn't accurate. It's supposed to get 5 abstracted pads from the
+ // NpadAbstractPropertiesHandler but this handler isn't fully implemented yet
+ IAbstractedPad abstracted_pad{};
+ const auto npad_id = properties_handler->GetNpadId();
+ abstracted_pad.xcd_handle = hid_core->GetEmulatedController(npad_id);
+ abstracted_pad.internal_flags.is_connected.Assign(abstracted_pad.xcd_handle->IsConnected());
+
+ if (abstracted_pad.internal_flags.is_connected) {
+ left_vibration_device->Mount(abstracted_pad, Core::HID::DeviceIndex::Left,
+ vibration_handler);
+ right_vibration_device->Mount(abstracted_pad, Core::HID::DeviceIndex::Right,
+ vibration_handler);
+ gc_vibration_device->Mount(abstracted_pad, 0, vibration_handler);
+ gc_vibration_device->Mount(abstracted_pad, 0, vibration_handler);
+ n64_vibration_device->Mount(abstracted_pad, vibration_handler);
+ return;
+ }
+
+ left_vibration_device->Unmount();
+ right_vibration_device->Unmount();
+ gc_vibration_device->Unmount();
+ gc_vibration_device->Unmount();
+ n64_vibration_device->Unmount();
}
} // namespace Service::HID
diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h
index aeb07ce86..8bc8129c2 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h
+++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h
@@ -9,6 +9,10 @@
#include "core/hle/result.h"
#include "hid_core/hid_types.h"
+namespace Core::HID {
+class HIDCore;
+}
+
namespace Service::HID {
struct AppletResourceHolder;
class NpadAbstractedPadHolder;
@@ -27,9 +31,11 @@ public:
void SetAbstractPadHolder(NpadAbstractedPadHolder* holder);
void SetAppletResource(AppletResourceHolder* applet_resource);
void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler);
+ void SetVibrationHandler(NpadVibration* handler);
+ void SetHidCore(Core::HID::HIDCore* core);
void SetN64Vibration(NpadN64VibrationDevice* n64_device);
- void SetVibration(std::span<NpadVibrationDevice*> device);
+ void SetVibration(NpadVibrationDevice* left_device, NpadVibrationDevice* right_device);
void SetGcVibration(NpadGcVibrationDevice* gc_device);
Result IncrementRefCounter();
@@ -41,9 +47,11 @@ private:
AppletResourceHolder* applet_resource_holder{nullptr};
NpadAbstractedPadHolder* abstract_pad_holder{nullptr};
NpadAbstractPropertiesHandler* properties_handler{nullptr};
+ Core::HID::HIDCore* hid_core{nullptr};
NpadN64VibrationDevice* n64_vibration_device{nullptr};
- std::array<NpadVibrationDevice*, 2> vibration_device{};
+ NpadVibrationDevice* left_vibration_device{};
+ NpadVibrationDevice* right_vibration_device{};
NpadGcVibrationDevice* gc_vibration_device{nullptr};
NpadVibration* vibration_handler{nullptr};
s32 ref_counter{};
diff --git a/src/hid_core/resources/applet_resource.cpp b/src/hid_core/resources/applet_resource.cpp
index a84826050..db4134037 100644
--- a/src/hid_core/resources/applet_resource.cpp
+++ b/src/hid_core/resources/applet_resource.cpp
@@ -200,6 +200,25 @@ void AppletResource::EnableInput(u64 aruid, bool is_enabled) {
data[index].flag.enable_touchscreen.Assign(is_enabled);
}
+bool AppletResource::SetAruidValidForVibration(u64 aruid, bool is_enabled) {
+ const u64 index = GetIndexFromAruid(aruid);
+ if (index >= AruidIndexMax) {
+ return false;
+ }
+
+ if (!is_enabled && aruid == active_vibration_aruid) {
+ active_vibration_aruid = SystemAruid;
+ return true;
+ }
+
+ if (is_enabled && aruid != active_vibration_aruid) {
+ active_vibration_aruid = aruid;
+ return true;
+ }
+
+ return false;
+}
+
void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
diff --git a/src/hid_core/resources/applet_resource.h b/src/hid_core/resources/applet_resource.h
index f3f32bac1..e9710d306 100644
--- a/src/hid_core/resources/applet_resource.h
+++ b/src/hid_core/resources/applet_resource.h
@@ -101,6 +101,7 @@ public:
Result DestroySevenSixAxisTransferMemory();
void EnableInput(u64 aruid, bool is_enabled);
+ bool SetAruidValidForVibration(u64 aruid, bool is_enabled);
void EnableSixAxisSensor(u64 aruid, bool is_enabled);
void EnablePadInput(u64 aruid, bool is_enabled);
void EnableTouchScreen(u64 aruid, bool is_enabled);
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index 97537a2e2..310fa8ba7 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -21,6 +21,7 @@
#include "hid_core/hid_util.h"
#include "hid_core/resources/applet_resource.h"
#include "hid_core/resources/npad/npad.h"
+#include "hid_core/resources/npad/npad_vibration.h"
#include "hid_core/resources/shared_memory_format.h"
namespace Service::HID {
@@ -31,10 +32,6 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service
for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
auto& controller = controller_data[aruid_index][i];
controller.device = hid_core.GetEmulatedControllerByIndex(i);
- controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
- Core::HID::DEFAULT_VIBRATION_VALUE;
- controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex]
- .latest_vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE;
Core::HID::ControllerUpdateCallback engine_callback{
.on_change =
[this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
@@ -43,6 +40,10 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service
controller.callback_key = controller.device->SetCallback(engine_callback);
}
}
+ for (std::size_t i = 0; i < abstracted_pads.size(); ++i) {
+ abstracted_pads[i] = AbstractPad{};
+ abstracted_pads[i].SetNpadId(IndexToNpadIdType(i));
+ }
}
NPad::~NPad() {
@@ -359,6 +360,7 @@ void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) {
npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
WriteEmptyEntry(controller.shared_memory);
hid_core.SetLastActiveController(npad_id);
+ abstracted_pads[NpadIdTypeToIndex(npad_id)].Update();
}
void NPad::WriteEmptyEntry(NpadInternalState* npad) {
@@ -740,171 +742,6 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID:
return true;
}
-bool NPad::VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
- std::size_t device_index,
- const Core::HID::VibrationValue& vibration_value) {
- auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
- if (!controller.device->IsConnected()) {
- return false;
- }
-
- if (!controller.device->IsVibrationEnabled(device_index)) {
- if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
- controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
- // Send an empty vibration to stop any vibrations.
- Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f};
- controller.device->SetVibration(device_index, vibration);
- // Then reset the vibration value to its default value.
- controller.vibration[device_index].latest_vibration_value =
- Core::HID::DEFAULT_VIBRATION_VALUE;
- }
-
- 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 15ms of each other.
- if ((vibration_value.low_amplitude != 0.0f || vibration_value.high_amplitude != 0.0f) &&
- duration_cast<milliseconds>(
- now - controller.vibration[device_index].last_vibration_timepoint) <
- milliseconds(15)) {
- return false;
- }
-
- controller.vibration[device_index].last_vibration_timepoint = now;
- }
-
- Core::HID::VibrationValue vibration{
- vibration_value.low_amplitude, vibration_value.low_frequency,
- vibration_value.high_amplitude, vibration_value.high_frequency};
- return controller.device->SetVibration(device_index, vibration);
-}
-
-void NPad::VibrateController(u64 aruid,
- const Core::HID::VibrationDeviceHandle& vibration_device_handle,
- const Core::HID::VibrationValue& vibration_value) {
- if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
- return;
- }
-
- if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
- return;
- }
-
- auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
- const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
-
- if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) {
- return;
- }
-
- if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) {
- ASSERT_MSG(false, "DeviceIndex should never be None!");
- return;
- }
-
- // Some games try to send mismatched parameters in the device handle, block these.
- if ((controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft &&
- (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconRight ||
- vibration_device_handle.device_index == Core::HID::DeviceIndex::Right)) ||
- (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight &&
- (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconLeft ||
- vibration_device_handle.device_index == Core::HID::DeviceIndex::Left))) {
- return;
- }
-
- // Filter out vibrations with equivalent values to reduce unnecessary state changes.
- if (vibration_value.low_amplitude ==
- controller.vibration[device_index].latest_vibration_value.low_amplitude &&
- vibration_value.high_amplitude ==
- controller.vibration[device_index].latest_vibration_value.high_amplitude) {
- return;
- }
-
- if (VibrateControllerAtIndex(aruid, controller.device->GetNpadIdType(), device_index,
- vibration_value)) {
- controller.vibration[device_index].latest_vibration_value = vibration_value;
- }
-}
-
-void NPad::VibrateControllers(
- u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
- std::span<const Core::HID::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(aruid, vibration_device_handles[i], vibration_values[i]);
- }
-}
-
-Core::HID::VibrationValue NPad::GetLastVibration(
- u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
- return {};
- }
-
- const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
- const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
- return controller.vibration[device_index].latest_vibration_value;
-}
-
-void NPad::InitializeVibrationDevice(
- const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
- if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
- return;
- }
-
- const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
- const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id);
- const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
-
- if (aruid == 0) {
- return;
- }
-
- InitializeVibrationDeviceAtIndex(aruid, npad_index, device_index);
-}
-
-void NPad::InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
- std::size_t device_index) {
- auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
- if (!Settings::values.vibration_enabled.GetValue()) {
- controller.vibration[device_index].device_mounted = false;
- return;
- }
-
- controller.vibration[device_index].device_mounted =
- controller.device->IsVibrationEnabled(device_index);
-}
-
-void NPad::SetPermitVibrationSession(bool permit_vibration_session) {
- permit_vibration_session_enabled = permit_vibration_session;
-}
-
-bool NPad::IsVibrationDeviceMounted(
- u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
- return false;
- }
-
- const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
- const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
- return controller.vibration[device_index].device_mounted;
-}
-
Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
Core::HID::NpadIdType npad_id) {
std::scoped_lock lock{mutex};
@@ -936,11 +773,6 @@ Result NPad::DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id) {
LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id);
auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
- for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
- // Send an empty vibration to stop any vibrations.
- VibrateControllerAtIndex(aruid, npad_id, device_idx, {});
- controller.vibration[device_idx].device_mounted = false;
- }
auto* shared_memory = controller.shared_memory;
// Don't reset shared_memory->assignment_mode this value is persistent
@@ -1236,22 +1068,17 @@ void NPad::UnregisterAppletResourceUserId(u64 aruid) {
}
void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource,
- std::recursive_mutex* shared_mutex) {
+ std::recursive_mutex* shared_mutex,
+ std::shared_ptr<HandheldConfig> handheld_config) {
applet_resource_holder.applet_resource = resource;
applet_resource_holder.shared_mutex = shared_mutex;
applet_resource_holder.shared_npad_resource = &npad_resource;
-}
+ applet_resource_holder.handheld_config = handheld_config;
-NPad::NpadControllerData& NPad::GetControllerFromHandle(
- u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(aruid, npad_id);
-}
-
-const NPad::NpadControllerData& NPad::GetControllerFromHandle(
- u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(aruid, npad_id);
+ for (auto& abstract_pad : abstracted_pads) {
+ abstract_pad.SetExternals(&applet_resource_holder, nullptr, nullptr, nullptr, nullptr,
+ &vibration_handler, &hid_core);
+ }
}
NPad::NpadControllerData& NPad::GetControllerFromHandle(
@@ -1389,4 +1216,97 @@ Result NPad::GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const {
return ResultSuccess;
}
+NpadVibration* NPad::GetVibrationHandler() {
+ return &vibration_handler;
+}
+
+std::vector<NpadVibrationBase*> NPad::GetAllVibrationDevices() {
+ std::vector<NpadVibrationBase*> vibration_devices;
+
+ for (auto& abstract_pad : abstracted_pads) {
+ auto* left_device = abstract_pad.GetVibrationDevice(Core::HID::DeviceIndex::Left);
+ auto* right_device = abstract_pad.GetVibrationDevice(Core::HID::DeviceIndex::Right);
+ auto* n64_device = abstract_pad.GetGCVibrationDevice();
+ auto* gc_device = abstract_pad.GetGCVibrationDevice();
+
+ if (left_device != nullptr) {
+ vibration_devices.emplace_back(left_device);
+ }
+ if (right_device != nullptr) {
+ vibration_devices.emplace_back(right_device);
+ }
+ if (n64_device != nullptr) {
+ vibration_devices.emplace_back(n64_device);
+ }
+ if (gc_device != nullptr) {
+ vibration_devices.emplace_back(gc_device);
+ }
+ }
+
+ return vibration_devices;
+}
+
+NpadVibrationBase* NPad::GetVibrationDevice(const Core::HID::VibrationDeviceHandle& handle) {
+ if (IsVibrationHandleValid(handle).IsError()) {
+ return nullptr;
+ }
+
+ const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
+ const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
+ if (style_inde == Core::HID::NpadStyleIndex::GameCube) {
+ return abstracted_pads[npad_index].GetGCVibrationDevice();
+ }
+ if (style_inde == Core::HID::NpadStyleIndex::N64) {
+ return abstracted_pads[npad_index].GetN64VibrationDevice();
+ }
+ return abstracted_pads[npad_index].GetVibrationDevice(handle.device_index);
+}
+
+NpadN64VibrationDevice* NPad::GetN64VibrationDevice(
+ const Core::HID::VibrationDeviceHandle& handle) {
+ if (IsVibrationHandleValid(handle).IsError()) {
+ return nullptr;
+ }
+
+ const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
+ const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
+ if (style_inde != Core::HID::NpadStyleIndex::N64) {
+ return nullptr;
+ }
+ return abstracted_pads[npad_index].GetN64VibrationDevice();
+}
+
+NpadVibrationDevice* NPad::GetNSVibrationDevice(const Core::HID::VibrationDeviceHandle& handle) {
+ if (IsVibrationHandleValid(handle).IsError()) {
+ return nullptr;
+ }
+
+ const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
+ const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
+ if (style_inde == Core::HID::NpadStyleIndex::GameCube ||
+ style_inde == Core::HID::NpadStyleIndex::N64) {
+ return nullptr;
+ }
+
+ return abstracted_pads[npad_index].GetVibrationDevice(handle.device_index);
+}
+
+NpadGcVibrationDevice* NPad::GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle) {
+ if (IsVibrationHandleValid(handle).IsError()) {
+ return nullptr;
+ }
+
+ const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
+ const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
+ if (style_inde != Core::HID::NpadStyleIndex::GameCube) {
+ return nullptr;
+ }
+ return abstracted_pads[npad_index].GetGCVibrationDevice();
+}
+
+void NPad::UpdateHandheldAbstractState() {
+ std::scoped_lock lock{mutex};
+ abstracted_pads[NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld)].Update();
+}
+
} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 01f3dabb1..18b25c688 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -10,9 +10,15 @@
#include "common/common_types.h"
#include "hid_core/hid_types.h"
+#include "hid_core/resources/abstracted_pad/abstract_pad.h"
#include "hid_core/resources/controller_base.h"
#include "hid_core/resources/npad/npad_resource.h"
#include "hid_core/resources/npad/npad_types.h"
+#include "hid_core/resources/npad/npad_vibration.h"
+#include "hid_core/resources/vibration/gc_vibration_device.h"
+#include "hid_core/resources/vibration/n64_vibration_device.h"
+#include "hid_core/resources/vibration/vibration_base.h"
+#include "hid_core/resources/vibration/vibration_device.h"
namespace Core::HID {
class EmulatedController;
@@ -32,6 +38,7 @@ union Result;
namespace Service::HID {
class AppletResource;
+struct HandheldConfig;
struct NpadInternalState;
struct NpadSixAxisSensorLifo;
struct NpadSharedMemoryFormat;
@@ -68,31 +75,6 @@ public:
bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
- bool VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
- std::size_t device_index,
- const Core::HID::VibrationValue& vibration_value);
-
- void VibrateController(u64 aruid,
- const Core::HID::VibrationDeviceHandle& vibration_device_handle,
- const Core::HID::VibrationValue& vibration_value);
-
- void VibrateControllers(
- u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
- std::span<const Core::HID::VibrationValue> vibration_values);
-
- Core::HID::VibrationValue GetLastVibration(
- u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
-
- void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
-
- void InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
- std::size_t device_index);
-
- void SetPermitVibrationSession(bool permit_vibration_session);
-
- bool IsVibrationDeviceMounted(
- u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
-
Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
Core::HID::NpadIdType npad_id);
@@ -145,7 +127,8 @@ public:
Result RegisterAppletResourceUserId(u64 aruid);
void UnregisterAppletResourceUserId(u64 aruid);
void SetNpadExternals(std::shared_ptr<AppletResource> resource,
- std::recursive_mutex* shared_mutex);
+ std::recursive_mutex* shared_mutex,
+ std::shared_ptr<HandheldConfig> handheld_config);
AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
@@ -161,18 +144,20 @@ public:
Result GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const;
-private:
- struct VibrationData {
- bool device_mounted{};
- Core::HID::VibrationValue latest_vibration_value{};
- std::chrono::steady_clock::time_point last_vibration_timepoint{};
- };
+ NpadVibration* GetVibrationHandler();
+ std::vector<NpadVibrationBase*> GetAllVibrationDevices();
+ NpadVibrationBase* GetVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
+ NpadN64VibrationDevice* GetN64VibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
+ NpadVibrationDevice* GetNSVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
+ NpadGcVibrationDevice* GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
+ void UpdateHandheldAbstractState();
+
+private:
struct NpadControllerData {
NpadInternalState* shared_memory = nullptr;
Core::HID::EmulatedController* device = nullptr;
- std::array<VibrationData, 2> vibration{};
bool is_connected{};
// Dual joycons can have only one side connected
@@ -192,10 +177,6 @@ private:
void WriteEmptyEntry(NpadInternalState* npad);
NpadControllerData& GetControllerFromHandle(
- u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle);
- const NpadControllerData& GetControllerFromHandle(
- u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const;
- NpadControllerData& GetControllerFromHandle(
u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
const NpadControllerData& GetControllerFromHandle(
u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
@@ -215,11 +196,13 @@ private:
mutable std::mutex mutex;
NPadResource npad_resource;
AppletResourceHolder applet_resource_holder{};
+ std::array<AbstractPad, MaxSupportedNpadIdTypes> abstracted_pads;
+ NpadVibration vibration_handler{};
+
Kernel::KEvent* input_event{nullptr};
std::mutex* input_mutex{nullptr};
std::atomic<u64> press_state{};
- bool permit_vibration_session_enabled;
std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
controller_data{};
};
diff --git a/src/hid_core/resources/npad/npad_types.h b/src/hid_core/resources/npad/npad_types.h
index fd86c8e40..92700d69a 100644
--- a/src/hid_core/resources/npad/npad_types.h
+++ b/src/hid_core/resources/npad/npad_types.h
@@ -8,6 +8,10 @@
#include "common/common_types.h"
#include "hid_core/hid_types.h"
+namespace Core::HID {
+class EmulatedController;
+}
+
namespace Service::HID {
static constexpr std::size_t MaxSupportedNpadIdTypes = 10;
static constexpr std::size_t StyleIndexCount = 7;
@@ -348,7 +352,7 @@ struct IAbstractedPad {
u8 indicator;
std::vector<f32> virtual_six_axis_sensor_acceleration;
std::vector<f32> virtual_six_axis_sensor_angle;
- u64 xcd_handle;
+ Core::HID::EmulatedController* xcd_handle;
u64 color;
};
} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_vibration.cpp b/src/hid_core/resources/npad/npad_vibration.cpp
index 7056e8eab..05aad4c54 100644
--- a/src/hid_core/resources/npad/npad_vibration.cpp
+++ b/src/hid_core/resources/npad/npad_vibration.cpp
@@ -77,4 +77,8 @@ Result NpadVibration::EndPermitVibrationSession() {
return ResultSuccess;
}
+u64 NpadVibration::GetSessionAruid() const {
+ return session_aruid;
+}
+
} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_vibration.h b/src/hid_core/resources/npad/npad_vibration.h
index 0748aeffc..d5a95f2a0 100644
--- a/src/hid_core/resources/npad/npad_vibration.h
+++ b/src/hid_core/resources/npad/npad_vibration.h
@@ -25,6 +25,8 @@ public:
Result BeginPermitVibrationSession(u64 aruid);
Result EndPermitVibrationSession();
+ u64 GetSessionAruid() const;
+
private:
f32 volume{};
u64 session_aruid{};
diff --git a/src/hid_core/resources/vibration/gc_vibration_device.cpp b/src/hid_core/resources/vibration/gc_vibration_device.cpp
index f01f81b9a..ad42b9d66 100644
--- a/src/hid_core/resources/vibration/gc_vibration_device.cpp
+++ b/src/hid_core/resources/vibration/gc_vibration_device.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_result.h"
#include "hid_core/resources/npad/npad_types.h"
#include "hid_core/resources/npad/npad_vibration.h"
@@ -10,24 +11,25 @@ namespace Service::HID {
NpadGcVibrationDevice::NpadGcVibrationDevice() {}
-Result NpadGcVibrationDevice::IncrementRefCounter() {
+Result NpadGcVibrationDevice::Activate() {
if (ref_counter == 0 && is_mounted) {
f32 volume = 1.0f;
const auto result = vibration_handler->GetVibrationVolume(volume);
if (result.IsSuccess()) {
- // TODO: SendVibrationGcErmCommand
+ xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
}
}
+
ref_counter++;
return ResultSuccess;
}
-Result NpadGcVibrationDevice::DecrementRefCounter() {
- if (ref_counter == 1 && !is_mounted) {
+Result NpadGcVibrationDevice::Deactivate() {
+ if (ref_counter == 1 && is_mounted) {
f32 volume = 1.0f;
const auto result = vibration_handler->GetVibrationVolume(volume);
if (result.IsSuccess()) {
- // TODO: SendVibrationGcErmCommand
+ xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
}
}
@@ -38,6 +40,48 @@ Result NpadGcVibrationDevice::DecrementRefCounter() {
return ResultSuccess;
}
+Result NpadGcVibrationDevice::Mount(IAbstractedPad& abstracted_pad, u32 slot,
+ NpadVibration* handler) {
+ if (!abstracted_pad.internal_flags.is_connected) {
+ return ResultSuccess;
+ }
+
+ // TODO: This device doesn't use a xcd handle instead has an GC adapter handle. This is just to
+ // keep compatibility with the front end.
+ xcd_handle = abstracted_pad.xcd_handle;
+ adapter_slot = slot;
+ vibration_handler = handler;
+ is_mounted = true;
+
+ if (ref_counter == 0) {
+ return ResultSuccess;
+ }
+
+ f32 volume{1.0f};
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
+ }
+
+ return ResultSuccess;
+}
+
+Result NpadGcVibrationDevice::Unmount() {
+ if (ref_counter == 0 || !is_mounted) {
+ is_mounted = false;
+ return ResultSuccess;
+ }
+
+ f32 volume{1.0f};
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
+ }
+
+ is_mounted = false;
+ return ResultSuccess;
+}
+
Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) {
if (!is_mounted) {
return ResultSuccess;
@@ -55,7 +99,7 @@ Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcEr
return ResultSuccess;
}
}
- // TODO: SendVibrationGcErmCommand
+ xcd_handle->SetVibration(adapter_slot, command);
return ResultSuccess;
}
diff --git a/src/hid_core/resources/vibration/gc_vibration_device.h b/src/hid_core/resources/vibration/gc_vibration_device.h
index 87abca57d..c624cbb28 100644
--- a/src/hid_core/resources/vibration/gc_vibration_device.h
+++ b/src/hid_core/resources/vibration/gc_vibration_device.h
@@ -20,12 +20,18 @@ class NpadGcVibrationDevice final : public NpadVibrationBase {
public:
explicit NpadGcVibrationDevice();
- Result IncrementRefCounter() override;
- Result DecrementRefCounter() override;
+ Result Activate() override;
+ Result Deactivate() override;
+
+ Result Mount(IAbstractedPad& abstracted_pad, u32 slot, NpadVibration* handler);
+ Result Unmount();
Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command);
Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& out_command);
Result SendVibrationNotificationPattern(Core::HID::VibrationGcErmCommand command);
+
+private:
+ u32 adapter_slot;
};
} // namespace Service::HID
diff --git a/src/hid_core/resources/vibration/n64_vibration_device.cpp b/src/hid_core/resources/vibration/n64_vibration_device.cpp
index 639f87abf..94ad37c8f 100644
--- a/src/hid_core/resources/vibration/n64_vibration_device.cpp
+++ b/src/hid_core/resources/vibration/n64_vibration_device.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_result.h"
#include "hid_core/resources/npad/npad_types.h"
#include "hid_core/resources/npad/npad_vibration.h"
@@ -10,12 +11,12 @@ namespace Service::HID {
NpadN64VibrationDevice::NpadN64VibrationDevice() {}
-Result NpadN64VibrationDevice::IncrementRefCounter() {
+Result NpadN64VibrationDevice::Activate() {
if (ref_counter == 0 && is_mounted) {
f32 volume = 1.0f;
const auto result = vibration_handler->GetVibrationVolume(volume);
if (result.IsSuccess()) {
- // TODO: SendVibrationInBool
+ xcd_handle->SetVibration(false);
}
}
@@ -23,19 +24,12 @@ Result NpadN64VibrationDevice::IncrementRefCounter() {
return ResultSuccess;
}
-Result NpadN64VibrationDevice::DecrementRefCounter() {
- if (ref_counter == 1) {
- if (!is_mounted) {
- ref_counter = 0;
- if (is_mounted != false) {
- // TODO: SendVibrationInBool
- }
- return ResultSuccess;
- }
+Result NpadN64VibrationDevice::Deactivate() {
+ if (ref_counter == 1 && is_mounted) {
f32 volume = 1.0f;
const auto result = vibration_handler->GetVibrationVolume(volume);
if (result.IsSuccess()) {
- // TODO
+ xcd_handle->SetVibration(false);
}
}
@@ -46,6 +40,43 @@ Result NpadN64VibrationDevice::DecrementRefCounter() {
return ResultSuccess;
}
+Result NpadN64VibrationDevice::Mount(IAbstractedPad& abstracted_pad, NpadVibration* handler) {
+ if (!abstracted_pad.internal_flags.is_connected) {
+ return ResultSuccess;
+ }
+ xcd_handle = abstracted_pad.xcd_handle;
+ vibration_handler = handler;
+ is_mounted = true;
+
+ if (ref_counter == 0) {
+ return ResultSuccess;
+ }
+
+ f32 volume{1.0f};
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(false);
+ }
+
+ return ResultSuccess;
+}
+
+Result NpadN64VibrationDevice::Unmount() {
+ if (ref_counter == 0 || !is_mounted) {
+ is_mounted = false;
+ return ResultSuccess;
+ }
+
+ f32 volume{1.0f};
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(false);
+ }
+
+ is_mounted = false;
+ return ResultSuccess;
+}
+
Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) {
if (ref_counter < 1) {
return ResultVibrationNotInitialized;
@@ -56,7 +87,7 @@ Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) {
if (result.IsError()) {
return result;
}
- // TODO: SendVibrationInBool
+ xcd_handle->SetVibration(false);
}
return ResultSuccess;
}
diff --git a/src/hid_core/resources/vibration/n64_vibration_device.h b/src/hid_core/resources/vibration/n64_vibration_device.h
index 54e6efc1a..09de7701c 100644
--- a/src/hid_core/resources/vibration/n64_vibration_device.h
+++ b/src/hid_core/resources/vibration/n64_vibration_device.h
@@ -14,14 +14,18 @@
namespace Service::HID {
class NpadVibration;
+struct IAbstractedPad;
/// Handles Npad request from HID interfaces
class NpadN64VibrationDevice final : public NpadVibrationBase {
public:
explicit NpadN64VibrationDevice();
- Result IncrementRefCounter() override;
- Result DecrementRefCounter() override;
+ Result Activate() override;
+ Result Deactivate() override;
+
+ Result Mount(IAbstractedPad& abstracted_pad, NpadVibration* handler);
+ Result Unmount();
Result SendValueInBool(bool is_vibrating);
Result SendVibrationNotificationPattern(u32 pattern);
diff --git a/src/hid_core/resources/vibration/vibration_base.cpp b/src/hid_core/resources/vibration/vibration_base.cpp
index 350f349c2..f28d30406 100644
--- a/src/hid_core/resources/vibration/vibration_base.cpp
+++ b/src/hid_core/resources/vibration/vibration_base.cpp
@@ -10,12 +10,12 @@ namespace Service::HID {
NpadVibrationBase::NpadVibrationBase() {}
-Result NpadVibrationBase::IncrementRefCounter() {
+Result NpadVibrationBase::Activate() {
ref_counter++;
return ResultSuccess;
}
-Result NpadVibrationBase::DecrementRefCounter() {
+Result NpadVibrationBase::Deactivate() {
if (ref_counter > 0) {
ref_counter--;
}
diff --git a/src/hid_core/resources/vibration/vibration_base.h b/src/hid_core/resources/vibration/vibration_base.h
index c6c5fc4d9..69c26e669 100644
--- a/src/hid_core/resources/vibration/vibration_base.h
+++ b/src/hid_core/resources/vibration/vibration_base.h
@@ -6,6 +6,10 @@
#include "common/common_types.h"
#include "core/hle/result.h"
+namespace Core::HID {
+class EmulatedController;
+}
+
namespace Service::HID {
class NpadVibration;
@@ -14,13 +18,13 @@ class NpadVibrationBase {
public:
explicit NpadVibrationBase();
- virtual Result IncrementRefCounter();
- virtual Result DecrementRefCounter();
+ virtual Result Activate();
+ virtual Result Deactivate();
bool IsVibrationMounted() const;
protected:
- u64 xcd_handle{};
+ Core::HID::EmulatedController* xcd_handle{nullptr};
s32 ref_counter{};
bool is_mounted{};
NpadVibration* vibration_handler{nullptr};
diff --git a/src/hid_core/resources/vibration/vibration_device.cpp b/src/hid_core/resources/vibration/vibration_device.cpp
index 888c3a7ed..08b14591f 100644
--- a/src/hid_core/resources/vibration/vibration_device.cpp
+++ b/src/hid_core/resources/vibration/vibration_device.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_result.h"
#include "hid_core/resources/npad/npad_types.h"
#include "hid_core/resources/npad/npad_vibration.h"
@@ -10,12 +11,30 @@ namespace Service::HID {
NpadVibrationDevice::NpadVibrationDevice() {}
-Result NpadVibrationDevice::IncrementRefCounter() {
+Result NpadVibrationDevice::Activate() {
+ if (ref_counter == 0 && is_mounted) {
+ f32 volume = 1.0f;
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
+ // TODO: SendNotificationPattern;
+ }
+ }
+
ref_counter++;
return ResultSuccess;
}
-Result NpadVibrationDevice::DecrementRefCounter() {
+Result NpadVibrationDevice::Deactivate() {
+ if (ref_counter == 1 && is_mounted) {
+ f32 volume = 1.0f;
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
+ // TODO: SendNotificationPattern;
+ }
+ }
+
if (ref_counter > 0) {
ref_counter--;
}
@@ -23,6 +42,45 @@ Result NpadVibrationDevice::DecrementRefCounter() {
return ResultSuccess;
}
+Result NpadVibrationDevice::Mount(IAbstractedPad& abstracted_pad, Core::HID::DeviceIndex index,
+ NpadVibration* handler) {
+ if (!abstracted_pad.internal_flags.is_connected) {
+ return ResultSuccess;
+ }
+ xcd_handle = abstracted_pad.xcd_handle;
+ device_index = index;
+ vibration_handler = handler;
+ is_mounted = true;
+
+ if (ref_counter == 0) {
+ return ResultSuccess;
+ }
+
+ f32 volume{1.0f};
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(false);
+ }
+
+ return ResultSuccess;
+}
+
+Result NpadVibrationDevice::Unmount() {
+ if (ref_counter == 0 || !is_mounted) {
+ is_mounted = false;
+ return ResultSuccess;
+ }
+
+ f32 volume{1.0f};
+ const auto result = vibration_handler->GetVibrationVolume(volume);
+ if (result.IsSuccess()) {
+ xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
+ }
+
+ is_mounted = false;
+ return ResultSuccess;
+}
+
Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) {
if (ref_counter == 0) {
return ResultVibrationNotInitialized;
@@ -37,7 +95,7 @@ Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue&
return result;
}
if (volume <= 0.0f) {
- // TODO: SendVibrationValue
+ xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
return ResultSuccess;
}
@@ -45,7 +103,7 @@ Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue&
vibration_value.high_amplitude *= volume;
vibration_value.low_amplitude *= volume;
- // TODO: SendVibrationValue
+ xcd_handle->SetVibration(device_index, vibration_value);
return ResultSuccess;
}
@@ -63,11 +121,11 @@ Result NpadVibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u3
pattern = 0;
}
- // return xcd_handle->SendVibrationNotificationPattern(pattern);
+ // TODO: SendVibrationNotificationPattern;
return ResultSuccess;
}
-Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) {
+Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) const {
if (ref_counter < 1) {
return ResultVibrationNotInitialized;
}
@@ -77,7 +135,7 @@ Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& o
return ResultSuccess;
}
- // TODO: SendVibrationValue
+ out_value = xcd_handle->GetActualVibrationValue(device_index);
return ResultSuccess;
}
diff --git a/src/hid_core/resources/vibration/vibration_device.h b/src/hid_core/resources/vibration/vibration_device.h
index 3574ad60b..c2f9891d3 100644
--- a/src/hid_core/resources/vibration/vibration_device.h
+++ b/src/hid_core/resources/vibration/vibration_device.h
@@ -12,6 +12,10 @@
#include "hid_core/resources/npad/npad_types.h"
#include "hid_core/resources/vibration/vibration_base.h"
+namespace Core::HID {
+enum class DeviceIndex : u8;
+}
+
namespace Service::HID {
class NpadVibration;
@@ -20,16 +24,20 @@ class NpadVibrationDevice final : public NpadVibrationBase {
public:
explicit NpadVibrationDevice();
- Result IncrementRefCounter();
- Result DecrementRefCounter();
+ Result Activate();
+ Result Deactivate();
+
+ Result Mount(IAbstractedPad& abstracted_pad, Core::HID::DeviceIndex index,
+ NpadVibration* handler);
+ Result Unmount();
Result SendVibrationValue(const Core::HID::VibrationValue& value);
Result SendVibrationNotificationPattern(u32 pattern);
- Result GetActualVibrationValue(Core::HID::VibrationValue& out_value);
+ Result GetActualVibrationValue(Core::HID::VibrationValue& out_value) const;
private:
- u32 device_index{};
+ Core::HID::DeviceIndex device_index{};
};
} // namespace Service::HID