summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/frontend/input.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp45
-rw-r--r--src/core/hle/service/hid/hid.h3
-rw-r--r--src/core/settings.cpp3
-rw-r--r--src/core/settings.h44
5 files changed, 100 insertions, 1 deletions
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index a0c51df0c..63e64ac67 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -94,4 +94,10 @@ std::unique_ptr<InputDeviceType> CreateDevice(const std::string& params) {
return pair->second->Create(package);
}
+/**
+ * A button device is an input device that returns bool as status.
+ * true for pressed; false for released.
+ */
+using ButtonDevice = InputDevice<bool>;
+
} // namespace Input
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index fb3acb507..0da731418 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,10 @@ 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 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,10 +82,38 @@ 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>);
+}
+
+static void UnloadInputDevices() {
+ for (auto& button : buttons) {
+ button.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;
@@ -313,6 +349,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 +388,11 @@ void Shutdown() {
event_accelerometer = nullptr;
event_gyroscope = nullptr;
event_debug_pad = nullptr;
+ UnloadInputDevices();
+}
+
+void ReloadInputDevices() {
+ is_device_reload_pending.store(true);
}
} // namespace HID
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index c7f4ee138..b828abe4b 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -297,5 +297,8 @@ void Init();
/// Shutdown HID service
void Shutdown();
+
+/// Reload input devices. Used when input configuration changed
+void ReloadInputDevices();
}
}
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 3a32b70aa..a598f9f2f 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -4,6 +4,7 @@
#include "audio_core/audio_core.h"
#include "core/gdbstub/gdbstub.h"
+#include "core/hle/service/hid/hid.h"
#include "settings.h"
#include "video_core/video_core.h"
@@ -29,6 +30,8 @@ void Apply() {
AudioCore::SelectSink(values.sink_id);
AudioCore::EnableStretching(values.enable_audio_stretching);
+
+ Service::HID::ReloadInputDevices();
}
} // namespace
diff --git a/src/core/settings.h b/src/core/settings.h
index b6c75531f..dba57bd6c 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -69,6 +69,48 @@ static const std::array<Values, NUM_INPUTS> All = {{
}};
}
+namespace NativeButton {
+enum Values {
+ A,
+ B,
+ X,
+ Y,
+ Up,
+ Down,
+ Left,
+ Right,
+ L,
+ R,
+ Start,
+ Select,
+
+ ZL,
+ ZR,
+
+ Home,
+
+ NumButtons,
+};
+
+constexpr int BUTTON_HID_BEGIN = A;
+constexpr int BUTTON_IR_BEGIN = ZL;
+constexpr int BUTTON_NS_BEGIN = Home;
+
+constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN;
+constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
+constexpr int BUTTON_NS_END = NumButtons;
+
+constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
+constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
+constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
+
+static const std::array<const char*, NumButtons> mapping = {{
+ "button_a", "button_b", "button_x", "button_y", "button_up", "button_down", "button_left",
+ "button_right", "button_l", "button_r", "button_start", "button_select", "button_zl",
+ "button_zr", "button_home",
+}};
+} // namespace NativeButton
+
struct Values {
// CheckNew3DS
bool is_new_3ds;
@@ -77,6 +119,8 @@ struct Values {
std::array<int, NativeInput::NUM_INPUTS> input_mappings;
float pad_circle_modifier_scale;
+ std::array<std::string, NativeButton::NumButtons> buttons;
+
// Core
bool use_cpu_jit;