summaryrefslogtreecommitdiff
path: root/src/input_common/gcadapter
diff options
context:
space:
mode:
authorMorph <39850852+Morph1984@users.noreply.github.com>2020-10-20 13:55:25 -0400
committerMorph <39850852+Morph1984@users.noreply.github.com>2020-11-15 23:33:20 -0500
commite9e1876e821b8bd1bb5c8254ec93e2cc479e16dd (patch)
tree344b40a5a874cb188c6e7aa7d1622c77a215090d /src/input_common/gcadapter
parent38110dd485e329fa39e2e4c02b91a89dfebcbc88 (diff)
input_common: Add VibrationDevice and VibrationDeviceFactory
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.
Diffstat (limited to 'src/input_common/gcadapter')
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp6
-rw-r--r--src/input_common/gcadapter/gc_adapter.h4
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp50
-rw-r--r--src/input_common/gcadapter/gc_poller.h11
4 files changed, 55 insertions, 16 deletions
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index b912188b6..d80195c82 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -230,10 +230,8 @@ void Adapter::SendVibrations() {
vibration_changed = false;
}
-bool Adapter::RumblePlay(std::size_t port, f32 amplitude) {
- amplitude = std::clamp(amplitude, 0.0f, 1.0f);
- const auto raw_amp = static_cast<u8>(amplitude * 0x8);
- pads[port].rumble_amplitude = raw_amp;
+bool Adapter::RumblePlay(std::size_t port, u8 amplitude) {
+ pads[port].rumble_amplitude = amplitude;
return rumble_enabled;
}
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index d28dcfad3..f1256c9da 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -77,8 +77,8 @@ public:
Adapter();
~Adapter();
- /// Request a vibration for a controlelr
- bool RumblePlay(std::size_t port, f32 amplitude);
+ /// Request a vibration for a controller
+ bool RumblePlay(std::size_t port, u8 amplitude);
/// Used for polling
void BeginConfiguration();
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 6bd6f57fc..fe57c13a5 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -15,7 +15,7 @@ namespace InputCommon {
class GCButton final : public Input::ButtonDevice {
public:
- explicit GCButton(u32 port_, s32 button_, GCAdapter::Adapter* adapter)
+ explicit GCButton(u32 port_, s32 button_, const GCAdapter::Adapter* adapter)
: port(port_), button(button_), gcadapter(adapter) {}
~GCButton() override;
@@ -27,18 +27,10 @@ public:
return false;
}
- bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
- const float amplitude = amp_high + amp_low > 2.0f ? 1.0f : (amp_high + amp_low) * 0.5f;
- const auto new_amp =
- static_cast<f32>(pow(amplitude, 0.5f) * (3.0f - 2.0f * pow(amplitude, 0.15f)));
-
- return gcadapter->RumblePlay(port, new_amp);
- }
-
private:
const u32 port;
const s32 button;
- GCAdapter::Adapter* gcadapter;
+ const GCAdapter::Adapter* gcadapter;
};
class GCAxisButton final : public Input::ButtonDevice {
@@ -299,4 +291,42 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
return params;
}
+class GCVibration final : public Input::VibrationDevice {
+public:
+ explicit GCVibration(u32 port_, GCAdapter::Adapter* adapter)
+ : port(port_), gcadapter(adapter) {}
+
+ u8 GetStatus() const override {
+ return gcadapter->RumblePlay(port, 0);
+ }
+
+ bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
+ const auto mean_amplitude = (amp_low + amp_high) * 0.5f;
+ const auto processed_amplitude = static_cast<u8>(
+ pow(mean_amplitude, 0.5f) * (3.0f - 2.0f * pow(mean_amplitude, 0.15f)) * 0x8);
+
+ return gcadapter->RumblePlay(port, processed_amplitude);
+ }
+
+private:
+ const u32 port;
+ GCAdapter::Adapter* gcadapter;
+};
+
+/// An vibration device factory that creates vibration devices from GC Adapter
+GCVibrationFactory::GCVibrationFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
+ : adapter(std::move(adapter_)) {}
+
+/**
+ * Creates a vibration device from a joystick
+ * @param params contains parameters for creating the device:
+ * - "port": the nth gcpad on the adapter
+ */
+std::unique_ptr<Input::VibrationDevice> GCVibrationFactory::Create(
+ const Common::ParamPackage& params) {
+ const auto port = static_cast<u32>(params.Get("port", 0));
+
+ return std::make_unique<GCVibration>(port, adapter.get());
+}
+
} // namespace InputCommon
diff --git a/src/input_common/gcadapter/gc_poller.h b/src/input_common/gcadapter/gc_poller.h
index 0527f328f..d1271e3ea 100644
--- a/src/input_common/gcadapter/gc_poller.h
+++ b/src/input_common/gcadapter/gc_poller.h
@@ -64,4 +64,15 @@ private:
bool polling = false;
};
+/// A vibration device factory creates vibration devices from GC Adapter
+class GCVibrationFactory final : public Input::Factory<Input::VibrationDevice> {
+public:
+ explicit GCVibrationFactory(std::shared_ptr<GCAdapter::Adapter> adapter_);
+
+ std::unique_ptr<Input::VibrationDevice> Create(const Common::ParamPackage& params) override;
+
+private:
+ std::shared_ptr<GCAdapter::Adapter> adapter;
+};
+
} // namespace InputCommon