summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2022-11-19 19:21:01 +0100
committerGitHub <noreply@github.com>2022-11-19 19:21:01 +0100
commitbcbc25eeb3027445f55050baa9ecd09289141dad (patch)
treec3e93e0ca9dc41a492898520b5c8e7c28f1f7954 /src/core
parentMerge pull request #9260 from liamwhite/youre-in-big-trouble-now (diff)
parentservice: hid: Only overclock npad controllers (diff)
downloadyuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.tar
yuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.tar.gz
yuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.tar.bz2
yuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.tar.lz
yuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.tar.xz
yuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.tar.zst
yuzu-bcbc25eeb3027445f55050baa9ecd09289141dad.zip
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hid/emulated_console.cpp94
-rw-r--r--src/core/hid/emulated_console.h15
-rw-r--r--src/core/hid/input_converter.cpp3
-rw-r--r--src/core/hle/service/hid/hid.cpp32
-rw-r--r--src/core/hle/service/hid/hid.h4
5 files changed, 113 insertions, 35 deletions
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index aac45907d..fb7e5802a 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -19,27 +19,26 @@ void EmulatedConsole::ReloadFromSettings() {
}
void EmulatedConsole::SetTouchParams() {
- // TODO(german77): Support any number of fingers
std::size_t index = 0;
- // Hardcode mouse, touchscreen and cemuhook parameters
+ // We can't use mouse as touch if native mouse is enabled
if (!Settings::values.mouse_enabled) {
- // We can't use mouse as touch if native mouse is enabled
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
}
touch_params[index++] =
- Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0,touch_id:0"};
+ Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"};
touch_params[index++] =
- Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1,touch_id:1"};
- touch_params[index++] =
- Common::ParamPackage{"engine:touch,axis_x:4,axis_y:5,button:2,touch_id:2"};
- touch_params[index++] =
- Common::ParamPackage{"engine:touch,axis_x:6,axis_y:7,button:3,touch_id:3"};
- touch_params[index++] =
- Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536,touch_id:0"};
- touch_params[index++] =
- Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072,touch_id:1"};
+ Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072"};
+
+ for (int i = 0; i < static_cast<int>(MaxActiveTouchInputs); i++) {
+ Common::ParamPackage touchscreen_param{};
+ touchscreen_param.Set("engine", "touch");
+ touchscreen_param.Set("axis_x", i * 2);
+ touchscreen_param.Set("axis_y", (i * 2) + 1);
+ touchscreen_param.Set("button", i);
+ touch_params[index++] = touchscreen_param;
+ }
const auto button_index =
static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
@@ -47,7 +46,7 @@ void EmulatedConsole::SetTouchParams() {
// Map the rest of the fingers from touch from button configuration
for (const auto& config_entry : touch_buttons) {
- if (index >= touch_params.size()) {
+ if (index >= MaxTouchDevices) {
continue;
}
Common::ParamPackage params{config_entry};
@@ -60,7 +59,6 @@ void EmulatedConsole::SetTouchParams() {
touch_button_params.Set("button", params.Serialize());
touch_button_params.Set("x", x);
touch_button_params.Set("y", y);
- touch_button_params.Set("touch_id", static_cast<int>(index));
touch_params[index] = touch_button_params;
index++;
}
@@ -178,12 +176,38 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
}
void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index) {
- if (index >= console.touch_values.size()) {
+ if (index >= MaxTouchDevices) {
return;
}
std::unique_lock lock{mutex};
- console.touch_values[index] = TransformToTouch(callback);
+ const auto touch_input = TransformToTouch(callback);
+ auto touch_index = GetIndexFromFingerId(index);
+ bool is_new_input = false;
+
+ if (!touch_index.has_value() && touch_input.pressed.value) {
+ touch_index = GetNextFreeIndex();
+ is_new_input = true;
+ }
+
+ // No free entries or invalid state. Ignore input
+ if (!touch_index.has_value()) {
+ return;
+ }
+
+ auto& touch_value = console.touch_values[touch_index.value()];
+
+ if (is_new_input) {
+ touch_value.pressed.value = true;
+ touch_value.id = static_cast<u32>(index);
+ }
+
+ touch_value.x = touch_input.x;
+ touch_value.y = touch_input.y;
+
+ if (!touch_input.pressed.value) {
+ touch_value.pressed.value = false;
+ }
if (is_configuring) {
lock.unlock();
@@ -191,11 +215,15 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st
return;
}
- // TODO(german77): Remap touch id in sequential order
- console.touch_state[index] = {
- .position = {console.touch_values[index].x.value, console.touch_values[index].y.value},
- .id = static_cast<u32>(console.touch_values[index].id),
- .pressed = console.touch_values[index].pressed.value,
+ // Touch outside allowed range. Ignore input
+ if (touch_index.value() >= MaxActiveTouchInputs) {
+ return;
+ }
+
+ console.touch_state[touch_index.value()] = {
+ .position = {touch_value.x.value, touch_value.y.value},
+ .id = static_cast<u32>(touch_index.value()),
+ .pressed = touch_input.pressed.value,
};
lock.unlock();
@@ -222,6 +250,28 @@ TouchFingerState EmulatedConsole::GetTouch() const {
return console.touch_state;
}
+std::optional<std::size_t> EmulatedConsole::GetIndexFromFingerId(std::size_t finger_id) const {
+ for (std::size_t index = 0; index < MaxTouchDevices; ++index) {
+ const auto& finger = console.touch_values[index];
+ if (!finger.pressed.value) {
+ continue;
+ }
+ if (finger.id == static_cast<int>(finger_id)) {
+ return index;
+ }
+ }
+ return std::nullopt;
+}
+
+std::optional<std::size_t> EmulatedConsole::GetNextFreeIndex() const {
+ for (std::size_t index = 0; index < MaxTouchDevices; ++index) {
+ if (!console.touch_values[index].pressed.value) {
+ return index;
+ }
+ }
+ return std::nullopt;
+}
+
void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
std::scoped_lock lock{callback_mutex};
for (const auto& poller_pair : callback_list) {
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h
index 1c510cd19..697ecd2d6 100644
--- a/src/core/hid/emulated_console.h
+++ b/src/core/hid/emulated_console.h
@@ -7,6 +7,7 @@
#include <functional>
#include <memory>
#include <mutex>
+#include <optional>
#include <unordered_map>
#include "common/common_funcs.h"
@@ -20,6 +21,8 @@
#include "core/hid/motion_input.h"
namespace Core::HID {
+static constexpr std::size_t MaxTouchDevices = 32;
+static constexpr std::size_t MaxActiveTouchInputs = 16;
struct ConsoleMotionInfo {
Common::Input::MotionStatus raw_status{};
@@ -27,13 +30,13 @@ struct ConsoleMotionInfo {
};
using ConsoleMotionDevices = std::unique_ptr<Common::Input::InputDevice>;
-using TouchDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, 16>;
+using TouchDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, MaxTouchDevices>;
using ConsoleMotionParams = Common::ParamPackage;
-using TouchParams = std::array<Common::ParamPackage, 16>;
+using TouchParams = std::array<Common::ParamPackage, MaxTouchDevices>;
using ConsoleMotionValues = ConsoleMotionInfo;
-using TouchValues = std::array<Common::Input::TouchStatus, 16>;
+using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>;
struct TouchFinger {
u64 last_touch{};
@@ -55,7 +58,7 @@ struct ConsoleMotion {
bool is_at_rest{};
};
-using TouchFingerState = std::array<TouchFinger, 16>;
+using TouchFingerState = std::array<TouchFinger, MaxActiveTouchInputs>;
struct ConsoleStatus {
// Data from input_common
@@ -166,6 +169,10 @@ private:
*/
void SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index);
+ std::optional<std::size_t> GetIndexFromFingerId(std::size_t finger_id) const;
+
+ std::optional<std::size_t> GetNextFreeIndex() const;
+
/**
* Triggers a callback that something has changed on the console status
* @param type Input type of the event to trigger
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
index 5d8b75b50..502692875 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -200,9 +200,6 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
x = std::clamp(x, 0.0f, 1.0f);
y = std::clamp(y, 0.0f, 1.0f);
- // Limit id to maximum number of fingers
- status.id = std::clamp(status.id, 0, 16);
-
if (status.pressed.inverted) {
status.pressed.value = !status.pressed.value;
}
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 79375bd2f..bf28440c6 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -36,8 +36,9 @@ namespace Service::HID {
// Updating period for each HID device.
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
-// Correct pad_update_ns is 4ms this is overclocked to lower input lag
-constexpr auto pad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
+// Correct npad_update_ns is 4ms this is overclocked to lower input lag
+constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
+constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
@@ -75,11 +76,19 @@ IAppletResource::IAppletResource(Core::System& system_,
GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
// Register update callbacks
- pad_update_event = Core::Timing::CreateEvent(
+ npad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback",
[this](std::uintptr_t user_data, s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
+ UpdateNpad(user_data, ns_late);
+ return std::nullopt;
+ });
+ default_update_event = Core::Timing::CreateEvent(
+ "HID::UpdateDefaultCallback",
+ [this](std::uintptr_t user_data, s64 time,
+ std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
+ const auto guard = LockService();
UpdateControllers(user_data, ns_late);
return std::nullopt;
});
@@ -100,7 +109,9 @@ IAppletResource::IAppletResource(Core::System& system_,
return std::nullopt;
});
- system.CoreTiming().ScheduleLoopingEvent(pad_update_ns, pad_update_ns, pad_update_event);
+ system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
+ system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
+ default_update_event);
system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
mouse_keyboard_update_event);
system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
@@ -118,7 +129,8 @@ void IAppletResource::DeactivateController(HidController controller) {
}
IAppletResource::~IAppletResource() {
- system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(default_update_event, 0);
system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
}
@@ -144,10 +156,20 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
continue;
}
+ // Npad has it's own update event
+ if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
+ continue;
+ }
controller->OnUpdate(core_timing);
}
}
+void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+ auto& core_timing = system.CoreTiming();
+
+ controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
+}
+
void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 340d26fdc..b7c2a23ef 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -71,12 +71,14 @@ private:
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
KernelHelpers::ServiceContext& service_context;
- std::shared_ptr<Core::Timing::EventType> pad_update_event;
+ std::shared_ptr<Core::Timing::EventType> npad_update_event;
+ std::shared_ptr<Core::Timing::EventType> default_update_event;
std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event;