summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/hid/hid.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2017-03-17 19:59:39 +0100
committerGitHub <noreply@github.com>2017-03-17 19:59:39 +0100
commit423ab5e2bcf5a522e5f412447c05f648df57a14c (patch)
tree1e60eaeffa59229254a47f885d2fe2cbbdc1a5c0 /src/core/hle/service/hid/hid.cpp
parentMerge pull request #2618 from wwylele/log-less-filename (diff)
parentqt/config_input: don't connect for null button (diff)
downloadyuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.tar
yuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.tar.gz
yuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.tar.bz2
yuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.tar.lz
yuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.tar.xz
yuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.tar.zst
yuzu-423ab5e2bcf5a522e5f412447c05f648df57a14c.zip
Diffstat (limited to 'src/core/hle/service/hid/hid.cpp')
-rw-r--r--src/core/hle/service/hid/hid.cpp56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index fb3acb507..b19e831fe 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2,10 +2,14 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+#include <atomic>
#include <cmath>
+#include <memory>
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/frontend/emu_window.h"
+#include "core/frontend/input.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/hid/hid.h"
@@ -44,6 +48,11 @@ constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234;
constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104;
constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101;
+static std::atomic<bool> is_device_reload_pending;
+static std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
+ buttons;
+static std::unique_ptr<Input::AnalogDevice> circle_pad;
+
static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
// 30 degree and 60 degree are angular thresholds for directions
constexpr float TAN30 = 0.577350269f;
@@ -74,14 +83,48 @@ static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
return state;
}
+static void LoadInputDevices() {
+ std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
+ Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
+ buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
+ circle_pad = Input::CreateDevice<Input::AnalogDevice>(
+ Settings::values.analogs[Settings::NativeAnalog::CirclePad]);
+}
+
+static void UnloadInputDevices() {
+ for (auto& button : buttons) {
+ button.reset();
+ }
+ circle_pad.reset();
+}
+
static void UpdatePadCallback(u64 userdata, int cycles_late) {
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
- PadState state = VideoCore::g_emu_window->GetPadState();
+ if (is_device_reload_pending.exchange(false))
+ LoadInputDevices();
+
+ PadState state;
+ using namespace Settings::NativeButton;
+ state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
+ state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
+ state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
+ state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
+ state.right.Assign(buttons[Right - BUTTON_HID_BEGIN]->GetStatus());
+ state.left.Assign(buttons[Left - BUTTON_HID_BEGIN]->GetStatus());
+ state.up.Assign(buttons[Up - BUTTON_HID_BEGIN]->GetStatus());
+ state.down.Assign(buttons[Down - BUTTON_HID_BEGIN]->GetStatus());
+ state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
+ state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
+ state.start.Assign(buttons[Start - BUTTON_HID_BEGIN]->GetStatus());
+ state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus());
// Get current circle pad position and update circle pad direction
- s16 circle_pad_x, circle_pad_y;
- std::tie(circle_pad_x, circle_pad_y) = VideoCore::g_emu_window->GetCirclePadState();
+ float circle_pad_x_f, circle_pad_y_f;
+ std::tie(circle_pad_x_f, circle_pad_y_f) = circle_pad->GetStatus();
+ constexpr int MAX_CIRCLEPAD_POS = 0x9C; // Max value for a circle pad position
+ s16 circle_pad_x = static_cast<s16>(circle_pad_x_f * MAX_CIRCLEPAD_POS);
+ s16 circle_pad_y = static_cast<s16>(circle_pad_y_f * MAX_CIRCLEPAD_POS);
state.hex |= GetCirclePadDirectionState(circle_pad_x, circle_pad_y).hex;
mem->pad.current_state.hex = state.hex;
@@ -313,6 +356,8 @@ void Init() {
AddService(new HID_U_Interface);
AddService(new HID_SPVR_Interface);
+ is_device_reload_pending.store(true);
+
using Kernel::MemoryPermission;
shared_mem =
SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read,
@@ -350,6 +395,11 @@ void Shutdown() {
event_accelerometer = nullptr;
event_gyroscope = nullptr;
event_debug_pad = nullptr;
+ UnloadInputDevices();
+}
+
+void ReloadInputDevices() {
+ is_device_reload_pending.store(true);
}
} // namespace HID