summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt92
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/core/frontend/applets/controller.cpp6
-rw-r--r--src/core/hid/emulated_console.cpp324
-rw-r--r--src/core/hid/emulated_console.h192
-rw-r--r--src/core/hid/emulated_controller.cpp1972
-rw-r--r--src/core/hid/emulated_controller.h619
-rw-r--r--src/core/hid/emulated_devices.cpp483
-rw-r--r--src/core/hid/emulated_devices.h212
-rw-r--r--src/core/hid/hid_core.cpp222
-rw-r--r--src/core/hid/hid_core.h89
-rw-r--r--src/core/hid/hid_types.h735
-rw-r--r--src/core/hid/input_converter.cpp436
-rw-r--r--src/core/hid/input_converter.h119
-rw-r--r--src/core/hid/input_interpreter.cpp64
-rw-r--r--src/core/hid/input_interpreter.h111
-rw-r--r--src/core/hid/irs_types.h301
-rw-r--r--src/core/hid/motion_input.cpp357
-rw-r--r--src/core/hid/motion_input.h119
-rw-r--r--src/core/hle/kernel/k_thread.cpp8
-rw-r--r--src/core/hle/service/am/am.cpp4
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp2
-rw-r--r--src/core/hle/service/am/applets/applet_controller.cpp8
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.cpp329
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.h122
-rw-r--r--src/core/hle/service/hid/controllers/capture_button.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/capture_button.h27
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.cpp44
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.h30
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.cpp39
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h53
-rw-r--r--src/core/hle/service/hid/controllers/debug_mouse.cpp63
-rw-r--r--src/core/hle/service/hid/controllers/debug_mouse.h34
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp58
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h36
-rw-r--r--src/core/hle/service/hid/controllers/digitizer.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/digitizer.h27
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp364
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h87
-rw-r--r--src/core/hle/service/hid/controllers/home_button.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/home_button.h27
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp55
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h28
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp63
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h34
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp1346
-rw-r--r--src/core/hle/service/hid/controllers/npad.h197
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp226
-rw-r--r--src/core/hle/service/hid/controllers/palma.h162
-rw-r--r--src/core/hle/service/hid/controllers/seven_six_axis.cpp66
-rw-r--r--src/core/hle/service/hid/controllers/seven_six_axis.h65
-rw-r--r--src/core/hle/service/hid/controllers/shared_memory_holder.cpp54
-rw-r--r--src/core/hle/service/hid/controllers/shared_memory_holder.h44
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.cpp420
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.h111
-rw-r--r--src/core/hle/service/hid/controllers/sleep_button.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/sleep_button.h27
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp132
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h43
-rw-r--r--src/core/hle/service/hid/controllers/types/debug_pad_types.h31
-rw-r--r--src/core/hle/service/hid/controllers/types/gesture_types.h77
-rw-r--r--src/core/hle/service/hid/controllers/types/keyboard_types.h20
-rw-r--r--src/core/hle/service/hid/controllers/types/mouse_types.h8
-rw-r--r--src/core/hle/service/hid/controllers/types/npad_types.h254
-rw-r--r--src/core/hle/service/hid/controllers/types/shared_memory_format.h240
-rw-r--r--src/core/hle/service/hid/controllers/types/touch_types.h90
-rw-r--r--src/core/hle/service/hid/controllers/unique_pad.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/unique_pad.h27
-rw-r--r--src/core/hle/service/hid/errors.h39
-rw-r--r--src/core/hle/service/hid/hid.cpp5
-rw-r--r--src/core/hle/service/hid/hid_debug_server.cpp2
-rw-r--r--src/core/hle/service/hid/hid_firmware_settings.cpp99
-rw-r--r--src/core/hle/service/hid/hid_firmware_settings.h54
-rw-r--r--src/core/hle/service/hid/hid_server.cpp257
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp113
-rw-r--r--src/core/hle/service/hid/hid_system_server.h6
-rw-r--r--src/core/hle/service/hid/hid_util.h146
-rw-r--r--src/core/hle/service/hid/hidbus.cpp8
-rw-r--r--src/core/hle/service/hid/hidbus.h2
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.cpp73
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.h183
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp292
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.h253
-rw-r--r--src/core/hle/service/hid/hidbus/starlink.cpp50
-rw-r--r--src/core/hle/service/hid/hidbus/starlink.h37
-rw-r--r--src/core/hle/service/hid/hidbus/stubbed.cpp50
-rw-r--r--src/core/hle/service/hid/hidbus/stubbed.h37
-rw-r--r--src/core/hle/service/hid/irs.cpp22
-rw-r--r--src/core/hle/service/hid/irs.h6
-rw-r--r--src/core/hle/service/hid/irs_ring_lifo.h47
-rw-r--r--src/core/hle/service/hid/irsensor/clustering_processor.cpp267
-rw-r--r--src/core/hle/service/hid/irsensor/clustering_processor.h115
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.cpp155
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.h77
-rw-r--r--src/core/hle/service/hid/irsensor/ir_led_processor.cpp27
-rw-r--r--src/core/hle/service/hid/irsensor/ir_led_processor.h47
-rw-r--r--src/core/hle/service/hid/irsensor/moment_processor.cpp149
-rw-r--r--src/core/hle/service/hid/irsensor/moment_processor.h91
-rw-r--r--src/core/hle/service/hid/irsensor/pointing_processor.cpp26
-rw-r--r--src/core/hle/service/hid/irsensor/pointing_processor.h61
-rw-r--r--src/core/hle/service/hid/irsensor/processor_base.cpp67
-rw-r--r--src/core/hle/service/hid/irsensor/processor_base.h33
-rw-r--r--src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp29
-rw-r--r--src/core/hle/service/hid/irsensor/tera_plugin_processor.h53
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp358
-rw-r--r--src/core/hle/service/hid/resource_manager.h149
-rw-r--r--src/core/hle/service/hid/ring_lifo.h53
-rw-r--r--src/core/hle/service/nfc/common/device.cpp6
-rw-r--r--src/core/hle/service/nfc/common/device_manager.cpp4
-rw-r--r--src/core/hle/service/nfc/common/device_manager.h2
-rw-r--r--src/core/hle/service/nfc/nfc_interface.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp_interface.cpp2
-rw-r--r--src/core/memory/cheat_engine.cpp4
113 files changed, 301 insertions, 15084 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index dfba79267..adcc23c18 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -183,22 +183,6 @@ add_library(core STATIC
frontend/framebuffer_layout.cpp
frontend/framebuffer_layout.h
frontend/graphics_context.h
- hid/emulated_console.cpp
- hid/emulated_console.h
- hid/emulated_controller.cpp
- hid/emulated_controller.h
- hid/emulated_devices.cpp
- hid/emulated_devices.h
- hid/hid_core.cpp
- hid/hid_core.h
- hid/hid_types.h
- hid/input_converter.cpp
- hid/input_converter.h
- hid/input_interpreter.cpp
- hid/input_interpreter.h
- hid/irs_types.h
- hid/motion_input.cpp
- hid/motion_input.h
hle/api_version.h
hle/ipc.h
hle/kernel/board/nintendo/nx/k_memory_layout.cpp
@@ -531,90 +515,16 @@ add_library(core STATIC
hle/service/hid/hid.h
hle/service/hid/hid_debug_server.cpp
hle/service/hid/hid_debug_server.h
- hle/service/hid/hid_firmware_settings.cpp
- hle/service/hid/hid_firmware_settings.h
hle/service/hid/hid_server.cpp
hle/service/hid/hid_server.h
hle/service/hid/hid_system_server.cpp
hle/service/hid/hid_system_server.h
- hle/service/hid/hid_util.h
hle/service/hid/hidbus.cpp
hle/service/hid/hidbus.h
hle/service/hid/irs.cpp
hle/service/hid/irs.h
- hle/service/hid/irs_ring_lifo.h
- hle/service/hid/resource_manager.cpp
- hle/service/hid/resource_manager.h
- hle/service/hid/ring_lifo.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
- hle/service/hid/errors.h
- hle/service/hid/controllers/types/debug_pad_types.h
- hle/service/hid/controllers/types/keyboard_types.h
- hle/service/hid/controllers/types/mouse_types.h
- hle/service/hid/controllers/types/npad_types.h
- hle/service/hid/controllers/types/shared_memory_format.h
- hle/service/hid/controllers/types/touch_types.h
- hle/service/hid/controllers/applet_resource.cpp
- hle/service/hid/controllers/applet_resource.h
- hle/service/hid/controllers/capture_button.cpp
- hle/service/hid/controllers/capture_button.h
- hle/service/hid/controllers/console_six_axis.cpp
- hle/service/hid/controllers/console_six_axis.h
- hle/service/hid/controllers/controller_base.cpp
- hle/service/hid/controllers/controller_base.h
- hle/service/hid/controllers/debug_mouse.cpp
- hle/service/hid/controllers/debug_mouse.h
- hle/service/hid/controllers/debug_pad.cpp
- hle/service/hid/controllers/debug_pad.h
- hle/service/hid/controllers/digitizer.cpp
- hle/service/hid/controllers/digitizer.h
- hle/service/hid/controllers/gesture.cpp
- hle/service/hid/controllers/gesture.h
- hle/service/hid/controllers/home_button.cpp
- hle/service/hid/controllers/home_button.h
- hle/service/hid/controllers/keyboard.cpp
- hle/service/hid/controllers/keyboard.h
- hle/service/hid/controllers/mouse.cpp
- hle/service/hid/controllers/mouse.h
- hle/service/hid/controllers/npad.cpp
- hle/service/hid/controllers/npad.h
- hle/service/hid/controllers/palma.cpp
- hle/service/hid/controllers/palma.h
- hle/service/hid/controllers/seven_six_axis.cpp
- hle/service/hid/controllers/seven_six_axis.h
- hle/service/hid/controllers/shared_memory_holder.cpp
- hle/service/hid/controllers/shared_memory_holder.h
- hle/service/hid/controllers/six_axis.cpp
- hle/service/hid/controllers/six_axis.h
- hle/service/hid/controllers/sleep_button.cpp
- hle/service/hid/controllers/sleep_button.h
- hle/service/hid/controllers/touchscreen.cpp
- hle/service/hid/controllers/touchscreen.h
- hle/service/hid/controllers/unique_pad.cpp
- hle/service/hid/controllers/unique_pad.h
- hle/service/hid/hidbus/hidbus_base.cpp
- hle/service/hid/hidbus/hidbus_base.h
- hle/service/hid/hidbus/ringcon.cpp
- hle/service/hid/hidbus/ringcon.h
- hle/service/hid/hidbus/starlink.cpp
- hle/service/hid/hidbus/starlink.h
- hle/service/hid/hidbus/stubbed.cpp
- hle/service/hid/hidbus/stubbed.h
- hle/service/hid/irsensor/clustering_processor.cpp
- hle/service/hid/irsensor/clustering_processor.h
- hle/service/hid/irsensor/image_transfer_processor.cpp
- hle/service/hid/irsensor/image_transfer_processor.h
- hle/service/hid/irsensor/ir_led_processor.cpp
- hle/service/hid/irsensor/ir_led_processor.h
- hle/service/hid/irsensor/moment_processor.cpp
- hle/service/hid/irsensor/moment_processor.h
- hle/service/hid/irsensor/pointing_processor.cpp
- hle/service/hid/irsensor/pointing_processor.h
- hle/service/hid/irsensor/processor_base.cpp
- hle/service/hid/irsensor/processor_base.h
- hle/service/hid/irsensor/tera_plugin_processor.cpp
- hle/service/hid/irsensor/tera_plugin_processor.h
hle/service/lbl/lbl.cpp
hle/service/lbl/lbl.h
hle/service/ldn/lan_discovery.cpp
@@ -955,7 +865,7 @@ endif()
create_target_directory_groups(core)
-target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core nx_tzdb)
+target_link_libraries(core PUBLIC common PRIVATE audio_core hid_core network video_core nx_tzdb)
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls RenderDoc::API)
if (MINGW)
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 66f444d39..c063f7719 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -28,7 +28,6 @@
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs_concat.h"
#include "core/file_sys/vfs_real.h"
-#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
@@ -52,6 +51,7 @@
#include "core/telemetry_session.h"
#include "core/tools/freezer.h"
#include "core/tools/renderdoc.h"
+#include "hid_core/hid_core.h"
#include "network/network.h"
#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h"
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 27755cb58..34fe23b6a 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -6,9 +6,9 @@
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/frontend/applets/controller.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hid/hid_types.h"
+#include "hid_core/frontend/emulated_controller.h"
+#include "hid_core/hid_core.h"
+#include "hid_core/hid_types.h"
namespace Core::Frontend {
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
deleted file mode 100644
index b4afd930e..000000000
--- a/src/core/hid/emulated_console.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/settings.h"
-#include "core/hid/emulated_console.h"
-#include "core/hid/input_converter.h"
-
-namespace Core::HID {
-EmulatedConsole::EmulatedConsole() = default;
-
-EmulatedConsole::~EmulatedConsole() = default;
-
-void EmulatedConsole::ReloadFromSettings() {
- // Using first motion device from player 1. No need to assign any unique config at the moment
- const auto& player = Settings::values.players.GetValue()[0];
- motion_params[0] = Common::ParamPackage(player.motions[0]);
-
- ReloadInput();
-}
-
-void EmulatedConsole::SetTouchParams() {
- std::size_t index = 0;
-
- // We can't use mouse as touch if native mouse is enabled
- if (!Settings::values.mouse_enabled) {
- touch_params[index++] =
- Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
- }
-
- touch_params[index++] =
- Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"};
- touch_params[index++] =
- 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++] = std::move(touchscreen_param);
- }
-
- if (Settings::values.touch_from_button_maps.empty()) {
- LOG_WARNING(Input, "touch_from_button_maps is unset by frontend config");
- return;
- }
-
- const auto button_index =
- static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
- const auto& touch_buttons = Settings::values.touch_from_button_maps[button_index].buttons;
-
- // Map the rest of the fingers from touch from button configuration
- for (const auto& config_entry : touch_buttons) {
- if (index >= MaxTouchDevices) {
- continue;
- }
- Common::ParamPackage params{config_entry};
- Common::ParamPackage touch_button_params;
- const int x = params.Get("x", 0);
- const int y = params.Get("y", 0);
- params.Erase("x");
- params.Erase("y");
- touch_button_params.Set("engine", "touch_from_button");
- touch_button_params.Set("button", params.Serialize());
- touch_button_params.Set("x", x);
- touch_button_params.Set("y", y);
- touch_params[index] = std::move(touch_button_params);
- index++;
- }
-}
-
-void EmulatedConsole::ReloadInput() {
- // If you load any device here add the equivalent to the UnloadInput() function
- SetTouchParams();
-
- motion_params[1] = Common::ParamPackage{"engine:virtual_gamepad,port:8,motion:0"};
-
- for (std::size_t index = 0; index < motion_devices.size(); ++index) {
- motion_devices[index] = Common::Input::CreateInputDevice(motion_params[index]);
- if (!motion_devices[index]) {
- continue;
- }
- motion_devices[index]->SetCallback({
- .on_change =
- [this](const Common::Input::CallbackStatus& callback) { SetMotion(callback); },
- });
- }
-
- // Restore motion state
- auto& emulated_motion = console.motion_values.emulated;
- auto& motion = console.motion_state;
- emulated_motion.ResetRotations();
- emulated_motion.ResetQuaternion();
- motion.accel = emulated_motion.GetAcceleration();
- motion.gyro = emulated_motion.GetGyroscope();
- motion.rotation = emulated_motion.GetRotations();
- motion.orientation = emulated_motion.GetOrientation();
- motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity);
-
- // Unique index for identifying touch device source
- std::size_t index = 0;
- for (auto& touch_device : touch_devices) {
- touch_device = Common::Input::CreateInputDevice(touch_params[index]);
- if (!touch_device) {
- continue;
- }
- touch_device->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetTouch(callback, index);
- },
- });
- index++;
- }
-}
-
-void EmulatedConsole::UnloadInput() {
- for (auto& motion : motion_devices) {
- motion.reset();
- }
- for (auto& touch : touch_devices) {
- touch.reset();
- }
-}
-
-void EmulatedConsole::EnableConfiguration() {
- is_configuring = true;
- SaveCurrentConfig();
-}
-
-void EmulatedConsole::DisableConfiguration() {
- is_configuring = false;
-}
-
-bool EmulatedConsole::IsConfiguring() const {
- return is_configuring;
-}
-
-void EmulatedConsole::SaveCurrentConfig() {
- if (!is_configuring) {
- return;
- }
-}
-
-void EmulatedConsole::RestoreConfig() {
- if (!is_configuring) {
- return;
- }
- ReloadFromSettings();
-}
-
-Common::ParamPackage EmulatedConsole::GetMotionParam() const {
- return motion_params[0];
-}
-
-void EmulatedConsole::SetMotionParam(Common::ParamPackage param) {
- motion_params[0] = std::move(param);
- ReloadInput();
-}
-
-void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
- std::unique_lock lock{mutex};
- auto& raw_status = console.motion_values.raw_status;
- auto& emulated = console.motion_values.emulated;
-
- raw_status = TransformToMotion(callback);
- emulated.SetAcceleration(Common::Vec3f{
- raw_status.accel.x.value,
- raw_status.accel.y.value,
- raw_status.accel.z.value,
- });
- emulated.SetGyroscope(Common::Vec3f{
- raw_status.gyro.x.value,
- raw_status.gyro.y.value,
- raw_status.gyro.z.value,
- });
- emulated.UpdateRotation(raw_status.delta_timestamp);
- emulated.UpdateOrientation(raw_status.delta_timestamp);
-
- if (is_configuring) {
- lock.unlock();
- TriggerOnChange(ConsoleTriggerType::Motion);
- return;
- }
-
- auto& motion = console.motion_state;
- motion.accel = emulated.GetAcceleration();
- motion.gyro = emulated.GetGyroscope();
- motion.rotation = emulated.GetRotations();
- motion.orientation = emulated.GetOrientation();
- motion.quaternion = emulated.GetQuaternion();
- motion.gyro_bias = emulated.GetGyroBias();
- motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
- // Find what is this value
- motion.verticalization_error = 0.0f;
-
- lock.unlock();
- TriggerOnChange(ConsoleTriggerType::Motion);
-}
-
-void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index) {
- if (index >= MaxTouchDevices) {
- return;
- }
- std::unique_lock lock{mutex};
-
- 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<int>(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();
- TriggerOnChange(ConsoleTriggerType::Touch);
- return;
- }
-
- // 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();
- TriggerOnChange(ConsoleTriggerType::Touch);
-}
-
-ConsoleMotionValues EmulatedConsole::GetMotionValues() const {
- std::scoped_lock lock{mutex};
- return console.motion_values;
-}
-
-TouchValues EmulatedConsole::GetTouchValues() const {
- std::scoped_lock lock{mutex};
- return console.touch_values;
-}
-
-ConsoleMotion EmulatedConsole::GetMotion() const {
- std::scoped_lock lock{mutex};
- return console.motion_state;
-}
-
-TouchFingerState EmulatedConsole::GetTouch() const {
- std::scoped_lock lock{mutex};
- 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) {
- const ConsoleUpdateCallback& poller = poller_pair.second;
- if (poller.on_change) {
- poller.on_change(type);
- }
- }
-}
-
-int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
- std::scoped_lock lock{callback_mutex};
- callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
- return last_callback_key++;
-}
-
-void EmulatedConsole::DeleteCallback(int key) {
- std::scoped_lock lock{callback_mutex};
- const auto& iterator = callback_list.find(key);
- if (iterator == callback_list.end()) {
- LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
- return;
- }
- callback_list.erase(iterator);
-}
-} // namespace Core::HID
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h
deleted file mode 100644
index fae15a556..000000000
--- a/src/core/hid/emulated_console.h
+++ /dev/null
@@ -1,192 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <unordered_map>
-
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "common/input.h"
-#include "common/param_package.h"
-#include "common/point.h"
-#include "common/quaternion.h"
-#include "common/vector_math.h"
-#include "core/hid/hid_types.h"
-#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{};
- MotionInput emulated{};
-};
-
-using ConsoleMotionDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, 2>;
-using TouchDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, MaxTouchDevices>;
-
-using ConsoleMotionParams = std::array<Common::ParamPackage, 2>;
-using TouchParams = std::array<Common::ParamPackage, MaxTouchDevices>;
-
-using ConsoleMotionValues = ConsoleMotionInfo;
-using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>;
-
-// Contains all motion related data that is used on the services
-struct ConsoleMotion {
- Common::Vec3f accel{};
- Common::Vec3f gyro{};
- Common::Vec3f rotation{};
- std::array<Common::Vec3f, 3> orientation{};
- Common::Quaternion<f32> quaternion{};
- Common::Vec3f gyro_bias{};
- f32 verticalization_error{};
- bool is_at_rest{};
-};
-
-using TouchFingerState = std::array<TouchFinger, MaxActiveTouchInputs>;
-
-struct ConsoleStatus {
- // Data from input_common
- ConsoleMotionValues motion_values{};
- TouchValues touch_values{};
-
- // Data for HID services
- ConsoleMotion motion_state{};
- TouchFingerState touch_state{};
-};
-
-enum class ConsoleTriggerType {
- Motion,
- Touch,
- All,
-};
-
-struct ConsoleUpdateCallback {
- std::function<void(ConsoleTriggerType)> on_change;
-};
-
-class EmulatedConsole {
-public:
- /**
- * Contains all input data within the emulated switch console tablet such as touch and motion
- */
- explicit EmulatedConsole();
- ~EmulatedConsole();
-
- YUZU_NON_COPYABLE(EmulatedConsole);
- YUZU_NON_MOVEABLE(EmulatedConsole);
-
- /// Removes all callbacks created from input devices
- void UnloadInput();
-
- /**
- * Sets the emulated console into configuring mode
- * This prevents the modification of the HID state of the emulated console by input commands
- */
- void EnableConfiguration();
-
- /// Returns the emulated console into normal mode, allowing the modification of the HID state
- void DisableConfiguration();
-
- /// Returns true if the emulated console is in configuring mode
- bool IsConfiguring() const;
-
- /// Reload all input devices
- void ReloadInput();
-
- /// Overrides current mapped devices with the stored configuration and reloads all input devices
- void ReloadFromSettings();
-
- /// Saves the current mapped configuration
- void SaveCurrentConfig();
-
- /// Reverts any mapped changes made that weren't saved
- void RestoreConfig();
-
- // Returns the current mapped motion device
- Common::ParamPackage GetMotionParam() const;
-
- /**
- * Updates the current mapped motion device
- * @param param ParamPackage with controller data to be mapped
- */
- void SetMotionParam(Common::ParamPackage param);
-
- /// Returns the latest status of motion input from the console with parameters
- ConsoleMotionValues GetMotionValues() const;
-
- /// Returns the latest status of touch input from the console with parameters
- TouchValues GetTouchValues() const;
-
- /// Returns the latest status of motion input from the console
- ConsoleMotion GetMotion() const;
-
- /// Returns the latest status of touch input from the console
- TouchFingerState GetTouch() const;
-
- /**
- * Adds a callback to the list of events
- * @param update_callback A ConsoleUpdateCallback that will be triggered
- * @return an unique key corresponding to the callback index in the list
- */
- int SetCallback(ConsoleUpdateCallback update_callback);
-
- /**
- * Removes a callback from the list stopping any future events to this object
- * @param key Key corresponding to the callback index in the list
- */
- void DeleteCallback(int key);
-
-private:
- /// Creates and stores the touch params
- void SetTouchParams();
-
- /**
- * Updates the motion status of the console
- * @param callback A CallbackStatus containing gyro and accelerometer data
- */
- void SetMotion(const Common::Input::CallbackStatus& callback);
-
- /**
- * Updates the touch status of the console
- * @param callback A CallbackStatus containing the touch position
- * @param index Finger ID to be updated
- */
- 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
- */
- void TriggerOnChange(ConsoleTriggerType type);
-
- bool is_configuring{false};
- f32 motion_sensitivity{0.01f};
-
- ConsoleMotionParams motion_params;
- TouchParams touch_params;
-
- ConsoleMotionDevices motion_devices;
- TouchDevices touch_devices;
-
- mutable std::mutex mutex;
- mutable std::mutex callback_mutex;
- std::unordered_map<int, ConsoleUpdateCallback> callback_list;
- int last_callback_key = 0;
-
- // Stores the current status of all console input
- ConsoleStatus console;
-};
-
-} // namespace Core::HID
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
deleted file mode 100644
index a6e681e15..000000000
--- a/src/core/hid/emulated_controller.cpp
+++ /dev/null
@@ -1,1972 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <algorithm>
-#include <common/scope_exit.h>
-
-#include "common/polyfill_ranges.h"
-#include "common/thread.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/input_converter.h"
-#include "core/hle/service/hid/hid_util.h"
-
-namespace Core::HID {
-constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
-constexpr s32 HID_TRIGGER_MAX = 0x7fff;
-constexpr u32 TURBO_BUTTON_DELAY = 4;
-// Use a common UUID for TAS and Virtual Gamepad
-constexpr Common::UUID TAS_UUID =
- Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
-constexpr Common::UUID VIRTUAL_UUID =
- Common::UUID{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
-
-EmulatedController::EmulatedController(NpadIdType npad_id_type_) : npad_id_type(npad_id_type_) {}
-
-EmulatedController::~EmulatedController() = default;
-
-NpadStyleIndex EmulatedController::MapSettingsTypeToNPad(Settings::ControllerType type) {
- switch (type) {
- case Settings::ControllerType::ProController:
- return NpadStyleIndex::ProController;
- case Settings::ControllerType::DualJoyconDetached:
- return NpadStyleIndex::JoyconDual;
- case Settings::ControllerType::LeftJoycon:
- return NpadStyleIndex::JoyconLeft;
- case Settings::ControllerType::RightJoycon:
- return NpadStyleIndex::JoyconRight;
- case Settings::ControllerType::Handheld:
- return NpadStyleIndex::Handheld;
- case Settings::ControllerType::GameCube:
- return NpadStyleIndex::GameCube;
- case Settings::ControllerType::Pokeball:
- return NpadStyleIndex::Pokeball;
- case Settings::ControllerType::NES:
- return NpadStyleIndex::NES;
- case Settings::ControllerType::SNES:
- return NpadStyleIndex::SNES;
- case Settings::ControllerType::N64:
- return NpadStyleIndex::N64;
- case Settings::ControllerType::SegaGenesis:
- return NpadStyleIndex::SegaGenesis;
- default:
- return NpadStyleIndex::ProController;
- }
-}
-
-Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleIndex type) {
- switch (type) {
- case NpadStyleIndex::ProController:
- return Settings::ControllerType::ProController;
- case NpadStyleIndex::JoyconDual:
- return Settings::ControllerType::DualJoyconDetached;
- case NpadStyleIndex::JoyconLeft:
- return Settings::ControllerType::LeftJoycon;
- case NpadStyleIndex::JoyconRight:
- return Settings::ControllerType::RightJoycon;
- case NpadStyleIndex::Handheld:
- return Settings::ControllerType::Handheld;
- case NpadStyleIndex::GameCube:
- return Settings::ControllerType::GameCube;
- case NpadStyleIndex::Pokeball:
- return Settings::ControllerType::Pokeball;
- case NpadStyleIndex::NES:
- return Settings::ControllerType::NES;
- case NpadStyleIndex::SNES:
- return Settings::ControllerType::SNES;
- case NpadStyleIndex::N64:
- return Settings::ControllerType::N64;
- case NpadStyleIndex::SegaGenesis:
- return Settings::ControllerType::SegaGenesis;
- default:
- return Settings::ControllerType::ProController;
- }
-}
-
-void EmulatedController::ReloadFromSettings() {
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- const auto& player = Settings::values.players.GetValue()[player_index];
-
- for (std::size_t index = 0; index < player.buttons.size(); ++index) {
- button_params[index] = Common::ParamPackage(player.buttons[index]);
- }
- for (std::size_t index = 0; index < player.analogs.size(); ++index) {
- stick_params[index] = Common::ParamPackage(player.analogs[index]);
- }
- for (std::size_t index = 0; index < player.motions.size(); ++index) {
- motion_params[index] = Common::ParamPackage(player.motions[index]);
- }
-
- controller.color_values = {};
- ReloadColorsFromSettings();
-
- ring_params[0] = Common::ParamPackage(Settings::values.ringcon_analogs);
-
- // Other or debug controller should always be a pro controller
- if (npad_id_type != NpadIdType::Other) {
- SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type));
- original_npad_type = npad_type;
- } else {
- SetNpadStyleIndex(NpadStyleIndex::ProController);
- original_npad_type = npad_type;
- }
-
- Disconnect();
- if (player.connected) {
- Connect();
- }
-
- ReloadInput();
-}
-
-void EmulatedController::ReloadColorsFromSettings() {
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- const auto& player = Settings::values.players.GetValue()[player_index];
-
- // Avoid updating colors if overridden by physical controller
- if (controller.color_values[LeftIndex].body != 0 &&
- controller.color_values[RightIndex].body != 0) {
- return;
- }
-
- controller.colors_state.fullkey = {
- .body = GetNpadColor(player.body_color_left),
- .button = GetNpadColor(player.button_color_left),
- };
- controller.colors_state.left = {
- .body = GetNpadColor(player.body_color_left),
- .button = GetNpadColor(player.button_color_left),
- };
- controller.colors_state.right = {
- .body = GetNpadColor(player.body_color_right),
- .button = GetNpadColor(player.button_color_right),
- };
-}
-
-void EmulatedController::LoadDevices() {
- // TODO(german77): Use more buttons to detect the correct device
- const auto left_joycon = button_params[Settings::NativeButton::DRight];
- const auto right_joycon = button_params[Settings::NativeButton::A];
-
- // Triggers for GC controllers
- trigger_params[LeftIndex] = button_params[Settings::NativeButton::ZL];
- trigger_params[RightIndex] = button_params[Settings::NativeButton::ZR];
-
- color_params[LeftIndex] = left_joycon;
- color_params[RightIndex] = right_joycon;
- color_params[LeftIndex].Set("color", true);
- color_params[RightIndex].Set("color", true);
-
- battery_params[LeftIndex] = left_joycon;
- battery_params[RightIndex] = right_joycon;
- battery_params[LeftIndex].Set("battery", true);
- battery_params[RightIndex].Set("battery", true);
-
- camera_params[0] = right_joycon;
- camera_params[0].Set("camera", true);
- nfc_params[1] = right_joycon;
- nfc_params[1].Set("nfc", true);
-
- // Only map virtual devices to the first controller
- if (npad_id_type == NpadIdType::Player1 || npad_id_type == NpadIdType::Handheld) {
- camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"};
- ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"};
- nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"};
- }
-
- output_params[LeftIndex] = left_joycon;
- output_params[RightIndex] = right_joycon;
- output_params[2] = camera_params[1];
- output_params[3] = nfc_params[0];
- output_params[LeftIndex].Set("output", true);
- output_params[RightIndex].Set("output", true);
- output_params[2].Set("output", true);
- output_params[3].Set("output", true);
-
- LoadTASParams();
- LoadVirtualGamepadParams();
-
- std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice);
- std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice);
- std::ranges::transform(motion_params, motion_devices.begin(), Common::Input::CreateInputDevice);
- std::ranges::transform(trigger_params, trigger_devices.begin(),
- Common::Input::CreateInputDevice);
- std::ranges::transform(battery_params, battery_devices.begin(),
- Common::Input::CreateInputDevice);
- std::ranges::transform(color_params, color_devices.begin(), Common::Input::CreateInputDevice);
- std::ranges::transform(camera_params, camera_devices.begin(), Common::Input::CreateInputDevice);
- std::ranges::transform(ring_params, ring_analog_devices.begin(),
- Common::Input::CreateInputDevice);
- std::ranges::transform(nfc_params, nfc_devices.begin(), Common::Input::CreateInputDevice);
- std::ranges::transform(output_params, output_devices.begin(),
- Common::Input::CreateOutputDevice);
-
- // Initialize TAS devices
- std::ranges::transform(tas_button_params, tas_button_devices.begin(),
- Common::Input::CreateInputDevice);
- std::ranges::transform(tas_stick_params, tas_stick_devices.begin(),
- Common::Input::CreateInputDevice);
-
- // Initialize virtual gamepad devices
- std::ranges::transform(virtual_button_params, virtual_button_devices.begin(),
- Common::Input::CreateInputDevice);
- std::ranges::transform(virtual_stick_params, virtual_stick_devices.begin(),
- Common::Input::CreateInputDevice);
- std::ranges::transform(virtual_motion_params, virtual_motion_devices.begin(),
- Common::Input::CreateInputDevice);
-}
-
-void EmulatedController::LoadTASParams() {
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- Common::ParamPackage common_params{};
- common_params.Set("engine", "tas");
- common_params.Set("port", static_cast<int>(player_index));
- for (auto& param : tas_button_params) {
- param = common_params;
- }
- for (auto& param : tas_stick_params) {
- param = common_params;
- }
-
- // TODO(german77): Replace this with an input profile or something better
- tas_button_params[Settings::NativeButton::A].Set("button", 0);
- tas_button_params[Settings::NativeButton::B].Set("button", 1);
- tas_button_params[Settings::NativeButton::X].Set("button", 2);
- tas_button_params[Settings::NativeButton::Y].Set("button", 3);
- tas_button_params[Settings::NativeButton::LStick].Set("button", 4);
- tas_button_params[Settings::NativeButton::RStick].Set("button", 5);
- tas_button_params[Settings::NativeButton::L].Set("button", 6);
- tas_button_params[Settings::NativeButton::R].Set("button", 7);
- tas_button_params[Settings::NativeButton::ZL].Set("button", 8);
- tas_button_params[Settings::NativeButton::ZR].Set("button", 9);
- tas_button_params[Settings::NativeButton::Plus].Set("button", 10);
- tas_button_params[Settings::NativeButton::Minus].Set("button", 11);
- tas_button_params[Settings::NativeButton::DLeft].Set("button", 12);
- tas_button_params[Settings::NativeButton::DUp].Set("button", 13);
- tas_button_params[Settings::NativeButton::DRight].Set("button", 14);
- tas_button_params[Settings::NativeButton::DDown].Set("button", 15);
- tas_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
- tas_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
- tas_button_params[Settings::NativeButton::Home].Set("button", 18);
- tas_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
- tas_button_params[Settings::NativeButton::SLRight].Set("button", 20);
- tas_button_params[Settings::NativeButton::SRRight].Set("button", 21);
-
- tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
- tas_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
- tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_x", 2);
- tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
-
- // set to optimal stick to avoid sanitizing the stick and tweaking the coordinates
- // making sure they play back in the game as originally written down in the script file
- tas_stick_params[Settings::NativeAnalog::LStick].Set("deadzone", 0.0f);
- tas_stick_params[Settings::NativeAnalog::LStick].Set("range", 1.0f);
- tas_stick_params[Settings::NativeAnalog::RStick].Set("deadzone", 0.0f);
- tas_stick_params[Settings::NativeAnalog::RStick].Set("range", 1.0f);
-}
-
-void EmulatedController::LoadVirtualGamepadParams() {
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- Common::ParamPackage common_params{};
- common_params.Set("engine", "virtual_gamepad");
- common_params.Set("port", static_cast<int>(player_index));
- for (auto& param : virtual_button_params) {
- param = common_params;
- }
- for (auto& param : virtual_stick_params) {
- param = common_params;
- }
- for (auto& param : virtual_stick_params) {
- param = common_params;
- }
- for (auto& param : virtual_motion_params) {
- param = common_params;
- }
-
- // TODO(german77): Replace this with an input profile or something better
- virtual_button_params[Settings::NativeButton::A].Set("button", 0);
- virtual_button_params[Settings::NativeButton::B].Set("button", 1);
- virtual_button_params[Settings::NativeButton::X].Set("button", 2);
- virtual_button_params[Settings::NativeButton::Y].Set("button", 3);
- virtual_button_params[Settings::NativeButton::LStick].Set("button", 4);
- virtual_button_params[Settings::NativeButton::RStick].Set("button", 5);
- virtual_button_params[Settings::NativeButton::L].Set("button", 6);
- virtual_button_params[Settings::NativeButton::R].Set("button", 7);
- virtual_button_params[Settings::NativeButton::ZL].Set("button", 8);
- virtual_button_params[Settings::NativeButton::ZR].Set("button", 9);
- virtual_button_params[Settings::NativeButton::Plus].Set("button", 10);
- virtual_button_params[Settings::NativeButton::Minus].Set("button", 11);
- virtual_button_params[Settings::NativeButton::DLeft].Set("button", 12);
- virtual_button_params[Settings::NativeButton::DUp].Set("button", 13);
- virtual_button_params[Settings::NativeButton::DRight].Set("button", 14);
- virtual_button_params[Settings::NativeButton::DDown].Set("button", 15);
- virtual_button_params[Settings::NativeButton::SLLeft].Set("button", 16);
- virtual_button_params[Settings::NativeButton::SRLeft].Set("button", 17);
- virtual_button_params[Settings::NativeButton::Home].Set("button", 18);
- virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19);
- virtual_button_params[Settings::NativeButton::SLRight].Set("button", 20);
- virtual_button_params[Settings::NativeButton::SRRight].Set("button", 21);
-
- virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0);
- virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1);
- virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_x", 2);
- virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3);
- virtual_stick_params[Settings::NativeAnalog::LStick].Set("deadzone", 0.0f);
- virtual_stick_params[Settings::NativeAnalog::LStick].Set("range", 1.0f);
- virtual_stick_params[Settings::NativeAnalog::RStick].Set("deadzone", 0.0f);
- virtual_stick_params[Settings::NativeAnalog::RStick].Set("range", 1.0f);
-
- virtual_motion_params[Settings::NativeMotion::MotionLeft].Set("motion", 0);
- virtual_motion_params[Settings::NativeMotion::MotionRight].Set("motion", 0);
-}
-
-void EmulatedController::ReloadInput() {
- // If you load any device here add the equivalent to the UnloadInput() function
- LoadDevices();
- for (std::size_t index = 0; index < button_devices.size(); ++index) {
- if (!button_devices[index]) {
- continue;
- }
- const auto uuid = Common::UUID{button_params[index].Get("guid", "")};
- button_devices[index]->SetCallback({
- .on_change =
- [this, index, uuid](const Common::Input::CallbackStatus& callback) {
- SetButton(callback, index, uuid);
- },
- });
- button_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < stick_devices.size(); ++index) {
- if (!stick_devices[index]) {
- continue;
- }
- const auto uuid = Common::UUID{stick_params[index].Get("guid", "")};
- stick_devices[index]->SetCallback({
- .on_change =
- [this, index, uuid](const Common::Input::CallbackStatus& callback) {
- SetStick(callback, index, uuid);
- },
- });
- stick_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < trigger_devices.size(); ++index) {
- if (!trigger_devices[index]) {
- continue;
- }
- const auto uuid = Common::UUID{trigger_params[index].Get("guid", "")};
- trigger_devices[index]->SetCallback({
- .on_change =
- [this, index, uuid](const Common::Input::CallbackStatus& callback) {
- SetTrigger(callback, index, uuid);
- },
- });
- trigger_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < battery_devices.size(); ++index) {
- if (!battery_devices[index]) {
- continue;
- }
- battery_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetBattery(callback, index);
- },
- });
- battery_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < color_devices.size(); ++index) {
- if (!color_devices[index]) {
- continue;
- }
- color_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetColors(callback, index);
- },
- });
- color_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < motion_devices.size(); ++index) {
- if (!motion_devices[index]) {
- continue;
- }
- motion_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetMotion(callback, index);
- },
- });
-
- // Restore motion state
- auto& emulated_motion = controller.motion_values[index].emulated;
- auto& motion = controller.motion_state[index];
- emulated_motion.ResetRotations();
- emulated_motion.ResetQuaternion();
- motion.accel = emulated_motion.GetAcceleration();
- motion.gyro = emulated_motion.GetGyroscope();
- motion.rotation = emulated_motion.GetRotations();
- motion.euler = emulated_motion.GetEulerAngles();
- motion.orientation = emulated_motion.GetOrientation();
- motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity);
- }
-
- for (std::size_t index = 0; index < camera_devices.size(); ++index) {
- if (!camera_devices[index]) {
- continue;
- }
- camera_devices[index]->SetCallback({
- .on_change =
- [this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); },
- });
- camera_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < ring_analog_devices.size(); ++index) {
- if (!ring_analog_devices[index]) {
- continue;
- }
- ring_analog_devices[index]->SetCallback({
- .on_change =
- [this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
- });
- ring_analog_devices[index]->ForceUpdate();
- }
-
- for (std::size_t index = 0; index < nfc_devices.size(); ++index) {
- if (!nfc_devices[index]) {
- continue;
- }
- nfc_devices[index]->SetCallback({
- .on_change =
- [this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
- });
- nfc_devices[index]->ForceUpdate();
- }
-
- // Register TAS devices. No need to force update
- for (std::size_t index = 0; index < tas_button_devices.size(); ++index) {
- if (!tas_button_devices[index]) {
- continue;
- }
- tas_button_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetButton(callback, index, TAS_UUID);
- },
- });
- }
-
- for (std::size_t index = 0; index < tas_stick_devices.size(); ++index) {
- if (!tas_stick_devices[index]) {
- continue;
- }
- tas_stick_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetStick(callback, index, TAS_UUID);
- },
- });
- }
-
- // Register virtual devices. No need to force update
- for (std::size_t index = 0; index < virtual_button_devices.size(); ++index) {
- if (!virtual_button_devices[index]) {
- continue;
- }
- virtual_button_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetButton(callback, index, VIRTUAL_UUID);
- },
- });
- }
-
- for (std::size_t index = 0; index < virtual_stick_devices.size(); ++index) {
- if (!virtual_stick_devices[index]) {
- continue;
- }
- virtual_stick_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetStick(callback, index, VIRTUAL_UUID);
- },
- });
- }
-
- for (std::size_t index = 0; index < virtual_motion_devices.size(); ++index) {
- if (!virtual_motion_devices[index]) {
- continue;
- }
- virtual_motion_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetMotion(callback, index);
- },
- });
- }
- turbo_button_state = 0;
- is_initalized = true;
-}
-
-void EmulatedController::UnloadInput() {
- is_initalized = false;
- for (auto& button : button_devices) {
- button.reset();
- }
- for (auto& stick : stick_devices) {
- stick.reset();
- }
- for (auto& motion : motion_devices) {
- motion.reset();
- }
- for (auto& trigger : trigger_devices) {
- trigger.reset();
- }
- for (auto& battery : battery_devices) {
- battery.reset();
- }
- for (auto& color : color_devices) {
- color.reset();
- }
- for (auto& output : output_devices) {
- output.reset();
- }
- for (auto& button : tas_button_devices) {
- button.reset();
- }
- for (auto& stick : tas_stick_devices) {
- stick.reset();
- }
- for (auto& button : virtual_button_devices) {
- button.reset();
- }
- for (auto& stick : virtual_stick_devices) {
- stick.reset();
- }
- for (auto& motion : virtual_motion_devices) {
- motion.reset();
- }
- for (auto& camera : camera_devices) {
- camera.reset();
- }
- for (auto& ring : ring_analog_devices) {
- ring.reset();
- }
- for (auto& nfc : nfc_devices) {
- nfc.reset();
- }
-}
-
-void EmulatedController::EnableConfiguration() {
- std::scoped_lock lock{connect_mutex, npad_mutex};
- is_configuring = true;
- tmp_is_connected = is_connected;
- tmp_npad_type = npad_type;
-}
-
-void EmulatedController::DisableConfiguration() {
- is_configuring = false;
-
- // Get Joycon colors before turning on the controller
- for (const auto& color_device : color_devices) {
- color_device->ForceUpdate();
- }
-
- // Apply temporary npad type to the real controller
- if (tmp_npad_type != npad_type) {
- if (is_connected) {
- Disconnect();
- }
- SetNpadStyleIndex(tmp_npad_type);
- original_npad_type = tmp_npad_type;
- }
-
- // Apply temporary connected status to the real controller
- if (tmp_is_connected != is_connected) {
- if (tmp_is_connected) {
- Connect();
- return;
- }
- Disconnect();
- }
-}
-
-void EmulatedController::EnableSystemButtons() {
- std::scoped_lock lock{mutex};
- system_buttons_enabled = true;
-}
-
-void EmulatedController::DisableSystemButtons() {
- std::scoped_lock lock{mutex};
- system_buttons_enabled = false;
- controller.home_button_state.raw = 0;
- controller.capture_button_state.raw = 0;
-}
-
-void EmulatedController::ResetSystemButtons() {
- std::scoped_lock lock{mutex};
- controller.home_button_state.home.Assign(false);
- controller.capture_button_state.capture.Assign(false);
-}
-
-bool EmulatedController::IsConfiguring() const {
- return is_configuring;
-}
-
-void EmulatedController::SaveCurrentConfig() {
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- auto& player = Settings::values.players.GetValue()[player_index];
- player.connected = is_connected;
- player.controller_type = MapNPadToSettingsType(npad_type);
- for (std::size_t index = 0; index < player.buttons.size(); ++index) {
- player.buttons[index] = button_params[index].Serialize();
- }
- for (std::size_t index = 0; index < player.analogs.size(); ++index) {
- player.analogs[index] = stick_params[index].Serialize();
- }
- for (std::size_t index = 0; index < player.motions.size(); ++index) {
- player.motions[index] = motion_params[index].Serialize();
- }
- if (npad_id_type == NpadIdType::Player1) {
- Settings::values.ringcon_analogs = ring_params[0].Serialize();
- }
-}
-
-void EmulatedController::RestoreConfig() {
- if (!is_configuring) {
- return;
- }
- ReloadFromSettings();
-}
-
-std::vector<Common::ParamPackage> EmulatedController::GetMappedDevices() const {
- std::vector<Common::ParamPackage> devices;
- for (const auto& param : button_params) {
- if (!param.Has("engine")) {
- continue;
- }
- const auto devices_it = std::find_if(
- devices.begin(), devices.end(), [&param](const Common::ParamPackage& param_) {
- return param.Get("engine", "") == param_.Get("engine", "") &&
- param.Get("guid", "") == param_.Get("guid", "") &&
- param.Get("port", 0) == param_.Get("port", 0) &&
- param.Get("pad", 0) == param_.Get("pad", 0);
- });
- if (devices_it != devices.end()) {
- continue;
- }
-
- auto& device = devices.emplace_back();
- device.Set("engine", param.Get("engine", ""));
- device.Set("guid", param.Get("guid", ""));
- device.Set("port", param.Get("port", 0));
- device.Set("pad", param.Get("pad", 0));
- }
-
- for (const auto& param : stick_params) {
- if (!param.Has("engine")) {
- continue;
- }
- if (param.Get("engine", "") == "analog_from_button") {
- continue;
- }
- const auto devices_it = std::find_if(
- devices.begin(), devices.end(), [&param](const Common::ParamPackage& param_) {
- return param.Get("engine", "") == param_.Get("engine", "") &&
- param.Get("guid", "") == param_.Get("guid", "") &&
- param.Get("port", 0) == param_.Get("port", 0) &&
- param.Get("pad", 0) == param_.Get("pad", 0);
- });
- if (devices_it != devices.end()) {
- continue;
- }
-
- auto& device = devices.emplace_back();
- device.Set("engine", param.Get("engine", ""));
- device.Set("guid", param.Get("guid", ""));
- device.Set("port", param.Get("port", 0));
- device.Set("pad", param.Get("pad", 0));
- }
- return devices;
-}
-
-Common::ParamPackage EmulatedController::GetButtonParam(std::size_t index) const {
- if (index >= button_params.size()) {
- return {};
- }
- return button_params[index];
-}
-
-Common::ParamPackage EmulatedController::GetStickParam(std::size_t index) const {
- if (index >= stick_params.size()) {
- return {};
- }
- return stick_params[index];
-}
-
-Common::ParamPackage EmulatedController::GetMotionParam(std::size_t index) const {
- if (index >= motion_params.size()) {
- return {};
- }
- return motion_params[index];
-}
-
-void EmulatedController::SetButtonParam(std::size_t index, Common::ParamPackage param) {
- if (index >= button_params.size()) {
- return;
- }
- button_params[index] = std::move(param);
- ReloadInput();
-}
-
-void EmulatedController::SetStickParam(std::size_t index, Common::ParamPackage param) {
- if (index >= stick_params.size()) {
- return;
- }
- stick_params[index] = std::move(param);
- ReloadInput();
-}
-
-void EmulatedController::SetMotionParam(std::size_t index, Common::ParamPackage param) {
- if (index >= motion_params.size()) {
- return;
- }
- motion_params[index] = std::move(param);
- ReloadInput();
-}
-
-void EmulatedController::StartMotionCalibration() {
- for (ControllerMotionInfo& motion : controller.motion_values) {
- motion.emulated.Calibrate();
- }
-}
-
-void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
- Common::UUID uuid) {
- if (index >= controller.button_values.size()) {
- return;
- }
- std::unique_lock lock{mutex};
- bool value_changed = false;
- const auto new_status = TransformToButton(callback);
- auto& current_status = controller.button_values[index];
-
- // Only read button values that have the same uuid or are pressed once
- if (current_status.uuid != uuid) {
- if (!new_status.value) {
- return;
- }
- }
-
- current_status.toggle = new_status.toggle;
- current_status.turbo = new_status.turbo;
- current_status.uuid = uuid;
-
- // Update button status with current
- if (!current_status.toggle) {
- current_status.locked = false;
- if (current_status.value != new_status.value) {
- current_status.value = new_status.value;
- value_changed = true;
- }
- } else {
- // Toggle button and lock status
- if (new_status.value && !current_status.locked) {
- current_status.locked = true;
- current_status.value = !current_status.value;
- value_changed = true;
- }
-
- // Unlock button ready for next press
- if (!new_status.value && current_status.locked) {
- current_status.locked = false;
- }
- }
-
- if (!value_changed) {
- return;
- }
-
- if (is_configuring) {
- controller.npad_button_state.raw = NpadButton::None;
- controller.debug_pad_button_state.raw = 0;
- controller.home_button_state.raw = 0;
- controller.capture_button_state.raw = 0;
- lock.unlock();
- TriggerOnChange(ControllerTriggerType::Button, false);
- return;
- }
-
- // GC controllers have triggers not buttons
- if (npad_type == NpadStyleIndex::GameCube) {
- if (index == Settings::NativeButton::ZR) {
- return;
- }
- if (index == Settings::NativeButton::ZL) {
- return;
- }
- }
-
- switch (index) {
- case Settings::NativeButton::A:
- controller.npad_button_state.a.Assign(current_status.value);
- controller.debug_pad_button_state.a.Assign(current_status.value);
- break;
- case Settings::NativeButton::B:
- controller.npad_button_state.b.Assign(current_status.value);
- controller.debug_pad_button_state.b.Assign(current_status.value);
- break;
- case Settings::NativeButton::X:
- controller.npad_button_state.x.Assign(current_status.value);
- controller.debug_pad_button_state.x.Assign(current_status.value);
- break;
- case Settings::NativeButton::Y:
- controller.npad_button_state.y.Assign(current_status.value);
- controller.debug_pad_button_state.y.Assign(current_status.value);
- break;
- case Settings::NativeButton::LStick:
- controller.npad_button_state.stick_l.Assign(current_status.value);
- break;
- case Settings::NativeButton::RStick:
- controller.npad_button_state.stick_r.Assign(current_status.value);
- break;
- case Settings::NativeButton::L:
- controller.npad_button_state.l.Assign(current_status.value);
- controller.debug_pad_button_state.l.Assign(current_status.value);
- break;
- case Settings::NativeButton::R:
- controller.npad_button_state.r.Assign(current_status.value);
- controller.debug_pad_button_state.r.Assign(current_status.value);
- break;
- case Settings::NativeButton::ZL:
- controller.npad_button_state.zl.Assign(current_status.value);
- controller.debug_pad_button_state.zl.Assign(current_status.value);
- break;
- case Settings::NativeButton::ZR:
- controller.npad_button_state.zr.Assign(current_status.value);
- controller.debug_pad_button_state.zr.Assign(current_status.value);
- break;
- case Settings::NativeButton::Plus:
- controller.npad_button_state.plus.Assign(current_status.value);
- controller.debug_pad_button_state.plus.Assign(current_status.value);
- break;
- case Settings::NativeButton::Minus:
- controller.npad_button_state.minus.Assign(current_status.value);
- controller.debug_pad_button_state.minus.Assign(current_status.value);
- break;
- case Settings::NativeButton::DLeft:
- controller.npad_button_state.left.Assign(current_status.value);
- controller.debug_pad_button_state.d_left.Assign(current_status.value);
- break;
- case Settings::NativeButton::DUp:
- controller.npad_button_state.up.Assign(current_status.value);
- controller.debug_pad_button_state.d_up.Assign(current_status.value);
- break;
- case Settings::NativeButton::DRight:
- controller.npad_button_state.right.Assign(current_status.value);
- controller.debug_pad_button_state.d_right.Assign(current_status.value);
- break;
- case Settings::NativeButton::DDown:
- controller.npad_button_state.down.Assign(current_status.value);
- controller.debug_pad_button_state.d_down.Assign(current_status.value);
- break;
- case Settings::NativeButton::SLLeft:
- controller.npad_button_state.left_sl.Assign(current_status.value);
- break;
- case Settings::NativeButton::SLRight:
- controller.npad_button_state.right_sl.Assign(current_status.value);
- break;
- case Settings::NativeButton::SRLeft:
- controller.npad_button_state.left_sr.Assign(current_status.value);
- break;
- case Settings::NativeButton::SRRight:
- controller.npad_button_state.right_sr.Assign(current_status.value);
- break;
- case Settings::NativeButton::Home:
- if (!system_buttons_enabled) {
- break;
- }
- controller.home_button_state.home.Assign(current_status.value);
- break;
- case Settings::NativeButton::Screenshot:
- if (!system_buttons_enabled) {
- break;
- }
- controller.capture_button_state.capture.Assign(current_status.value);
- break;
- }
-
- lock.unlock();
-
- if (!is_connected) {
- if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) {
- Connect();
- }
- if (npad_id_type == NpadIdType::Handheld && npad_type == NpadStyleIndex::Handheld) {
- Connect();
- }
- }
- TriggerOnChange(ControllerTriggerType::Button, true);
-}
-
-void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, std::size_t index,
- Common::UUID uuid) {
- if (index >= controller.stick_values.size()) {
- return;
- }
- auto trigger_guard =
- SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Stick, !is_configuring); });
- std::scoped_lock lock{mutex};
- const auto stick_value = TransformToStick(callback);
-
- // Only read stick values that have the same uuid or are over the threshold to avoid flapping
- if (controller.stick_values[index].uuid != uuid) {
- const bool is_tas = uuid == TAS_UUID;
- if (is_tas && stick_value.x.value == 0 && stick_value.y.value == 0) {
- trigger_guard.Cancel();
- return;
- }
- if (!is_tas && !stick_value.down && !stick_value.up && !stick_value.left &&
- !stick_value.right) {
- trigger_guard.Cancel();
- return;
- }
- }
-
- controller.stick_values[index] = stick_value;
- controller.stick_values[index].uuid = uuid;
-
- if (is_configuring) {
- controller.analog_stick_state.left = {};
- controller.analog_stick_state.right = {};
- return;
- }
-
- const AnalogStickState stick{
- .x = static_cast<s32>(controller.stick_values[index].x.value * HID_JOYSTICK_MAX),
- .y = static_cast<s32>(controller.stick_values[index].y.value * HID_JOYSTICK_MAX),
- };
-
- switch (index) {
- case Settings::NativeAnalog::LStick:
- controller.analog_stick_state.left = stick;
- controller.npad_button_state.stick_l_left.Assign(controller.stick_values[index].left);
- controller.npad_button_state.stick_l_up.Assign(controller.stick_values[index].up);
- controller.npad_button_state.stick_l_right.Assign(controller.stick_values[index].right);
- controller.npad_button_state.stick_l_down.Assign(controller.stick_values[index].down);
- break;
- case Settings::NativeAnalog::RStick:
- controller.analog_stick_state.right = stick;
- controller.npad_button_state.stick_r_left.Assign(controller.stick_values[index].left);
- controller.npad_button_state.stick_r_up.Assign(controller.stick_values[index].up);
- controller.npad_button_state.stick_r_right.Assign(controller.stick_values[index].right);
- controller.npad_button_state.stick_r_down.Assign(controller.stick_values[index].down);
- break;
- }
-}
-
-void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callback,
- std::size_t index, Common::UUID uuid) {
- if (index >= controller.trigger_values.size()) {
- return;
- }
- auto trigger_guard =
- SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Trigger, !is_configuring); });
- std::scoped_lock lock{mutex};
- const auto trigger_value = TransformToTrigger(callback);
-
- // Only read trigger values that have the same uuid or are pressed once
- if (controller.trigger_values[index].uuid != uuid) {
- if (!trigger_value.pressed.value) {
- return;
- }
- }
-
- controller.trigger_values[index] = trigger_value;
- controller.trigger_values[index].uuid = uuid;
-
- if (is_configuring) {
- controller.gc_trigger_state.left = 0;
- controller.gc_trigger_state.right = 0;
- return;
- }
-
- // Only GC controllers have analog triggers
- if (npad_type != NpadStyleIndex::GameCube) {
- trigger_guard.Cancel();
- return;
- }
-
- const auto& trigger = controller.trigger_values[index];
-
- switch (index) {
- case Settings::NativeTrigger::LTrigger:
- controller.gc_trigger_state.left = static_cast<s32>(trigger.analog.value * HID_TRIGGER_MAX);
- controller.npad_button_state.zl.Assign(trigger.pressed.value);
- break;
- case Settings::NativeTrigger::RTrigger:
- controller.gc_trigger_state.right =
- static_cast<s32>(trigger.analog.value * HID_TRIGGER_MAX);
- controller.npad_button_state.zr.Assign(trigger.pressed.value);
- break;
- }
-}
-
-void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= controller.motion_values.size()) {
- return;
- }
- SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Motion, !is_configuring); });
- std::scoped_lock lock{mutex};
- auto& raw_status = controller.motion_values[index].raw_status;
- auto& emulated = controller.motion_values[index].emulated;
-
- raw_status = TransformToMotion(callback);
- emulated.SetAcceleration(Common::Vec3f{
- raw_status.accel.x.value,
- raw_status.accel.y.value,
- raw_status.accel.z.value,
- });
- emulated.SetGyroscope(Common::Vec3f{
- raw_status.gyro.x.value,
- raw_status.gyro.y.value,
- raw_status.gyro.z.value,
- });
- emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold);
- emulated.UpdateRotation(raw_status.delta_timestamp);
- emulated.UpdateOrientation(raw_status.delta_timestamp);
-
- auto& motion = controller.motion_state[index];
- motion.accel = emulated.GetAcceleration();
- motion.gyro = emulated.GetGyroscope();
- motion.rotation = emulated.GetRotations();
- motion.euler = emulated.GetEulerAngles();
- motion.orientation = emulated.GetOrientation();
- motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
-}
-
-void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= controller.color_values.size()) {
- return;
- }
- auto trigger_guard =
- SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Color, !is_configuring); });
- std::scoped_lock lock{mutex};
- controller.color_values[index] = TransformToColor(callback);
-
- if (is_configuring) {
- return;
- }
-
- if (controller.color_values[index].body == 0) {
- trigger_guard.Cancel();
- return;
- }
-
- controller.colors_state.fullkey = {
- .body = GetNpadColor(controller.color_values[index].body),
- .button = GetNpadColor(controller.color_values[index].buttons),
- };
- if (npad_type == NpadStyleIndex::ProController) {
- controller.colors_state.left = {
- .body = GetNpadColor(controller.color_values[index].left_grip),
- .button = GetNpadColor(controller.color_values[index].buttons),
- };
- controller.colors_state.right = {
- .body = GetNpadColor(controller.color_values[index].right_grip),
- .button = GetNpadColor(controller.color_values[index].buttons),
- };
- } else {
- switch (index) {
- case LeftIndex:
- controller.colors_state.left = {
- .body = GetNpadColor(controller.color_values[index].body),
- .button = GetNpadColor(controller.color_values[index].buttons),
- };
- break;
- case RightIndex:
- controller.colors_state.right = {
- .body = GetNpadColor(controller.color_values[index].body),
- .button = GetNpadColor(controller.color_values[index].buttons),
- };
- break;
- }
- }
-}
-
-void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= controller.battery_values.size()) {
- return;
- }
- SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Battery, !is_configuring); });
- std::scoped_lock lock{mutex};
- controller.battery_values[index] = TransformToBattery(callback);
-
- if (is_configuring) {
- return;
- }
-
- bool is_charging = false;
- bool is_powered = false;
- NpadBatteryLevel battery_level = NpadBatteryLevel::Empty;
- switch (controller.battery_values[index]) {
- case Common::Input::BatteryLevel::Charging:
- is_charging = true;
- is_powered = true;
- battery_level = NpadBatteryLevel::Full;
- break;
- case Common::Input::BatteryLevel::Medium:
- battery_level = NpadBatteryLevel::High;
- break;
- case Common::Input::BatteryLevel::Low:
- battery_level = NpadBatteryLevel::Low;
- break;
- case Common::Input::BatteryLevel::Critical:
- battery_level = NpadBatteryLevel::Critical;
- break;
- case Common::Input::BatteryLevel::Empty:
- battery_level = NpadBatteryLevel::Empty;
- break;
- case Common::Input::BatteryLevel::None:
- case Common::Input::BatteryLevel::Full:
- default:
- is_powered = true;
- battery_level = NpadBatteryLevel::Full;
- break;
- }
-
- switch (index) {
- case LeftIndex:
- controller.battery_state.left = {
- .is_powered = is_powered,
- .is_charging = is_charging,
- .battery_level = battery_level,
- };
- break;
- case RightIndex:
- controller.battery_state.right = {
- .is_powered = is_powered,
- .is_charging = is_charging,
- .battery_level = battery_level,
- };
- break;
- case DualIndex:
- controller.battery_state.dual = {
- .is_powered = is_powered,
- .is_charging = is_charging,
- .battery_level = battery_level,
- };
- break;
- }
-}
-
-void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) {
- SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::IrSensor, !is_configuring); });
- std::scoped_lock lock{mutex};
- controller.camera_values = TransformToCamera(callback);
-
- if (is_configuring) {
- return;
- }
-
- controller.camera_state.sample++;
- controller.camera_state.format =
- static_cast<Core::IrSensor::ImageTransferProcessorFormat>(controller.camera_values.format);
- controller.camera_state.data = controller.camera_values.data;
-}
-
-void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
- SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::RingController, !is_configuring); });
- std::scoped_lock lock{mutex};
- const auto force_value = TransformToStick(callback);
-
- controller.ring_analog_value = force_value.x;
-
- if (is_configuring) {
- return;
- }
-
- controller.ring_analog_state.force = force_value.x.value;
-}
-
-void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
- SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Nfc, !is_configuring); });
- std::scoped_lock lock{mutex};
- controller.nfc_values = TransformToNfc(callback);
-
- if (is_configuring) {
- return;
- }
-
- controller.nfc_state = controller.nfc_values;
-}
-
-bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
- if (!is_initalized) {
- return false;
- }
- if (device_index >= output_devices.size()) {
- return false;
- }
- if (!output_devices[device_index]) {
- return false;
- }
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- const auto& player = Settings::values.players.GetValue()[player_index];
- const f32 strength = static_cast<f32>(player.vibration_strength) / 100.0f;
-
- if (!player.vibration_enabled) {
- return false;
- }
-
- // Exponential amplification is too strong at low amplitudes. Switch to a linear
- // amplification if strength is set below 0.7f
- const Common::Input::VibrationAmplificationType type =
- strength > 0.7f ? Common::Input::VibrationAmplificationType::Exponential
- : Common::Input::VibrationAmplificationType::Linear;
-
- const Common::Input::VibrationStatus status = {
- .low_amplitude = std::min(vibration.low_amplitude * strength, 1.0f),
- .low_frequency = vibration.low_frequency,
- .high_amplitude = std::min(vibration.high_amplitude * strength, 1.0f),
- .high_frequency = vibration.high_frequency,
- .type = type,
- };
- return output_devices[device_index]->SetVibration(status) ==
- Common::Input::DriverResult::Success;
-}
-
-bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
- const auto player_index = Service::HID::NpadIdTypeToIndex(npad_id_type);
- const auto& player = Settings::values.players.GetValue()[player_index];
-
- if (!is_initalized) {
- return false;
- }
-
- if (!player.vibration_enabled) {
- return false;
- }
-
- if (device_index >= output_devices.size()) {
- return false;
- }
-
- if (!output_devices[device_index]) {
- return false;
- }
-
- return output_devices[device_index]->IsVibrationEnabled();
-}
-
-Common::Input::DriverResult EmulatedController::SetPollingMode(
- EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
- LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
-
- if (!is_initalized) {
- return Common::Input::DriverResult::InvalidHandle;
- }
-
- auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
- auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_output_device = output_devices[3];
-
- if (device_index == EmulatedDeviceIndex::LeftIndex) {
- controller.left_polling_mode = polling_mode;
- return left_output_device->SetPollingMode(polling_mode);
- }
-
- if (device_index == EmulatedDeviceIndex::RightIndex) {
- controller.right_polling_mode = polling_mode;
- const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
- const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode);
-
- // Restore previous state
- if (mapped_nfc_result != Common::Input::DriverResult::Success) {
- right_output_device->SetPollingMode(Common::Input::PollingMode::Active);
- }
-
- if (virtual_nfc_result == Common::Input::DriverResult::Success) {
- return virtual_nfc_result;
- }
- return mapped_nfc_result;
- }
-
- controller.left_polling_mode = polling_mode;
- controller.right_polling_mode = polling_mode;
- left_output_device->SetPollingMode(polling_mode);
- right_output_device->SetPollingMode(polling_mode);
- nfc_output_device->SetPollingMode(polling_mode);
- return Common::Input::DriverResult::Success;
-}
-
-Common::Input::PollingMode EmulatedController::GetPollingMode(
- EmulatedDeviceIndex device_index) const {
- if (device_index == EmulatedDeviceIndex::LeftIndex) {
- return controller.left_polling_mode;
- }
- return controller.right_polling_mode;
-}
-
-bool EmulatedController::SetCameraFormat(
- Core::IrSensor::ImageTransferProcessorFormat camera_format) {
- LOG_INFO(Service_HID, "Set camera format {}", camera_format);
-
- if (!is_initalized) {
- return false;
- }
-
- auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& camera_output_device = output_devices[2];
-
- if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
- camera_format)) == Common::Input::DriverResult::Success) {
- return true;
- }
-
- // Fallback to Qt camera if native device doesn't have support
- return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
- camera_format)) == Common::Input::DriverResult::Success;
-}
-
-Common::ParamPackage EmulatedController::GetRingParam() const {
- return ring_params[0];
-}
-
-void EmulatedController::SetRingParam(Common::ParamPackage param) {
- ring_params[0] = std::move(param);
- ReloadInput();
-}
-
-bool EmulatedController::HasNfc() const {
-
- if (!is_initalized) {
- return false;
- }
-
- const auto& nfc_output_device = output_devices[3];
-
- switch (npad_type) {
- case NpadStyleIndex::JoyconRight:
- case NpadStyleIndex::JoyconDual:
- case NpadStyleIndex::ProController:
- case NpadStyleIndex::Handheld:
- break;
- default:
- return false;
- }
-
- const bool has_virtual_nfc =
- npad_id_type == NpadIdType::Player1 || npad_id_type == NpadIdType::Handheld;
- const bool is_virtual_nfc_supported =
- nfc_output_device->SupportsNfc() != Common::Input::NfcState::NotSupported;
-
- return is_connected && (has_virtual_nfc && is_virtual_nfc_supported);
-}
-
-bool EmulatedController::AddNfcHandle() {
- nfc_handles++;
- return SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::NFC) ==
- Common::Input::DriverResult::Success;
-}
-
-bool EmulatedController::RemoveNfcHandle() {
- nfc_handles--;
- if (nfc_handles <= 0) {
- return SetPollingMode(EmulatedDeviceIndex::RightIndex,
- Common::Input::PollingMode::Active) ==
- Common::Input::DriverResult::Success;
- }
- return true;
-}
-
-bool EmulatedController::StartNfcPolling() {
- if (!is_initalized) {
- return false;
- }
-
- auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_virtual_output_device = output_devices[3];
-
- const auto device_result = nfc_output_device->StartNfcPolling();
- const auto virtual_device_result = nfc_virtual_output_device->StartNfcPolling();
-
- return device_result == Common::Input::NfcState::Success ||
- virtual_device_result == Common::Input::NfcState::Success;
-}
-
-bool EmulatedController::StopNfcPolling() {
- if (!is_initalized) {
- return false;
- }
-
- auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_virtual_output_device = output_devices[3];
-
- const auto device_result = nfc_output_device->StopNfcPolling();
- const auto virtual_device_result = nfc_virtual_output_device->StopNfcPolling();
-
- return device_result == Common::Input::NfcState::Success ||
- virtual_device_result == Common::Input::NfcState::Success;
-}
-
-bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
- if (!is_initalized) {
- return false;
- }
-
- auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_virtual_output_device = output_devices[3];
-
- if (nfc_output_device->ReadAmiiboData(data) == Common::Input::NfcState::Success) {
- return true;
- }
-
- return nfc_virtual_output_device->ReadAmiiboData(data) == Common::Input::NfcState::Success;
-}
-
-bool EmulatedController::ReadMifareData(const Common::Input::MifareRequest& request,
- Common::Input::MifareRequest& out_data) {
- if (!is_initalized) {
- return false;
- }
-
- auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_virtual_output_device = output_devices[3];
-
- if (nfc_output_device->ReadMifareData(request, out_data) == Common::Input::NfcState::Success) {
- return true;
- }
-
- return nfc_virtual_output_device->ReadMifareData(request, out_data) ==
- Common::Input::NfcState::Success;
-}
-
-bool EmulatedController::WriteMifareData(const Common::Input::MifareRequest& request) {
- if (!is_initalized) {
- return false;
- }
-
- auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_virtual_output_device = output_devices[3];
-
- if (nfc_output_device->WriteMifareData(request) == Common::Input::NfcState::Success) {
- return true;
- }
-
- return nfc_virtual_output_device->WriteMifareData(request) == Common::Input::NfcState::Success;
-}
-
-bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
- if (!is_initalized) {
- return false;
- }
-
- auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- auto& nfc_virtual_output_device = output_devices[3];
-
- if (nfc_output_device->SupportsNfc() != Common::Input::NfcState::NotSupported) {
- return nfc_output_device->WriteNfcData(data) == Common::Input::NfcState::Success;
- }
-
- return nfc_virtual_output_device->WriteNfcData(data) == Common::Input::NfcState::Success;
-}
-
-void EmulatedController::SetLedPattern() {
- if (!is_initalized) {
- return;
- }
-
- for (auto& device : output_devices) {
- if (!device) {
- continue;
- }
-
- const LedPattern pattern = GetLedPattern();
- const Common::Input::LedStatus status = {
- .led_1 = pattern.position1 != 0,
- .led_2 = pattern.position2 != 0,
- .led_3 = pattern.position3 != 0,
- .led_4 = pattern.position4 != 0,
- };
- device->SetLED(status);
- }
-}
-
-void EmulatedController::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode) {
- for (auto& motion : controller.motion_values) {
- switch (mode) {
- case GyroscopeZeroDriftMode::Loose:
- motion_sensitivity = motion.emulated.IsAtRestLoose;
- motion.emulated.SetGyroThreshold(motion.emulated.ThresholdLoose);
- break;
- case GyroscopeZeroDriftMode::Tight:
- motion_sensitivity = motion.emulated.IsAtRestThight;
- motion.emulated.SetGyroThreshold(motion.emulated.ThresholdThight);
- break;
- case GyroscopeZeroDriftMode::Standard:
- default:
- motion_sensitivity = motion.emulated.IsAtRestStandard;
- motion.emulated.SetGyroThreshold(motion.emulated.ThresholdStandard);
- break;
- }
- }
-}
-
-void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) {
- supported_style_tag = supported_styles;
- if (!is_connected) {
- return;
- }
-
- // Attempt to reconnect with the original type
- if (npad_type != original_npad_type) {
- Disconnect();
- const auto current_npad_type = npad_type;
- SetNpadStyleIndex(original_npad_type);
- if (IsControllerSupported()) {
- Connect();
- return;
- }
- SetNpadStyleIndex(current_npad_type);
- Connect();
- }
-
- if (IsControllerSupported()) {
- return;
- }
-
- Disconnect();
-
- // Fallback Fullkey controllers to Pro controllers
- if (IsControllerFullkey() && supported_style_tag.fullkey) {
- LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type);
- SetNpadStyleIndex(NpadStyleIndex::ProController);
- Connect();
- return;
- }
-
- // Fallback Dual joycon controllers to Pro controllers
- if (npad_type == NpadStyleIndex::JoyconDual && supported_style_tag.fullkey) {
- LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type);
- SetNpadStyleIndex(NpadStyleIndex::ProController);
- Connect();
- return;
- }
-
- // Fallback Pro controllers to Dual joycon
- if (npad_type == NpadStyleIndex::ProController && supported_style_tag.joycon_dual) {
- LOG_WARNING(Service_HID, "Reconnecting controller type {} as Dual Joycons", npad_type);
- SetNpadStyleIndex(NpadStyleIndex::JoyconDual);
- Connect();
- return;
- }
-
- LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller",
- npad_type);
-}
-
-bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const {
- std::scoped_lock lock{mutex};
- const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
- switch (type) {
- case NpadStyleIndex::ProController:
- case NpadStyleIndex::GameCube:
- case NpadStyleIndex::NES:
- case NpadStyleIndex::SNES:
- case NpadStyleIndex::N64:
- case NpadStyleIndex::SegaGenesis:
- return true;
- default:
- return false;
- }
-}
-
-bool EmulatedController::IsControllerSupported(bool use_temporary_value) const {
- std::scoped_lock lock{mutex};
- const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
- switch (type) {
- case NpadStyleIndex::ProController:
- return supported_style_tag.fullkey.As<bool>();
- case NpadStyleIndex::Handheld:
- return supported_style_tag.handheld.As<bool>();
- case NpadStyleIndex::JoyconDual:
- return supported_style_tag.joycon_dual.As<bool>();
- case NpadStyleIndex::JoyconLeft:
- return supported_style_tag.joycon_left.As<bool>();
- case NpadStyleIndex::JoyconRight:
- return supported_style_tag.joycon_right.As<bool>();
- case NpadStyleIndex::GameCube:
- return supported_style_tag.gamecube.As<bool>();
- case NpadStyleIndex::Pokeball:
- return supported_style_tag.palma.As<bool>();
- case NpadStyleIndex::NES:
- return supported_style_tag.lark.As<bool>();
- case NpadStyleIndex::SNES:
- return supported_style_tag.lucia.As<bool>();
- case NpadStyleIndex::N64:
- return supported_style_tag.lagoon.As<bool>();
- case NpadStyleIndex::SegaGenesis:
- return supported_style_tag.lager.As<bool>();
- default:
- return false;
- }
-}
-
-void EmulatedController::Connect(bool use_temporary_value) {
- if (!IsControllerSupported(use_temporary_value)) {
- const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
- LOG_ERROR(Service_HID, "Controller type {} is not supported", type);
- return;
- }
-
- auto trigger_guard =
- SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Connected, !is_configuring); });
- std::scoped_lock lock{connect_mutex, mutex};
- if (is_configuring) {
- tmp_is_connected = true;
- return;
- }
-
- if (is_connected) {
- trigger_guard.Cancel();
- return;
- }
- is_connected = true;
-}
-
-void EmulatedController::Disconnect() {
- auto trigger_guard =
- SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Disconnected, !is_configuring); });
- std::scoped_lock lock{connect_mutex, mutex};
- if (is_configuring) {
- tmp_is_connected = false;
- return;
- }
-
- if (!is_connected) {
- trigger_guard.Cancel();
- return;
- }
- is_connected = false;
-}
-
-bool EmulatedController::IsConnected(bool get_temporary_value) const {
- std::scoped_lock lock{connect_mutex};
- if (get_temporary_value && is_configuring) {
- return tmp_is_connected;
- }
- return is_connected;
-}
-
-NpadIdType EmulatedController::GetNpadIdType() const {
- std::scoped_lock lock{mutex};
- return npad_id_type;
-}
-
-NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const {
- std::scoped_lock lock{npad_mutex};
- if (get_temporary_value && is_configuring) {
- return tmp_npad_type;
- }
- return npad_type;
-}
-
-void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
- auto trigger_guard =
- SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Type, !is_configuring); });
- std::scoped_lock lock{mutex, npad_mutex};
-
- if (is_configuring) {
- if (tmp_npad_type == npad_type_) {
- trigger_guard.Cancel();
- return;
- }
- tmp_npad_type = npad_type_;
- return;
- }
-
- if (npad_type == npad_type_) {
- trigger_guard.Cancel();
- return;
- }
- if (is_connected) {
- LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
- Service::HID::NpadIdTypeToIndex(npad_id_type));
- }
- npad_type = npad_type_;
-}
-
-LedPattern EmulatedController::GetLedPattern() const {
- switch (npad_id_type) {
- case NpadIdType::Player1:
- return LedPattern{1, 0, 0, 0};
- case NpadIdType::Player2:
- return LedPattern{1, 1, 0, 0};
- case NpadIdType::Player3:
- return LedPattern{1, 1, 1, 0};
- case NpadIdType::Player4:
- return LedPattern{1, 1, 1, 1};
- case NpadIdType::Player5:
- return LedPattern{1, 0, 0, 1};
- case NpadIdType::Player6:
- return LedPattern{1, 0, 1, 0};
- case NpadIdType::Player7:
- return LedPattern{1, 0, 1, 1};
- case NpadIdType::Player8:
- return LedPattern{0, 1, 1, 0};
- default:
- return LedPattern{0, 0, 0, 0};
- }
-}
-
-ButtonValues EmulatedController::GetButtonsValues() const {
- std::scoped_lock lock{mutex};
- return controller.button_values;
-}
-
-SticksValues EmulatedController::GetSticksValues() const {
- std::scoped_lock lock{mutex};
- return controller.stick_values;
-}
-
-TriggerValues EmulatedController::GetTriggersValues() const {
- std::scoped_lock lock{mutex};
- return controller.trigger_values;
-}
-
-ControllerMotionValues EmulatedController::GetMotionValues() const {
- std::scoped_lock lock{mutex};
- return controller.motion_values;
-}
-
-ColorValues EmulatedController::GetColorsValues() const {
- std::scoped_lock lock{mutex};
- return controller.color_values;
-}
-
-BatteryValues EmulatedController::GetBatteryValues() const {
- std::scoped_lock lock{mutex};
- return controller.battery_values;
-}
-
-CameraValues EmulatedController::GetCameraValues() const {
- std::scoped_lock lock{mutex};
- return controller.camera_values;
-}
-
-RingAnalogValue EmulatedController::GetRingSensorValues() const {
- return controller.ring_analog_value;
-}
-
-HomeButtonState EmulatedController::GetHomeButtons() const {
- std::scoped_lock lock{mutex};
- if (is_configuring) {
- return {};
- }
- return controller.home_button_state;
-}
-
-CaptureButtonState EmulatedController::GetCaptureButtons() const {
- std::scoped_lock lock{mutex};
- if (is_configuring) {
- return {};
- }
- return controller.capture_button_state;
-}
-
-NpadButtonState EmulatedController::GetNpadButtons() const {
- std::scoped_lock lock{mutex};
- if (is_configuring) {
- return {};
- }
- return {controller.npad_button_state.raw & GetTurboButtonMask()};
-}
-
-DebugPadButton EmulatedController::GetDebugPadButtons() const {
- std::scoped_lock lock{mutex};
- if (is_configuring) {
- return {};
- }
- return controller.debug_pad_button_state;
-}
-
-AnalogSticks EmulatedController::GetSticks() const {
- std::scoped_lock lock{mutex};
-
- if (is_configuring) {
- return {};
- }
-
- return controller.analog_stick_state;
-}
-
-NpadGcTriggerState EmulatedController::GetTriggers() const {
- std::scoped_lock lock{mutex};
- if (is_configuring) {
- return {};
- }
- return controller.gc_trigger_state;
-}
-
-MotionState EmulatedController::GetMotions() const {
- std::unique_lock lock{mutex};
- return controller.motion_state;
-}
-
-ControllerColors EmulatedController::GetColors() const {
- std::scoped_lock lock{mutex};
- return controller.colors_state;
-}
-
-BatteryLevelState EmulatedController::GetBattery() const {
- std::scoped_lock lock{mutex};
- return controller.battery_state;
-}
-
-const CameraState& EmulatedController::GetCamera() const {
- std::scoped_lock lock{mutex};
- return controller.camera_state;
-}
-
-RingSensorForce EmulatedController::GetRingSensorForce() const {
- return controller.ring_analog_state;
-}
-
-const NfcState& EmulatedController::GetNfc() const {
- std::scoped_lock lock{mutex};
- return controller.nfc_state;
-}
-
-NpadColor EmulatedController::GetNpadColor(u32 color) {
- return {
- .r = static_cast<u8>((color >> 16) & 0xFF),
- .g = static_cast<u8>((color >> 8) & 0xFF),
- .b = static_cast<u8>(color & 0xFF),
- .a = 0xff,
- };
-}
-
-void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) {
- std::scoped_lock lock{callback_mutex};
- for (const auto& poller_pair : callback_list) {
- const ControllerUpdateCallback& poller = poller_pair.second;
- if (!is_npad_service_update && poller.is_npad_service) {
- continue;
- }
- if (poller.on_change) {
- poller.on_change(type);
- }
- }
-}
-
-int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) {
- std::scoped_lock lock{callback_mutex};
- callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
- return last_callback_key++;
-}
-
-void EmulatedController::DeleteCallback(int key) {
- std::scoped_lock lock{callback_mutex};
- const auto& iterator = callback_list.find(key);
- if (iterator == callback_list.end()) {
- LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
- return;
- }
- callback_list.erase(iterator);
-}
-
-void EmulatedController::StatusUpdate() {
- turbo_button_state = (turbo_button_state + 1) % (TURBO_BUTTON_DELAY * 2);
-
- // Some drivers like key motion need constant refreshing
- for (std::size_t index = 0; index < motion_devices.size(); ++index) {
- const auto& raw_status = controller.motion_values[index].raw_status;
- auto& device = motion_devices[index];
- if (!raw_status.force_update) {
- continue;
- }
- if (!device) {
- continue;
- }
- device->ForceUpdate();
- }
-}
-
-NpadButton EmulatedController::GetTurboButtonMask() const {
- // Apply no mask when disabled
- if (turbo_button_state < TURBO_BUTTON_DELAY) {
- return {NpadButton::All};
- }
-
- NpadButtonState button_mask{};
- for (std::size_t index = 0; index < controller.button_values.size(); ++index) {
- if (!controller.button_values[index].turbo) {
- continue;
- }
-
- switch (index) {
- case Settings::NativeButton::A:
- button_mask.a.Assign(1);
- break;
- case Settings::NativeButton::B:
- button_mask.b.Assign(1);
- break;
- case Settings::NativeButton::X:
- button_mask.x.Assign(1);
- break;
- case Settings::NativeButton::Y:
- button_mask.y.Assign(1);
- break;
- case Settings::NativeButton::L:
- button_mask.l.Assign(1);
- break;
- case Settings::NativeButton::R:
- button_mask.r.Assign(1);
- break;
- case Settings::NativeButton::ZL:
- button_mask.zl.Assign(1);
- break;
- case Settings::NativeButton::ZR:
- button_mask.zr.Assign(1);
- break;
- case Settings::NativeButton::DLeft:
- button_mask.left.Assign(1);
- break;
- case Settings::NativeButton::DUp:
- button_mask.up.Assign(1);
- break;
- case Settings::NativeButton::DRight:
- button_mask.right.Assign(1);
- break;
- case Settings::NativeButton::DDown:
- button_mask.down.Assign(1);
- break;
- case Settings::NativeButton::SLLeft:
- button_mask.left_sl.Assign(1);
- break;
- case Settings::NativeButton::SLRight:
- button_mask.right_sl.Assign(1);
- break;
- case Settings::NativeButton::SRLeft:
- button_mask.left_sr.Assign(1);
- break;
- case Settings::NativeButton::SRRight:
- button_mask.right_sr.Assign(1);
- break;
- default:
- break;
- }
- }
-
- return static_cast<NpadButton>(~button_mask.raw);
-}
-
-} // namespace Core::HID
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
deleted file mode 100644
index d6e20ab66..000000000
--- a/src/core/hid/emulated_controller.h
+++ /dev/null
@@ -1,619 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-#include "common/common_types.h"
-#include "common/input.h"
-#include "common/param_package.h"
-#include "common/settings.h"
-#include "common/vector_math.h"
-#include "core/hid/hid_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hid/motion_input.h"
-
-namespace Core::HID {
-const std::size_t max_emulated_controllers = 2;
-const std::size_t output_devices_size = 4;
-struct ControllerMotionInfo {
- Common::Input::MotionStatus raw_status{};
- MotionInput emulated{};
-};
-
-using ButtonDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeButton::NumButtons>;
-using StickDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeAnalog::NumAnalogs>;
-using ControllerMotionDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>;
-using TriggerDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
-using ColorDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
-using BatteryDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
-using CameraDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
-using RingAnalogDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
-using NfcDevices =
- std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
-using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>;
-
-using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
-using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
-using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
-using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
-using ColorParams = std::array<Common::ParamPackage, max_emulated_controllers>;
-using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
-using CameraParams = std::array<Common::ParamPackage, max_emulated_controllers>;
-using RingAnalogParams = std::array<Common::ParamPackage, max_emulated_controllers>;
-using NfcParams = std::array<Common::ParamPackage, max_emulated_controllers>;
-using OutputParams = std::array<Common::ParamPackage, output_devices_size>;
-
-using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
-using SticksValues = std::array<Common::Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
-using TriggerValues =
- std::array<Common::Input::TriggerStatus, Settings::NativeTrigger::NumTriggers>;
-using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::NativeMotion::NumMotions>;
-using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
-using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
-using CameraValues = Common::Input::CameraStatus;
-using RingAnalogValue = Common::Input::AnalogStatus;
-using NfcValues = Common::Input::NfcStatus;
-using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
-
-struct AnalogSticks {
- AnalogStickState left{};
- AnalogStickState right{};
-};
-
-struct ControllerColors {
- NpadControllerColor fullkey{};
- NpadControllerColor left{};
- NpadControllerColor right{};
-};
-
-struct BatteryLevelState {
- NpadPowerInfo dual{};
- NpadPowerInfo left{};
- NpadPowerInfo right{};
-};
-
-struct CameraState {
- Core::IrSensor::ImageTransferProcessorFormat format{};
- std::vector<u8> data{};
- std::size_t sample{};
-};
-
-struct RingSensorForce {
- f32 force;
-};
-
-using NfcState = Common::Input::NfcStatus;
-
-struct ControllerMotion {
- Common::Vec3f accel{};
- Common::Vec3f gyro{};
- Common::Vec3f rotation{};
- Common::Vec3f euler{};
- std::array<Common::Vec3f, 3> orientation{};
- bool is_at_rest{};
-};
-
-enum EmulatedDeviceIndex : u8 {
- LeftIndex,
- RightIndex,
- DualIndex,
- AllDevices,
-};
-
-using MotionState = std::array<ControllerMotion, 2>;
-
-struct ControllerStatus {
- // Data from input_common
- ButtonValues button_values{};
- SticksValues stick_values{};
- ControllerMotionValues motion_values{};
- TriggerValues trigger_values{};
- ColorValues color_values{};
- BatteryValues battery_values{};
- VibrationValues vibration_values{};
- CameraValues camera_values{};
- RingAnalogValue ring_analog_value{};
- NfcValues nfc_values{};
-
- // Data for HID services
- HomeButtonState home_button_state{};
- CaptureButtonState capture_button_state{};
- NpadButtonState npad_button_state{};
- DebugPadButton debug_pad_button_state{};
- AnalogSticks analog_stick_state{};
- MotionState motion_state{};
- NpadGcTriggerState gc_trigger_state{};
- ControllerColors colors_state{};
- BatteryLevelState battery_state{};
- CameraState camera_state{};
- RingSensorForce ring_analog_state{};
- NfcState nfc_state{};
- Common::Input::PollingMode left_polling_mode{};
- Common::Input::PollingMode right_polling_mode{};
-};
-
-enum class ControllerTriggerType {
- Button,
- Stick,
- Trigger,
- Motion,
- Color,
- Battery,
- Vibration,
- IrSensor,
- RingController,
- Nfc,
- Connected,
- Disconnected,
- Type,
- All,
-};
-
-struct ControllerUpdateCallback {
- std::function<void(ControllerTriggerType)> on_change;
- bool is_npad_service;
-};
-
-class EmulatedController {
-public:
- /**
- * Contains all input data (buttons, joysticks, vibration, and motion) within this controller.
- * @param npad_id_type npad id type for this specific controller
- */
- explicit EmulatedController(NpadIdType npad_id_type_);
- ~EmulatedController();
-
- YUZU_NON_COPYABLE(EmulatedController);
- YUZU_NON_MOVEABLE(EmulatedController);
-
- /// Converts the controller type from settings to npad type
- static NpadStyleIndex MapSettingsTypeToNPad(Settings::ControllerType type);
-
- /// Converts npad type to the equivalent of controller type from settings
- static Settings::ControllerType MapNPadToSettingsType(NpadStyleIndex type);
-
- /// Gets the NpadIdType for this controller
- NpadIdType GetNpadIdType() const;
-
- /// Sets the NpadStyleIndex for this controller
- void SetNpadStyleIndex(NpadStyleIndex npad_type_);
-
- /**
- * Gets the NpadStyleIndex for this controller
- * @param get_temporary_value If true tmp_npad_type will be returned
- * @return NpadStyleIndex set on the controller
- */
- NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const;
-
- /**
- * Sets the supported controller types. Disconnects the controller if current type is not
- * supported
- * @param supported_styles bitflag with supported types
- */
- void SetSupportedNpadStyleTag(NpadStyleTag supported_styles);
-
- /**
- * Sets the connected status to true
- * @param use_temporary_value If true tmp_npad_type will be used
- */
- void Connect(bool use_temporary_value = false);
-
- /// Sets the connected status to false
- void Disconnect();
-
- /**
- * Is the emulated connected
- * @param get_temporary_value If true tmp_is_connected will be returned
- * @return true if the controller has the connected status
- */
- bool IsConnected(bool get_temporary_value = false) const;
-
- /// Removes all callbacks created from input devices
- void UnloadInput();
-
- /**
- * Sets the emulated controller into configuring mode
- * This prevents the modification of the HID state of the emulated controller by input commands
- */
- void EnableConfiguration();
-
- /// Returns the emulated controller into normal mode, allowing the modification of the HID state
- void DisableConfiguration();
-
- /// Enables Home and Screenshot buttons
- void EnableSystemButtons();
-
- /// Disables Home and Screenshot buttons
- void DisableSystemButtons();
-
- /// Sets Home and Screenshot buttons to false
- void ResetSystemButtons();
-
- /// Returns true if the emulated controller is in configuring mode
- bool IsConfiguring() const;
-
- /// Reload all input devices
- void ReloadInput();
-
- /// Overrides current mapped devices with the stored configuration and reloads all input devices
- void ReloadFromSettings();
-
- /// Updates current colors with the ones stored in the configuration
- void ReloadColorsFromSettings();
-
- /// Saves the current mapped configuration
- void SaveCurrentConfig();
-
- /// Reverts any mapped changes made that weren't saved
- void RestoreConfig();
-
- /// Returns a vector of mapped devices from the mapped button and stick parameters
- std::vector<Common::ParamPackage> GetMappedDevices() const;
-
- // Returns the current mapped button device
- Common::ParamPackage GetButtonParam(std::size_t index) const;
-
- // Returns the current mapped stick device
- Common::ParamPackage GetStickParam(std::size_t index) const;
-
- // Returns the current mapped motion device
- Common::ParamPackage GetMotionParam(std::size_t index) const;
-
- /**
- * Updates the current mapped button device
- * @param param ParamPackage with controller data to be mapped
- */
- void SetButtonParam(std::size_t index, Common::ParamPackage param);
-
- /**
- * Updates the current mapped stick device
- * @param param ParamPackage with controller data to be mapped
- */
- void SetStickParam(std::size_t index, Common::ParamPackage param);
-
- /**
- * Updates the current mapped motion device
- * @param param ParamPackage with controller data to be mapped
- */
- void SetMotionParam(std::size_t index, Common::ParamPackage param);
-
- /// Auto calibrates the current motion devices
- void StartMotionCalibration();
-
- /// Returns the latest button status from the controller with parameters
- ButtonValues GetButtonsValues() const;
-
- /// Returns the latest analog stick status from the controller with parameters
- SticksValues GetSticksValues() const;
-
- /// Returns the latest trigger status from the controller with parameters
- TriggerValues GetTriggersValues() const;
-
- /// Returns the latest motion status from the controller with parameters
- ControllerMotionValues GetMotionValues() const;
-
- /// Returns the latest color status from the controller with parameters
- ColorValues GetColorsValues() const;
-
- /// Returns the latest battery status from the controller with parameters
- BatteryValues GetBatteryValues() const;
-
- /// Returns the latest camera status from the controller with parameters
- CameraValues GetCameraValues() const;
-
- /// Returns the latest status of analog input from the ring sensor with parameters
- RingAnalogValue GetRingSensorValues() const;
-
- /// Returns the latest status of button input for the hid::HomeButton service
- HomeButtonState GetHomeButtons() const;
-
- /// Returns the latest status of button input for the hid::CaptureButton service
- CaptureButtonState GetCaptureButtons() const;
-
- /// Returns the latest status of button input for the hid::Npad service
- NpadButtonState GetNpadButtons() const;
-
- /// Returns the latest status of button input for the debug pad service
- DebugPadButton GetDebugPadButtons() const;
-
- /// Returns the latest status of stick input from the mouse
- AnalogSticks GetSticks() const;
-
- /// Returns the latest status of trigger input from the mouse
- NpadGcTriggerState GetTriggers() const;
-
- /// Returns the latest status of motion input from the mouse
- MotionState GetMotions() const;
-
- /// Returns the latest color value from the controller
- ControllerColors GetColors() const;
-
- /// Returns the latest battery status from the controller
- BatteryLevelState GetBattery() const;
-
- /// Returns the latest camera status from the controller
- const CameraState& GetCamera() const;
-
- /// Returns the latest ringcon force sensor value
- RingSensorForce GetRingSensorForce() const;
-
- /// Returns the latest ntag status from the controller
- const NfcState& GetNfc() const;
-
- /**
- * Sends a specific vibration to the output device
- * @return true if vibration had no errors
- */
- bool SetVibration(std::size_t device_index, VibrationValue vibration);
-
- /**
- * Sends a small vibration to the output device
- * @return true if SetVibration was successful
- */
- bool IsVibrationEnabled(std::size_t device_index);
-
- /**
- * Sets the desired data to be polled from a controller
- * @param device_index index of the controller to set the polling mode
- * @param polling_mode type of input desired buttons, gyro, nfc, ir, etc.
- * @return driver result from this command
- */
- Common::Input::DriverResult SetPollingMode(EmulatedDeviceIndex device_index,
- Common::Input::PollingMode polling_mode);
- /**
- * Get the current polling mode from a controller
- * @param device_index index of the controller to set the polling mode
- * @return current polling mode
- */
- Common::Input::PollingMode GetPollingMode(EmulatedDeviceIndex device_index) const;
-
- /**
- * Sets the desired camera format to be polled from a controller
- * @param camera_format size of each frame
- * @return true if SetCameraFormat was successful
- */
- bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format);
-
- // Returns the current mapped ring device
- Common::ParamPackage GetRingParam() const;
-
- /**
- * Updates the current mapped ring device
- * @param param ParamPackage with ring sensor data to be mapped
- */
- void SetRingParam(Common::ParamPackage param);
-
- /// Returns true if the device has nfc support
- bool HasNfc() const;
-
- /// Sets the joycon in nfc mode and increments the handle count
- bool AddNfcHandle();
-
- /// Decrements the handle count if zero sets the joycon in active mode
- bool RemoveNfcHandle();
-
- /// Start searching for nfc tags
- bool StartNfcPolling();
-
- /// Stop searching for nfc tags
- bool StopNfcPolling();
-
- /// Returns true if the nfc tag was readable
- bool ReadAmiiboData(std::vector<u8>& data);
-
- /// Returns true if the nfc tag was written
- bool WriteNfc(const std::vector<u8>& data);
-
- /// Returns true if the nfc tag was readable
- bool ReadMifareData(const Common::Input::MifareRequest& request,
- Common::Input::MifareRequest& out_data);
-
- /// Returns true if the nfc tag was written
- bool WriteMifareData(const Common::Input::MifareRequest& request);
-
- /// Returns the led pattern corresponding to this emulated controller
- LedPattern GetLedPattern() const;
-
- /// Asks the output device to change the player led pattern
- void SetLedPattern();
-
- /// Changes sensitivity of the motion sensor
- void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode);
-
- /**
- * Adds a callback to the list of events
- * @param update_callback A ConsoleUpdateCallback that will be triggered
- * @return an unique key corresponding to the callback index in the list
- */
- int SetCallback(ControllerUpdateCallback update_callback);
-
- /**
- * Removes a callback from the list stopping any future events to this object
- * @param key Key corresponding to the callback index in the list
- */
- void DeleteCallback(int key);
-
- /// Swaps the state of the turbo buttons and updates motion input
- void StatusUpdate();
-
-private:
- /// creates input devices from params
- void LoadDevices();
-
- /// Set the params for TAS devices
- void LoadTASParams();
-
- /// Set the params for virtual pad devices
- void LoadVirtualGamepadParams();
-
- /**
- * @param use_temporary_value If true tmp_npad_type will be used
- * @return true if the controller style is fullkey
- */
- bool IsControllerFullkey(bool use_temporary_value = false) const;
-
- /**
- * Checks the current controller type against the supported_style_tag
- * @param use_temporary_value If true tmp_npad_type will be used
- * @return true if the controller is supported
- */
- bool IsControllerSupported(bool use_temporary_value = false) const;
-
- /**
- * Updates the button status of the controller
- * @param callback A CallbackStatus containing the button status
- * @param index Button ID of the to be updated
- */
- void SetButton(const Common::Input::CallbackStatus& callback, std::size_t index,
- Common::UUID uuid);
-
- /**
- * Updates the analog stick status of the controller
- * @param callback A CallbackStatus containing the analog stick status
- * @param index stick ID of the to be updated
- */
- void SetStick(const Common::Input::CallbackStatus& callback, std::size_t index,
- Common::UUID uuid);
-
- /**
- * Updates the trigger status of the controller
- * @param callback A CallbackStatus containing the trigger status
- * @param index trigger ID of the to be updated
- */
- void SetTrigger(const Common::Input::CallbackStatus& callback, std::size_t index,
- Common::UUID uuid);
-
- /**
- * Updates the motion status of the controller
- * @param callback A CallbackStatus containing gyro and accelerometer data
- * @param index motion ID of the to be updated
- */
- void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the color status of the controller
- * @param callback A CallbackStatus containing the color status
- * @param index color ID of the to be updated
- */
- void SetColors(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the battery status of the controller
- * @param callback A CallbackStatus containing the battery status
- * @param index battery ID of the to be updated
- */
- void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the camera status of the controller
- * @param callback A CallbackStatus containing the camera status
- */
- void SetCamera(const Common::Input::CallbackStatus& callback);
-
- /**
- * Updates the ring analog sensor status of the ring controller
- * @param callback A CallbackStatus containing the force status
- */
- void SetRingAnalog(const Common::Input::CallbackStatus& callback);
-
- /**
- * Updates the nfc status of the controller
- * @param callback A CallbackStatus containing the nfc status
- */
- void SetNfc(const Common::Input::CallbackStatus& callback);
-
- /**
- * Converts a color format from bgra to rgba
- * @param color in bgra format
- * @return NpadColor in rgba format
- */
- NpadColor GetNpadColor(u32 color);
-
- /**
- * Triggers a callback that something has changed on the controller status
- * @param type Input type of the event to trigger
- * @param is_service_update indicates if this event should only be sent to HID services
- */
- void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
-
- NpadButton GetTurboButtonMask() const;
-
- const NpadIdType npad_id_type;
- NpadStyleIndex npad_type{NpadStyleIndex::None};
- NpadStyleIndex original_npad_type{NpadStyleIndex::None};
- NpadStyleTag supported_style_tag{NpadStyleSet::All};
- bool is_connected{false};
- bool is_configuring{false};
- bool is_initalized{false};
- bool system_buttons_enabled{true};
- f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
- u32 turbo_button_state{0};
- std::size_t nfc_handles{0};
-
- // Temporary values to avoid doing changes while the controller is in configuring mode
- NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
- bool tmp_is_connected{false};
-
- ButtonParams button_params;
- StickParams stick_params;
- ControllerMotionParams motion_params;
- TriggerParams trigger_params;
- BatteryParams battery_params;
- ColorParams color_params;
- CameraParams camera_params;
- RingAnalogParams ring_params;
- NfcParams nfc_params;
- OutputParams output_params;
-
- ButtonDevices button_devices;
- StickDevices stick_devices;
- ControllerMotionDevices motion_devices;
- TriggerDevices trigger_devices;
- BatteryDevices battery_devices;
- ColorDevices color_devices;
- CameraDevices camera_devices;
- RingAnalogDevices ring_analog_devices;
- NfcDevices nfc_devices;
- OutputDevices output_devices;
-
- // TAS related variables
- ButtonParams tas_button_params;
- StickParams tas_stick_params;
- ButtonDevices tas_button_devices;
- StickDevices tas_stick_devices;
-
- // Virtual gamepad related variables
- ButtonParams virtual_button_params;
- StickParams virtual_stick_params;
- ControllerMotionParams virtual_motion_params;
- ButtonDevices virtual_button_devices;
- StickDevices virtual_stick_devices;
- ControllerMotionDevices virtual_motion_devices;
-
- mutable std::mutex mutex;
- mutable std::mutex callback_mutex;
- mutable std::mutex npad_mutex;
- mutable std::mutex connect_mutex;
- std::unordered_map<int, ControllerUpdateCallback> callback_list;
- int last_callback_key = 0;
-
- // Stores the current status of all controller input
- ControllerStatus controller;
-};
-
-} // namespace Core::HID
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
deleted file mode 100644
index 8e165dded..000000000
--- a/src/core/hid/emulated_devices.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <algorithm>
-#include <fmt/format.h>
-
-#include "core/hid/emulated_devices.h"
-#include "core/hid/input_converter.h"
-
-namespace Core::HID {
-
-EmulatedDevices::EmulatedDevices() = default;
-
-EmulatedDevices::~EmulatedDevices() = default;
-
-void EmulatedDevices::ReloadFromSettings() {
- ReloadInput();
-}
-
-void EmulatedDevices::ReloadInput() {
- // If you load any device here add the equivalent to the UnloadInput() function
-
- // Native Mouse is mapped on port 1, pad 0
- const Common::ParamPackage mouse_params{"engine:mouse,port:1,pad:0"};
-
- // Keyboard keys is mapped on port 1, pad 0 for normal keys, pad 1 for moddifier keys
- const Common::ParamPackage keyboard_params{"engine:keyboard,port:1"};
-
- std::size_t key_index = 0;
- for (auto& mouse_device : mouse_button_devices) {
- Common::ParamPackage mouse_button_params = mouse_params;
- mouse_button_params.Set("button", static_cast<int>(key_index));
- mouse_device = Common::Input::CreateInputDevice(mouse_button_params);
- key_index++;
- }
-
- Common::ParamPackage mouse_position_params = mouse_params;
- mouse_position_params.Set("axis_x", 0);
- mouse_position_params.Set("axis_y", 1);
- mouse_position_params.Set("deadzone", 0.0f);
- mouse_position_params.Set("range", 1.0f);
- mouse_position_params.Set("threshold", 0.0f);
- mouse_stick_device = Common::Input::CreateInputDevice(mouse_position_params);
-
- // First two axis are reserved for mouse position
- key_index = 2;
- for (auto& mouse_device : mouse_wheel_devices) {
- Common::ParamPackage mouse_wheel_params = mouse_params;
- mouse_wheel_params.Set("axis", static_cast<int>(key_index));
- mouse_device = Common::Input::CreateInputDevice(mouse_wheel_params);
- key_index++;
- }
-
- key_index = 0;
- for (auto& keyboard_device : keyboard_devices) {
- Common::ParamPackage keyboard_key_params = keyboard_params;
- keyboard_key_params.Set("button", static_cast<int>(key_index));
- keyboard_key_params.Set("pad", 0);
- keyboard_device = Common::Input::CreateInputDevice(keyboard_key_params);
- key_index++;
- }
-
- key_index = 0;
- for (auto& keyboard_device : keyboard_modifier_devices) {
- Common::ParamPackage keyboard_moddifier_params = keyboard_params;
- keyboard_moddifier_params.Set("button", static_cast<int>(key_index));
- keyboard_moddifier_params.Set("pad", 1);
- keyboard_device = Common::Input::CreateInputDevice(keyboard_moddifier_params);
- key_index++;
- }
-
- for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) {
- if (!mouse_button_devices[index]) {
- continue;
- }
- mouse_button_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetMouseButton(callback, index);
- },
- });
- }
-
- for (std::size_t index = 0; index < mouse_wheel_devices.size(); ++index) {
- if (!mouse_wheel_devices[index]) {
- continue;
- }
- mouse_wheel_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetMouseWheel(callback, index);
- },
- });
- }
-
- if (mouse_stick_device) {
- mouse_stick_device->SetCallback({
- .on_change =
- [this](const Common::Input::CallbackStatus& callback) {
- SetMousePosition(callback);
- },
- });
- }
-
- for (std::size_t index = 0; index < keyboard_devices.size(); ++index) {
- if (!keyboard_devices[index]) {
- continue;
- }
- keyboard_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetKeyboardButton(callback, index);
- },
- });
- }
-
- for (std::size_t index = 0; index < keyboard_modifier_devices.size(); ++index) {
- if (!keyboard_modifier_devices[index]) {
- continue;
- }
- keyboard_modifier_devices[index]->SetCallback({
- .on_change =
- [this, index](const Common::Input::CallbackStatus& callback) {
- SetKeyboardModifier(callback, index);
- },
- });
- }
-}
-
-void EmulatedDevices::UnloadInput() {
- for (auto& button : mouse_button_devices) {
- button.reset();
- }
- for (auto& analog : mouse_wheel_devices) {
- analog.reset();
- }
- mouse_stick_device.reset();
- for (auto& button : keyboard_devices) {
- button.reset();
- }
- for (auto& button : keyboard_modifier_devices) {
- button.reset();
- }
-}
-
-void EmulatedDevices::EnableConfiguration() {
- is_configuring = true;
- SaveCurrentConfig();
-}
-
-void EmulatedDevices::DisableConfiguration() {
- is_configuring = false;
-}
-
-bool EmulatedDevices::IsConfiguring() const {
- return is_configuring;
-}
-
-void EmulatedDevices::SaveCurrentConfig() {
- if (!is_configuring) {
- return;
- }
-}
-
-void EmulatedDevices::RestoreConfig() {
- if (!is_configuring) {
- return;
- }
- ReloadFromSettings();
-}
-
-void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= device_status.keyboard_values.size()) {
- return;
- }
- std::unique_lock lock{mutex};
- bool value_changed = false;
- const auto new_status = TransformToButton(callback);
- auto& current_status = device_status.keyboard_values[index];
- current_status.toggle = new_status.toggle;
-
- // Update button status with current status
- if (!current_status.toggle) {
- current_status.locked = false;
- if (current_status.value != new_status.value) {
- current_status.value = new_status.value;
- value_changed = true;
- }
- } else {
- // Toggle button and lock status
- if (new_status.value && !current_status.locked) {
- current_status.locked = true;
- current_status.value = !current_status.value;
- value_changed = true;
- }
-
- // Unlock button, ready for next press
- if (!new_status.value && current_status.locked) {
- current_status.locked = false;
- }
- }
-
- if (!value_changed) {
- return;
- }
-
- if (is_configuring) {
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Keyboard);
- return;
- }
-
- // Index should be converted from NativeKeyboard to KeyboardKeyIndex
- UpdateKey(index, current_status.value);
-
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Keyboard);
-}
-
-void EmulatedDevices::UpdateKey(std::size_t key_index, bool status) {
- constexpr std::size_t KEYS_PER_BYTE = 8;
- auto& entry = device_status.keyboard_state.key[key_index / KEYS_PER_BYTE];
- const u8 mask = static_cast<u8>(1 << (key_index % KEYS_PER_BYTE));
- if (status) {
- entry = entry | mask;
- } else {
- entry = static_cast<u8>(entry & ~mask);
- }
-}
-
-void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= device_status.keyboard_moddifier_values.size()) {
- return;
- }
- std::unique_lock lock{mutex};
- bool value_changed = false;
- const auto new_status = TransformToButton(callback);
- auto& current_status = device_status.keyboard_moddifier_values[index];
- current_status.toggle = new_status.toggle;
-
- // Update button status with current
- if (!current_status.toggle) {
- current_status.locked = false;
- if (current_status.value != new_status.value) {
- current_status.value = new_status.value;
- value_changed = true;
- }
- } else {
- // Toggle button and lock status
- if (new_status.value && !current_status.locked) {
- current_status.locked = true;
- current_status.value = !current_status.value;
- value_changed = true;
- }
-
- // Unlock button ready for next press
- if (!new_status.value && current_status.locked) {
- current_status.locked = false;
- }
- }
-
- if (!value_changed) {
- return;
- }
-
- if (is_configuring) {
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::KeyboardModdifier);
- return;
- }
-
- switch (index) {
- case Settings::NativeKeyboard::LeftControl:
- case Settings::NativeKeyboard::RightControl:
- device_status.keyboard_moddifier_state.control.Assign(current_status.value);
- break;
- case Settings::NativeKeyboard::LeftShift:
- case Settings::NativeKeyboard::RightShift:
- device_status.keyboard_moddifier_state.shift.Assign(current_status.value);
- break;
- case Settings::NativeKeyboard::LeftAlt:
- device_status.keyboard_moddifier_state.left_alt.Assign(current_status.value);
- break;
- case Settings::NativeKeyboard::RightAlt:
- device_status.keyboard_moddifier_state.right_alt.Assign(current_status.value);
- break;
- case Settings::NativeKeyboard::CapsLock:
- device_status.keyboard_moddifier_state.caps_lock.Assign(current_status.value);
- break;
- case Settings::NativeKeyboard::ScrollLock:
- device_status.keyboard_moddifier_state.scroll_lock.Assign(current_status.value);
- break;
- case Settings::NativeKeyboard::NumLock:
- device_status.keyboard_moddifier_state.num_lock.Assign(current_status.value);
- break;
- }
-
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::KeyboardModdifier);
-}
-
-void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= device_status.mouse_button_values.size()) {
- return;
- }
- std::unique_lock lock{mutex};
- bool value_changed = false;
- const auto new_status = TransformToButton(callback);
- auto& current_status = device_status.mouse_button_values[index];
- current_status.toggle = new_status.toggle;
-
- // Update button status with current
- if (!current_status.toggle) {
- current_status.locked = false;
- if (current_status.value != new_status.value) {
- current_status.value = new_status.value;
- value_changed = true;
- }
- } else {
- // Toggle button and lock status
- if (new_status.value && !current_status.locked) {
- current_status.locked = true;
- current_status.value = !current_status.value;
- value_changed = true;
- }
-
- // Unlock button ready for next press
- if (!new_status.value && current_status.locked) {
- current_status.locked = false;
- }
- }
-
- if (!value_changed) {
- return;
- }
-
- if (is_configuring) {
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Mouse);
- return;
- }
-
- switch (index) {
- case Settings::NativeMouseButton::Left:
- device_status.mouse_button_state.left.Assign(current_status.value);
- break;
- case Settings::NativeMouseButton::Right:
- device_status.mouse_button_state.right.Assign(current_status.value);
- break;
- case Settings::NativeMouseButton::Middle:
- device_status.mouse_button_state.middle.Assign(current_status.value);
- break;
- case Settings::NativeMouseButton::Forward:
- device_status.mouse_button_state.forward.Assign(current_status.value);
- break;
- case Settings::NativeMouseButton::Back:
- device_status.mouse_button_state.back.Assign(current_status.value);
- break;
- }
-
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Mouse);
-}
-
-void EmulatedDevices::SetMouseWheel(const Common::Input::CallbackStatus& callback,
- std::size_t index) {
- if (index >= device_status.mouse_wheel_values.size()) {
- return;
- }
- std::unique_lock lock{mutex};
- const auto analog_value = TransformToAnalog(callback);
-
- device_status.mouse_wheel_values[index] = analog_value;
-
- if (is_configuring) {
- device_status.mouse_wheel_state = {};
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Mouse);
- return;
- }
-
- switch (index) {
- case Settings::NativeMouseWheel::X:
- device_status.mouse_wheel_state.x = static_cast<s32>(analog_value.value);
- break;
- case Settings::NativeMouseWheel::Y:
- device_status.mouse_wheel_state.y = static_cast<s32>(analog_value.value);
- break;
- }
-
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Mouse);
-}
-
-void EmulatedDevices::SetMousePosition(const Common::Input::CallbackStatus& callback) {
- std::unique_lock lock{mutex};
- const auto touch_value = TransformToTouch(callback);
-
- device_status.mouse_stick_value = touch_value;
-
- if (is_configuring) {
- device_status.mouse_position_state = {};
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Mouse);
- return;
- }
-
- device_status.mouse_position_state.x = touch_value.x.value;
- device_status.mouse_position_state.y = touch_value.y.value;
-
- lock.unlock();
- TriggerOnChange(DeviceTriggerType::Mouse);
-}
-
-KeyboardValues EmulatedDevices::GetKeyboardValues() const {
- std::scoped_lock lock{mutex};
- return device_status.keyboard_values;
-}
-
-KeyboardModifierValues EmulatedDevices::GetKeyboardModdifierValues() const {
- std::scoped_lock lock{mutex};
- return device_status.keyboard_moddifier_values;
-}
-
-MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const {
- std::scoped_lock lock{mutex};
- return device_status.mouse_button_values;
-}
-
-KeyboardKey EmulatedDevices::GetKeyboard() const {
- std::scoped_lock lock{mutex};
- return device_status.keyboard_state;
-}
-
-KeyboardModifier EmulatedDevices::GetKeyboardModifier() const {
- std::scoped_lock lock{mutex};
- return device_status.keyboard_moddifier_state;
-}
-
-MouseButton EmulatedDevices::GetMouseButtons() const {
- std::scoped_lock lock{mutex};
- return device_status.mouse_button_state;
-}
-
-MousePosition EmulatedDevices::GetMousePosition() const {
- std::scoped_lock lock{mutex};
- return device_status.mouse_position_state;
-}
-
-AnalogStickState EmulatedDevices::GetMouseWheel() const {
- std::scoped_lock lock{mutex};
- return device_status.mouse_wheel_state;
-}
-
-void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
- std::scoped_lock lock{callback_mutex};
- for (const auto& poller_pair : callback_list) {
- const InterfaceUpdateCallback& poller = poller_pair.second;
- if (poller.on_change) {
- poller.on_change(type);
- }
- }
-}
-
-int EmulatedDevices::SetCallback(InterfaceUpdateCallback update_callback) {
- std::scoped_lock lock{callback_mutex};
- callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
- return last_callback_key++;
-}
-
-void EmulatedDevices::DeleteCallback(int key) {
- std::scoped_lock lock{callback_mutex};
- const auto& iterator = callback_list.find(key);
- if (iterator == callback_list.end()) {
- LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
- return;
- }
- callback_list.erase(iterator);
-}
-} // namespace Core::HID
diff --git a/src/core/hid/emulated_devices.h b/src/core/hid/emulated_devices.h
deleted file mode 100644
index 5eab693e4..000000000
--- a/src/core/hid/emulated_devices.h
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-#include "common/common_types.h"
-#include "common/input.h"
-#include "common/param_package.h"
-#include "common/settings.h"
-#include "core/hid/hid_types.h"
-
-namespace Core::HID {
-using KeyboardDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
- Settings::NativeKeyboard::NumKeyboardKeys>;
-using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
- Settings::NativeKeyboard::NumKeyboardMods>;
-using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
- Settings::NativeMouseButton::NumMouseButtons>;
-using MouseWheelDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
- Settings::NativeMouseWheel::NumMouseWheels>;
-using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
-
-using MouseButtonParams =
- std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;
-
-using KeyboardValues =
- std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>;
-using KeyboardModifierValues =
- std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
-using MouseButtonValues =
- std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
-using MouseWheelValues =
- std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
-using MouseStickValue = Common::Input::TouchStatus;
-
-struct MousePosition {
- f32 x;
- f32 y;
-};
-
-struct DeviceStatus {
- // Data from input_common
- KeyboardValues keyboard_values{};
- KeyboardModifierValues keyboard_moddifier_values{};
- MouseButtonValues mouse_button_values{};
- MouseWheelValues mouse_wheel_values{};
- MouseStickValue mouse_stick_value{};
-
- // Data for HID services
- KeyboardKey keyboard_state{};
- KeyboardModifier keyboard_moddifier_state{};
- MouseButton mouse_button_state{};
- MousePosition mouse_position_state{};
- AnalogStickState mouse_wheel_state{};
-};
-
-enum class DeviceTriggerType {
- Keyboard,
- KeyboardModdifier,
- Mouse,
- RingController,
-};
-
-struct InterfaceUpdateCallback {
- std::function<void(DeviceTriggerType)> on_change;
-};
-
-class EmulatedDevices {
-public:
- /**
- * Contains all input data related to external devices that aren't necessarily a controller
- * This includes devices such as the keyboard or mouse
- */
- explicit EmulatedDevices();
- ~EmulatedDevices();
-
- YUZU_NON_COPYABLE(EmulatedDevices);
- YUZU_NON_MOVEABLE(EmulatedDevices);
-
- /// Removes all callbacks created from input devices
- void UnloadInput();
-
- /**
- * Sets the emulated devices into configuring mode
- * This prevents the modification of the HID state of the emulated devices by input commands
- */
- void EnableConfiguration();
-
- /// Returns the emulated devices into normal mode, allowing the modification of the HID state
- void DisableConfiguration();
-
- /// Returns true if the emulated device is in configuring mode
- bool IsConfiguring() const;
-
- /// Reload all input devices
- void ReloadInput();
-
- /// Overrides current mapped devices with the stored configuration and reloads all input devices
- void ReloadFromSettings();
-
- /// Saves the current mapped configuration
- void SaveCurrentConfig();
-
- /// Reverts any mapped changes made that weren't saved
- void RestoreConfig();
-
- /// Returns the latest status of button input from the keyboard with parameters
- KeyboardValues GetKeyboardValues() const;
-
- /// Returns the latest status of button input from the keyboard modifiers with parameters
- KeyboardModifierValues GetKeyboardModdifierValues() const;
-
- /// Returns the latest status of button input from the mouse with parameters
- MouseButtonValues GetMouseButtonsValues() const;
-
- /// Returns the latest status of button input from the keyboard
- KeyboardKey GetKeyboard() const;
-
- /// Returns the latest status of button input from the keyboard modifiers
- KeyboardModifier GetKeyboardModifier() const;
-
- /// Returns the latest status of button input from the mouse
- MouseButton GetMouseButtons() const;
-
- /// Returns the latest mouse coordinates
- MousePosition GetMousePosition() const;
-
- /// Returns the latest mouse wheel change
- AnalogStickState GetMouseWheel() const;
-
- /**
- * Adds a callback to the list of events
- * @param update_callback InterfaceUpdateCallback that will be triggered
- * @return an unique key corresponding to the callback index in the list
- */
- int SetCallback(InterfaceUpdateCallback update_callback);
-
- /**
- * Removes a callback from the list stopping any future events to this object
- * @param key Key corresponding to the callback index in the list
- */
- void DeleteCallback(int key);
-
-private:
- /// Helps assigning a value to keyboard_state
- void UpdateKey(std::size_t key_index, bool status);
-
- /**
- * Updates the touch status of the keyboard device
- * @param callback A CallbackStatus containing the key status
- * @param index key ID to be updated
- */
- void SetKeyboardButton(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the keyboard status of the keyboard device
- * @param callback A CallbackStatus containing the modifier key status
- * @param index modifier key ID to be updated
- */
- void SetKeyboardModifier(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the mouse button status of the mouse device
- * @param callback A CallbackStatus containing the button status
- * @param index Button ID to be updated
- */
- void SetMouseButton(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the mouse wheel status of the mouse device
- * @param callback A CallbackStatus containing the wheel status
- * @param index wheel ID to be updated
- */
- void SetMouseWheel(const Common::Input::CallbackStatus& callback, std::size_t index);
-
- /**
- * Updates the mouse position status of the mouse device
- * @param callback A CallbackStatus containing the position status
- */
- void SetMousePosition(const Common::Input::CallbackStatus& callback);
-
- /**
- * Triggers a callback that something has changed on the device status
- * @param type Input type of the event to trigger
- */
- void TriggerOnChange(DeviceTriggerType type);
-
- bool is_configuring{false};
-
- KeyboardDevices keyboard_devices;
- KeyboardModifierDevices keyboard_modifier_devices;
- MouseButtonDevices mouse_button_devices;
- MouseWheelDevices mouse_wheel_devices;
- MouseStickDevice mouse_stick_device;
-
- mutable std::mutex mutex;
- mutable std::mutex callback_mutex;
- std::unordered_map<int, InterfaceUpdateCallback> callback_list;
- int last_callback_key = 0;
-
- // Stores the current status of all external device input
- DeviceStatus device_status;
-};
-
-} // namespace Core::HID
diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp
deleted file mode 100644
index 2cf25a870..000000000
--- a/src/core/hid/hid_core.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/assert.h"
-#include "core/hid/emulated_console.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/emulated_devices.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/hid_util.h"
-
-namespace Core::HID {
-
-HIDCore::HIDCore()
- : player_1{std::make_unique<EmulatedController>(NpadIdType::Player1)},
- player_2{std::make_unique<EmulatedController>(NpadIdType::Player2)},
- player_3{std::make_unique<EmulatedController>(NpadIdType::Player3)},
- player_4{std::make_unique<EmulatedController>(NpadIdType::Player4)},
- player_5{std::make_unique<EmulatedController>(NpadIdType::Player5)},
- player_6{std::make_unique<EmulatedController>(NpadIdType::Player6)},
- player_7{std::make_unique<EmulatedController>(NpadIdType::Player7)},
- player_8{std::make_unique<EmulatedController>(NpadIdType::Player8)},
- other{std::make_unique<EmulatedController>(NpadIdType::Other)},
- handheld{std::make_unique<EmulatedController>(NpadIdType::Handheld)},
- console{std::make_unique<EmulatedConsole>()}, devices{std::make_unique<EmulatedDevices>()} {}
-
-HIDCore::~HIDCore() = default;
-
-EmulatedController* HIDCore::GetEmulatedController(NpadIdType npad_id_type) {
- switch (npad_id_type) {
- case NpadIdType::Player1:
- return player_1.get();
- case NpadIdType::Player2:
- return player_2.get();
- case NpadIdType::Player3:
- return player_3.get();
- case NpadIdType::Player4:
- return player_4.get();
- case NpadIdType::Player5:
- return player_5.get();
- case NpadIdType::Player6:
- return player_6.get();
- case NpadIdType::Player7:
- return player_7.get();
- case NpadIdType::Player8:
- return player_8.get();
- case NpadIdType::Other:
- return other.get();
- case NpadIdType::Handheld:
- return handheld.get();
- case NpadIdType::Invalid:
- default:
- ASSERT_MSG(false, "Invalid NpadIdType={}", npad_id_type);
- return nullptr;
- }
-}
-
-const EmulatedController* HIDCore::GetEmulatedController(NpadIdType npad_id_type) const {
- switch (npad_id_type) {
- case NpadIdType::Player1:
- return player_1.get();
- case NpadIdType::Player2:
- return player_2.get();
- case NpadIdType::Player3:
- return player_3.get();
- case NpadIdType::Player4:
- return player_4.get();
- case NpadIdType::Player5:
- return player_5.get();
- case NpadIdType::Player6:
- return player_6.get();
- case NpadIdType::Player7:
- return player_7.get();
- case NpadIdType::Player8:
- return player_8.get();
- case NpadIdType::Other:
- return other.get();
- case NpadIdType::Handheld:
- return handheld.get();
- case NpadIdType::Invalid:
- default:
- ASSERT_MSG(false, "Invalid NpadIdType={}", npad_id_type);
- return nullptr;
- }
-}
-EmulatedConsole* HIDCore::GetEmulatedConsole() {
- return console.get();
-}
-
-const EmulatedConsole* HIDCore::GetEmulatedConsole() const {
- return console.get();
-}
-
-EmulatedDevices* HIDCore::GetEmulatedDevices() {
- return devices.get();
-}
-
-const EmulatedDevices* HIDCore::GetEmulatedDevices() const {
- return devices.get();
-}
-
-EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) {
- return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
-}
-
-const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t index) const {
- return GetEmulatedController(Service::HID::IndexToNpadIdType(index));
-}
-
-void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) {
- supported_style_tag.raw = style_tag.raw;
- player_1->SetSupportedNpadStyleTag(supported_style_tag);
- player_2->SetSupportedNpadStyleTag(supported_style_tag);
- player_3->SetSupportedNpadStyleTag(supported_style_tag);
- player_4->SetSupportedNpadStyleTag(supported_style_tag);
- player_5->SetSupportedNpadStyleTag(supported_style_tag);
- player_6->SetSupportedNpadStyleTag(supported_style_tag);
- player_7->SetSupportedNpadStyleTag(supported_style_tag);
- player_8->SetSupportedNpadStyleTag(supported_style_tag);
- other->SetSupportedNpadStyleTag(supported_style_tag);
- handheld->SetSupportedNpadStyleTag(supported_style_tag);
-}
-
-NpadStyleTag HIDCore::GetSupportedStyleTag() const {
- return supported_style_tag;
-}
-
-s8 HIDCore::GetPlayerCount() const {
- s8 active_players = 0;
- for (std::size_t player_index = 0; player_index < available_controllers - 2; ++player_index) {
- const auto* const controller = GetEmulatedControllerByIndex(player_index);
- if (controller->IsConnected()) {
- active_players++;
- }
- }
- return active_players;
-}
-
-NpadIdType HIDCore::GetFirstNpadId() const {
- for (std::size_t player_index = 0; player_index < available_controllers; ++player_index) {
- const auto* const controller = GetEmulatedControllerByIndex(player_index);
- if (controller->IsConnected()) {
- return controller->GetNpadIdType();
- }
- }
- return NpadIdType::Player1;
-}
-
-NpadIdType HIDCore::GetFirstDisconnectedNpadId() const {
- for (std::size_t player_index = 0; player_index < available_controllers; ++player_index) {
- const auto* const controller = GetEmulatedControllerByIndex(player_index);
- if (!controller->IsConnected()) {
- return controller->GetNpadIdType();
- }
- }
- return NpadIdType::Player1;
-}
-
-void HIDCore::SetLastActiveController(NpadIdType npad_id) {
- last_active_controller = npad_id;
-}
-
-NpadIdType HIDCore::GetLastActiveController() const {
- return last_active_controller;
-}
-
-void HIDCore::EnableAllControllerConfiguration() {
- player_1->EnableConfiguration();
- player_2->EnableConfiguration();
- player_3->EnableConfiguration();
- player_4->EnableConfiguration();
- player_5->EnableConfiguration();
- player_6->EnableConfiguration();
- player_7->EnableConfiguration();
- player_8->EnableConfiguration();
- other->EnableConfiguration();
- handheld->EnableConfiguration();
-}
-
-void HIDCore::DisableAllControllerConfiguration() {
- player_1->DisableConfiguration();
- player_2->DisableConfiguration();
- player_3->DisableConfiguration();
- player_4->DisableConfiguration();
- player_5->DisableConfiguration();
- player_6->DisableConfiguration();
- player_7->DisableConfiguration();
- player_8->DisableConfiguration();
- other->DisableConfiguration();
- handheld->DisableConfiguration();
-}
-
-void HIDCore::ReloadInputDevices() {
- player_1->ReloadFromSettings();
- player_2->ReloadFromSettings();
- player_3->ReloadFromSettings();
- player_4->ReloadFromSettings();
- player_5->ReloadFromSettings();
- player_6->ReloadFromSettings();
- player_7->ReloadFromSettings();
- player_8->ReloadFromSettings();
- other->ReloadFromSettings();
- handheld->ReloadFromSettings();
- console->ReloadFromSettings();
- devices->ReloadFromSettings();
-}
-
-void HIDCore::UnloadInputDevices() {
- player_1->UnloadInput();
- player_2->UnloadInput();
- player_3->UnloadInput();
- player_4->UnloadInput();
- player_5->UnloadInput();
- player_6->UnloadInput();
- player_7->UnloadInput();
- player_8->UnloadInput();
- other->UnloadInput();
- handheld->UnloadInput();
- console->UnloadInput();
- devices->UnloadInput();
-}
-
-} // namespace Core::HID
diff --git a/src/core/hid/hid_core.h b/src/core/hid/hid_core.h
deleted file mode 100644
index 80abab18b..000000000
--- a/src/core/hid/hid_core.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <memory>
-
-#include "common/common_funcs.h"
-#include "core/hid/hid_types.h"
-
-namespace Core::HID {
-class EmulatedConsole;
-class EmulatedController;
-class EmulatedDevices;
-} // namespace Core::HID
-
-namespace Core::HID {
-
-class HIDCore {
-public:
- explicit HIDCore();
- ~HIDCore();
-
- YUZU_NON_COPYABLE(HIDCore);
- YUZU_NON_MOVEABLE(HIDCore);
-
- EmulatedController* GetEmulatedController(NpadIdType npad_id_type);
- const EmulatedController* GetEmulatedController(NpadIdType npad_id_type) const;
-
- EmulatedController* GetEmulatedControllerByIndex(std::size_t index);
- const EmulatedController* GetEmulatedControllerByIndex(std::size_t index) const;
-
- EmulatedConsole* GetEmulatedConsole();
- const EmulatedConsole* GetEmulatedConsole() const;
-
- EmulatedDevices* GetEmulatedDevices();
- const EmulatedDevices* GetEmulatedDevices() const;
-
- void SetSupportedStyleTag(NpadStyleTag style_tag);
- NpadStyleTag GetSupportedStyleTag() const;
-
- /// Counts the connected players from P1-P8
- s8 GetPlayerCount() const;
-
- /// Returns the first connected npad id
- NpadIdType GetFirstNpadId() const;
-
- /// Returns the first disconnected npad id
- NpadIdType GetFirstDisconnectedNpadId() const;
-
- /// Sets the npad id of the last active controller
- void SetLastActiveController(NpadIdType npad_id);
-
- /// Returns the npad id of the last controller that pushed a button
- NpadIdType GetLastActiveController() const;
-
- /// Sets all emulated controllers into configuring mode.
- void EnableAllControllerConfiguration();
-
- /// Sets all emulated controllers into normal mode.
- void DisableAllControllerConfiguration();
-
- /// Reloads all input devices from settings
- void ReloadInputDevices();
-
- /// Removes all callbacks from input common
- void UnloadInputDevices();
-
- /// Number of emulated controllers
- static constexpr std::size_t available_controllers{10};
-
-private:
- std::unique_ptr<EmulatedController> player_1;
- std::unique_ptr<EmulatedController> player_2;
- std::unique_ptr<EmulatedController> player_3;
- std::unique_ptr<EmulatedController> player_4;
- std::unique_ptr<EmulatedController> player_5;
- std::unique_ptr<EmulatedController> player_6;
- std::unique_ptr<EmulatedController> player_7;
- std::unique_ptr<EmulatedController> player_8;
- std::unique_ptr<EmulatedController> other;
- std::unique_ptr<EmulatedController> handheld;
- std::unique_ptr<EmulatedConsole> console;
- std::unique_ptr<EmulatedDevices> devices;
- NpadStyleTag supported_style_tag{NpadStyleSet::All};
- NpadIdType last_active_controller{NpadIdType::Handheld};
-};
-
-} // namespace Core::HID
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
deleted file mode 100644
index 4bf285f36..000000000
--- a/src/core/hid/hid_types.h
+++ /dev/null
@@ -1,735 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "common/bit_field.h"
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "common/point.h"
-#include "common/uuid.h"
-#include "common/vector_math.h"
-
-namespace Core::HID {
-
-enum class DeviceIndex : u8 {
- Left = 0,
- Right = 1,
- None = 2,
- MaxDeviceIndex = 3,
-};
-
-// This is nn::hid::NpadButton
-enum class NpadButton : u64 {
- None = 0,
- A = 1U << 0,
- B = 1U << 1,
- X = 1U << 2,
- Y = 1U << 3,
- StickL = 1U << 4,
- StickR = 1U << 5,
- L = 1U << 6,
- R = 1U << 7,
- ZL = 1U << 8,
- ZR = 1U << 9,
- Plus = 1U << 10,
- Minus = 1U << 11,
-
- Left = 1U << 12,
- Up = 1U << 13,
- Right = 1U << 14,
- Down = 1U << 15,
-
- StickLLeft = 1U << 16,
- StickLUp = 1U << 17,
- StickLRight = 1U << 18,
- StickLDown = 1U << 19,
-
- StickRLeft = 1U << 20,
- StickRUp = 1U << 21,
- StickRRight = 1U << 22,
- StickRDown = 1U << 23,
-
- LeftSL = 1U << 24,
- LeftSR = 1U << 25,
-
- RightSL = 1U << 26,
- RightSR = 1U << 27,
-
- Palma = 1U << 28,
- Verification = 1U << 29,
- HandheldLeftB = 1U << 30,
- LagonCLeft = 1U << 31,
- LagonCUp = 1ULL << 32,
- LagonCRight = 1ULL << 33,
- LagonCDown = 1ULL << 34,
-
- All = 0xFFFFFFFFFFFFFFFFULL,
-};
-DECLARE_ENUM_FLAG_OPERATORS(NpadButton);
-
-enum class KeyboardKeyIndex : u32 {
- A = 4,
- B = 5,
- C = 6,
- D = 7,
- E = 8,
- F = 9,
- G = 10,
- H = 11,
- I = 12,
- J = 13,
- K = 14,
- L = 15,
- M = 16,
- N = 17,
- O = 18,
- P = 19,
- Q = 20,
- R = 21,
- S = 22,
- T = 23,
- U = 24,
- V = 25,
- W = 26,
- X = 27,
- Y = 28,
- Z = 29,
- D1 = 30,
- D2 = 31,
- D3 = 32,
- D4 = 33,
- D5 = 34,
- D6 = 35,
- D7 = 36,
- D8 = 37,
- D9 = 38,
- D0 = 39,
- Return = 40,
- Escape = 41,
- Backspace = 42,
- Tab = 43,
- Space = 44,
- Minus = 45,
- Plus = 46,
- OpenBracket = 47,
- CloseBracket = 48,
- Pipe = 49,
- Tilde = 50,
- Semicolon = 51,
- Quote = 52,
- Backquote = 53,
- Comma = 54,
- Period = 55,
- Slash = 56,
- CapsLock = 57,
- F1 = 58,
- F2 = 59,
- F3 = 60,
- F4 = 61,
- F5 = 62,
- F6 = 63,
- F7 = 64,
- F8 = 65,
- F9 = 66,
- F10 = 67,
- F11 = 68,
- F12 = 69,
- PrintScreen = 70,
- ScrollLock = 71,
- Pause = 72,
- Insert = 73,
- Home = 74,
- PageUp = 75,
- Delete = 76,
- End = 77,
- PageDown = 78,
- RightArrow = 79,
- LeftArrow = 80,
- DownArrow = 81,
- UpArrow = 82,
- NumLock = 83,
- NumPadDivide = 84,
- NumPadMultiply = 85,
- NumPadSubtract = 86,
- NumPadAdd = 87,
- NumPadEnter = 88,
- NumPad1 = 89,
- NumPad2 = 90,
- NumPad3 = 91,
- NumPad4 = 92,
- NumPad5 = 93,
- NumPad6 = 94,
- NumPad7 = 95,
- NumPad8 = 96,
- NumPad9 = 97,
- NumPad0 = 98,
- NumPadDot = 99,
- Backslash = 100,
- Application = 101,
- Power = 102,
- NumPadEquals = 103,
- F13 = 104,
- F14 = 105,
- F15 = 106,
- F16 = 107,
- F17 = 108,
- F18 = 109,
- F19 = 110,
- F20 = 111,
- F21 = 112,
- F22 = 113,
- F23 = 114,
- F24 = 115,
- NumPadComma = 133,
- Ro = 135,
- KatakanaHiragana = 136,
- Yen = 137,
- Henkan = 138,
- Muhenkan = 139,
- NumPadCommaPc98 = 140,
- HangulEnglish = 144,
- Hanja = 145,
- Katakana = 146,
- Hiragana = 147,
- ZenkakuHankaku = 148,
- LeftControl = 224,
- LeftShift = 225,
- LeftAlt = 226,
- LeftGui = 227,
- RightControl = 228,
- RightShift = 229,
- RightAlt = 230,
- RightGui = 231,
-};
-
-// This is nn::hid::NpadIdType
-enum class NpadIdType : u32 {
- Player1 = 0x0,
- Player2 = 0x1,
- Player3 = 0x2,
- Player4 = 0x3,
- Player5 = 0x4,
- Player6 = 0x5,
- Player7 = 0x6,
- Player8 = 0x7,
- Other = 0x10,
- Handheld = 0x20,
-
- Invalid = 0xFFFFFFFF,
-};
-
-enum class NpadInterfaceType : u8 {
- Bluetooth = 1,
- Rail = 2,
- Usb = 3,
- Embedded = 4,
-};
-
-// This is nn::hid::NpadStyleIndex
-enum class NpadStyleIndex : u8 {
- None = 0,
- ProController = 3,
- Handheld = 4,
- HandheldNES = 4,
- JoyconDual = 5,
- JoyconLeft = 6,
- JoyconRight = 7,
- GameCube = 8,
- Pokeball = 9,
- NES = 10,
- SNES = 12,
- N64 = 13,
- SegaGenesis = 14,
- SystemExt = 32,
- System = 33,
- MaxNpadType = 34,
-};
-
-// This is nn::hid::NpadStyleSet
-enum class NpadStyleSet : u32 {
- None = 0,
- Fullkey = 1U << 0,
- Handheld = 1U << 1,
- JoyDual = 1U << 2,
- JoyLeft = 1U << 3,
- JoyRight = 1U << 4,
- Gc = 1U << 5,
- Palma = 1U << 6,
- Lark = 1U << 7,
- HandheldLark = 1U << 8,
- Lucia = 1U << 9,
- Lagoon = 1U << 10,
- Lager = 1U << 11,
- SystemExt = 1U << 29,
- System = 1U << 30,
-
- All = 0xFFFFFFFFU,
-};
-static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
-
-// This is nn::hid::VibrationDevicePosition
-enum class VibrationDevicePosition : u32 {
- None = 0,
- Left = 1,
- Right = 2,
-};
-
-// This is nn::hid::VibrationDeviceType
-enum class VibrationDeviceType : u32 {
- Unknown = 0,
- LinearResonantActuator = 1,
- GcErm = 2,
- N64 = 3,
-};
-
-// This is nn::hid::VibrationGcErmCommand
-enum class VibrationGcErmCommand : u64 {
- Stop = 0,
- Start = 1,
- StopHard = 2,
-};
-
-// This is nn::hid::GyroscopeZeroDriftMode
-enum class GyroscopeZeroDriftMode : u32 {
- Loose = 0,
- Standard = 1,
- Tight = 2,
-};
-
-// This is nn::settings::system::TouchScreenMode
-enum class TouchScreenMode : u32 {
- Stylus = 0,
- Standard = 1,
-};
-
-// This is nn::hid::TouchScreenModeForNx
-enum class TouchScreenModeForNx : u8 {
- UseSystemSetting,
- Finger,
- Heat2,
-};
-
-// This is nn::hid::system::NpadBatteryLevel
-enum class NpadBatteryLevel : u32 {
- Empty,
- Critical,
- Low,
- High,
- Full,
-};
-
-// This is nn::hid::NpadStyleTag
-struct NpadStyleTag {
- union {
- NpadStyleSet raw{};
-
- BitField<0, 1, u32> fullkey;
- BitField<1, 1, u32> handheld;
- BitField<2, 1, u32> joycon_dual;
- BitField<3, 1, u32> joycon_left;
- BitField<4, 1, u32> joycon_right;
- BitField<5, 1, u32> gamecube;
- BitField<6, 1, u32> palma;
- BitField<7, 1, u32> lark;
- BitField<8, 1, u32> handheld_lark;
- BitField<9, 1, u32> lucia;
- BitField<10, 1, u32> lagoon;
- BitField<11, 1, u32> lager;
- BitField<29, 1, u32> system_ext;
- BitField<30, 1, u32> system;
- };
-};
-static_assert(sizeof(NpadStyleTag) == 4, "NpadStyleTag is an invalid size");
-
-// This is nn::hid::TouchAttribute
-struct TouchAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> start_touch;
- BitField<1, 1, u32> end_touch;
- };
-};
-static_assert(sizeof(TouchAttribute) == 0x4, "TouchAttribute is an invalid size");
-
-// This is nn::hid::TouchState
-struct TouchState {
- u64 delta_time{};
- TouchAttribute attribute{};
- u32 finger{};
- Common::Point<u32> position{};
- u32 diameter_x{};
- u32 diameter_y{};
- u32 rotation_angle{};
-};
-static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
-
-struct TouchFinger {
- u64 last_touch{};
- Common::Point<float> position{};
- u32 id{};
- TouchAttribute attribute{};
- bool pressed{};
-};
-
-// This is nn::hid::TouchScreenConfigurationForNx
-struct TouchScreenConfigurationForNx {
- TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting};
- INSERT_PADDING_BYTES(0xF);
-};
-static_assert(sizeof(TouchScreenConfigurationForNx) == 0x10,
- "TouchScreenConfigurationForNx is an invalid size");
-
-struct NpadColor {
- u8 r{};
- u8 g{};
- u8 b{};
- u8 a{};
-};
-static_assert(sizeof(NpadColor) == 4, "NpadColor is an invalid size");
-
-// This is nn::hid::NpadControllerColor
-struct NpadControllerColor {
- NpadColor body{};
- NpadColor button{};
-};
-static_assert(sizeof(NpadControllerColor) == 8, "NpadControllerColor is an invalid size");
-
-// This is nn::hid::AnalogStickState
-struct AnalogStickState {
- s32 x{};
- s32 y{};
-};
-static_assert(sizeof(AnalogStickState) == 8, "AnalogStickState is an invalid size");
-
-// This is nn::hid::server::NpadGcTriggerState
-struct NpadGcTriggerState {
- s64 sampling_number{};
- s32 left{};
- s32 right{};
-};
-static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
-
-// This is nn::hid::system::NpadPowerInfo
-struct NpadPowerInfo {
- bool is_powered{};
- bool is_charging{};
- INSERT_PADDING_BYTES(0x6);
- NpadBatteryLevel battery_level{NpadBatteryLevel::Full};
-};
-static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
-
-struct LedPattern {
- explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
- position1.Assign(light1);
- position2.Assign(light2);
- position3.Assign(light3);
- position4.Assign(light4);
- }
- union {
- u64 raw{};
- BitField<0, 1, u64> position1;
- BitField<1, 1, u64> position2;
- BitField<2, 1, u64> position3;
- BitField<3, 1, u64> position4;
- };
-};
-
-struct HomeButtonState {
- union {
- u64 raw{};
-
- // Buttons
- BitField<0, 1, u64> home;
- };
-};
-static_assert(sizeof(HomeButtonState) == 0x8, "HomeButtonState has incorrect size.");
-
-struct CaptureButtonState {
- union {
- u64 raw{};
-
- // Buttons
- BitField<0, 1, u64> capture;
- };
-};
-static_assert(sizeof(CaptureButtonState) == 0x8, "CaptureButtonState has incorrect size.");
-
-struct NpadButtonState {
- union {
- NpadButton raw{};
-
- // Buttons
- BitField<0, 1, u64> a;
- BitField<1, 1, u64> b;
- BitField<2, 1, u64> x;
- BitField<3, 1, u64> y;
- BitField<4, 1, u64> stick_l;
- BitField<5, 1, u64> stick_r;
- BitField<6, 1, u64> l;
- BitField<7, 1, u64> r;
- BitField<8, 1, u64> zl;
- BitField<9, 1, u64> zr;
- BitField<10, 1, u64> plus;
- BitField<11, 1, u64> minus;
-
- // D-Pad
- BitField<12, 1, u64> left;
- BitField<13, 1, u64> up;
- BitField<14, 1, u64> right;
- BitField<15, 1, u64> down;
-
- // Left JoyStick
- BitField<16, 1, u64> stick_l_left;
- BitField<17, 1, u64> stick_l_up;
- BitField<18, 1, u64> stick_l_right;
- BitField<19, 1, u64> stick_l_down;
-
- // Right JoyStick
- BitField<20, 1, u64> stick_r_left;
- BitField<21, 1, u64> stick_r_up;
- BitField<22, 1, u64> stick_r_right;
- BitField<23, 1, u64> stick_r_down;
-
- BitField<24, 1, u64> left_sl;
- BitField<25, 1, u64> left_sr;
-
- BitField<26, 1, u64> right_sl;
- BitField<27, 1, u64> right_sr;
-
- BitField<28, 1, u64> palma;
- BitField<29, 1, u64> verification;
- BitField<30, 1, u64> handheld_left_b;
- BitField<31, 1, u64> lagon_c_left;
- BitField<32, 1, u64> lagon_c_up;
- BitField<33, 1, u64> lagon_c_right;
- BitField<34, 1, u64> lagon_c_down;
- };
-};
-static_assert(sizeof(NpadButtonState) == 0x8, "NpadButtonState has incorrect size.");
-
-// This is nn::hid::DebugPadButton
-struct DebugPadButton {
- union {
- u32 raw{};
- BitField<0, 1, u32> a;
- BitField<1, 1, u32> b;
- BitField<2, 1, u32> x;
- BitField<3, 1, u32> y;
- BitField<4, 1, u32> l;
- BitField<5, 1, u32> r;
- BitField<6, 1, u32> zl;
- BitField<7, 1, u32> zr;
- BitField<8, 1, u32> plus;
- BitField<9, 1, u32> minus;
- BitField<10, 1, u32> d_left;
- BitField<11, 1, u32> d_up;
- BitField<12, 1, u32> d_right;
- BitField<13, 1, u32> d_down;
- };
-};
-static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size");
-
-// This is nn::hid::ConsoleSixAxisSensorHandle
-struct ConsoleSixAxisSensorHandle {
- u8 unknown_1{};
- u8 unknown_2{};
- INSERT_PADDING_BYTES_NOINIT(2);
-};
-static_assert(sizeof(ConsoleSixAxisSensorHandle) == 4,
- "ConsoleSixAxisSensorHandle is an invalid size");
-
-// This is nn::hid::SixAxisSensorHandle
-struct SixAxisSensorHandle {
- NpadStyleIndex npad_type{NpadStyleIndex::None};
- u8 npad_id{};
- DeviceIndex device_index{DeviceIndex::None};
- INSERT_PADDING_BYTES_NOINIT(1);
-};
-static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an invalid size");
-
-// These parameters seem related to how much gyro/accelerometer is used
-struct SixAxisSensorFusionParameters {
- f32 parameter1{0.03f}; // Range 0.0 to 1.0, default 0.03
- f32 parameter2{0.4f}; // Default 0.4
-};
-static_assert(sizeof(SixAxisSensorFusionParameters) == 8,
- "SixAxisSensorFusionParameters is an invalid size");
-
-// This is nn::hid::server::SixAxisSensorProperties
-struct SixAxisSensorProperties {
- union {
- u8 raw{};
- BitField<0, 1, u8> is_newly_assigned;
- BitField<1, 1, u8> is_firmware_update_available;
- };
-};
-static_assert(sizeof(SixAxisSensorProperties) == 1, "SixAxisSensorProperties is an invalid size");
-
-// This is nn::hid::SixAxisSensorCalibrationParameter
-struct SixAxisSensorCalibrationParameter {
- std::array<u8, 0x744> unknown_data{};
-};
-static_assert(sizeof(SixAxisSensorCalibrationParameter) == 0x744,
- "SixAxisSensorCalibrationParameter is an invalid size");
-
-// This is nn::hid::SixAxisSensorIcInformation
-struct SixAxisSensorIcInformation {
- f32 angular_rate{2000.0f}; // dps
- std::array<f32, 6> unknown_gyro_data1{
- -10.0f, -10.0f, -10.0f, 10.0f, 10.0f, 10.0f,
- }; // dps
- std::array<f32, 9> unknown_gyro_data2{
- 0.95f, -0.003f, -0.003f, -0.003f, 0.95f, -0.003f, -0.003f, -0.003f, 0.95f,
- };
- std::array<f32, 9> unknown_gyro_data3{
- 1.05f, 0.003f, 0.003f, 0.003f, 1.05f, 0.003f, 0.003f, 0.003f, 1.05f,
- };
- f32 acceleration_range{8.0f}; // g force
- std::array<f32, 6> unknown_accel_data1{
- -0.0612f, -0.0612f, -0.0612f, 0.0612f, 0.0612f, 0.0612f,
- }; // g force
- std::array<f32, 9> unknown_accel_data2{
- 0.95f, -0.003f, -0.003f, -0.003f, 0.95f, -0.003f, -0.003f, -0.003f, 0.95f,
- };
- std::array<f32, 9> unknown_accel_data3{
- 1.05f, 0.003f, 0.003f, 0.003f, 1.05f, 0.003f, 0.003f, 0.003f, 1.05f,
- };
-};
-static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
- "SixAxisSensorIcInformation is an invalid size");
-
-// This is nn::hid::SixAxisSensorAttribute
-struct SixAxisSensorAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> is_connected;
- BitField<1, 1, u32> is_interpolated;
- };
-};
-static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
-
-// This is nn::hid::SixAxisSensorState
-struct SixAxisSensorState {
- s64 delta_time{};
- s64 sampling_number{};
- Common::Vec3f accel{};
- Common::Vec3f gyro{};
- Common::Vec3f rotation{};
- std::array<Common::Vec3f, 3> orientation{};
- SixAxisSensorAttribute attribute{};
- INSERT_PADDING_BYTES(4); // Reserved
-};
-static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
-
-// This is nn::hid::VibrationDeviceHandle
-struct VibrationDeviceHandle {
- NpadStyleIndex npad_type{NpadStyleIndex::None};
- u8 npad_id{};
- DeviceIndex device_index{DeviceIndex::None};
- INSERT_PADDING_BYTES_NOINIT(1);
-};
-static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size");
-
-// This is nn::hid::VibrationValue
-struct VibrationValue {
- f32 low_amplitude{};
- f32 low_frequency{};
- f32 high_amplitude{};
- f32 high_frequency{};
-};
-static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
-
-constexpr VibrationValue DEFAULT_VIBRATION_VALUE{
- .low_amplitude = 0.0f,
- .low_frequency = 160.0f,
- .high_amplitude = 0.0f,
- .high_frequency = 320.0f,
-};
-
-// This is nn::hid::VibrationDeviceInfo
-struct VibrationDeviceInfo {
- VibrationDeviceType type{};
- VibrationDevicePosition position{};
-};
-static_assert(sizeof(VibrationDeviceInfo) == 0x8, "VibrationDeviceInfo has incorrect size.");
-
-// This is nn::hid::KeyboardModifier
-struct KeyboardModifier {
- union {
- u32 raw{};
- BitField<0, 1, u32> control;
- BitField<1, 1, u32> shift;
- BitField<2, 1, u32> left_alt;
- BitField<3, 1, u32> right_alt;
- BitField<4, 1, u32> gui;
- BitField<8, 1, u32> caps_lock;
- BitField<9, 1, u32> scroll_lock;
- BitField<10, 1, u32> num_lock;
- BitField<11, 1, u32> katakana;
- BitField<12, 1, u32> hiragana;
- };
-};
-
-static_assert(sizeof(KeyboardModifier) == 0x4, "KeyboardModifier is an invalid size");
-
-// This is nn::hid::KeyboardAttribute
-struct KeyboardAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> is_connected;
- };
-};
-static_assert(sizeof(KeyboardAttribute) == 0x4, "KeyboardAttribute is an invalid size");
-
-// This is nn::hid::KeyboardKey
-struct KeyboardKey {
- // This should be a 256 bit flag
- std::array<u8, 32> key{};
-};
-static_assert(sizeof(KeyboardKey) == 0x20, "KeyboardKey is an invalid size");
-
-// This is nn::hid::MouseButton
-struct MouseButton {
- union {
- u32_le raw{};
- BitField<0, 1, u32> left;
- BitField<1, 1, u32> right;
- BitField<2, 1, u32> middle;
- BitField<3, 1, u32> forward;
- BitField<4, 1, u32> back;
- };
-};
-static_assert(sizeof(MouseButton) == 0x4, "MouseButton is an invalid size");
-
-// This is nn::hid::MouseAttribute
-struct MouseAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> transferable;
- BitField<1, 1, u32> is_connected;
- };
-};
-static_assert(sizeof(MouseAttribute) == 0x4, "MouseAttribute is an invalid size");
-
-// This is nn::hid::detail::MouseState
-struct MouseState {
- s64 sampling_number{};
- s32 x{};
- s32 y{};
- s32 delta_x{};
- s32 delta_y{};
- // Axis Order in HW is switched for the wheel
- s32 delta_wheel_y{};
- s32 delta_wheel_x{};
- MouseButton button{};
- MouseAttribute attribute{};
-};
-static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
-
-struct UniquePadId {
- u64 id;
-};
-static_assert(sizeof(UniquePadId) == 0x8, "UniquePadId is an invalid size");
-
-} // namespace Core::HID
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
deleted file mode 100644
index a05716fd8..000000000
--- a/src/core/hid/input_converter.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <algorithm>
-#include <random>
-
-#include "common/input.h"
-#include "core/hid/input_converter.h"
-
-namespace Core::HID {
-
-Common::Input::BatteryStatus TransformToBattery(const Common::Input::CallbackStatus& callback) {
- Common::Input::BatteryStatus battery{Common::Input::BatteryStatus::None};
- switch (callback.type) {
- case Common::Input::InputType::Analog:
- case Common::Input::InputType::Trigger: {
- const auto value = TransformToTrigger(callback).analog.value;
- battery = Common::Input::BatteryLevel::Empty;
- if (value > 0.2f) {
- battery = Common::Input::BatteryLevel::Critical;
- }
- if (value > 0.4f) {
- battery = Common::Input::BatteryLevel::Low;
- }
- if (value > 0.6f) {
- battery = Common::Input::BatteryLevel::Medium;
- }
- if (value > 0.8f) {
- battery = Common::Input::BatteryLevel::Full;
- }
- if (value >= 0.95f) {
- battery = Common::Input::BatteryLevel::Charging;
- }
- break;
- }
- case Common::Input::InputType::Button:
- battery = callback.button_status.value ? Common::Input::BatteryLevel::Charging
- : Common::Input::BatteryLevel::Critical;
- break;
- case Common::Input::InputType::Battery:
- battery = callback.battery_status;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to battery not implemented", callback.type);
- break;
- }
-
- return battery;
-}
-
-Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatus& callback) {
- Common::Input::ButtonStatus status{};
- switch (callback.type) {
- case Common::Input::InputType::Analog:
- status.value = TransformToTrigger(callback).pressed.value;
- status.toggle = callback.analog_status.properties.toggle;
- status.inverted = callback.analog_status.properties.inverted_button;
- break;
- case Common::Input::InputType::Trigger:
- status.value = TransformToTrigger(callback).pressed.value;
- break;
- case Common::Input::InputType::Button:
- status = callback.button_status;
- break;
- case Common::Input::InputType::Motion:
- status.value = std::abs(callback.motion_status.gyro.x.raw_value) > 1.0f;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to button not implemented", callback.type);
- break;
- }
-
- if (status.inverted) {
- status.value = !status.value;
- }
-
- return status;
-}
-
-Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatus& callback) {
- Common::Input::MotionStatus status{};
- switch (callback.type) {
- case Common::Input::InputType::Button: {
- Common::Input::AnalogProperties properties{
- .deadzone = 0.0f,
- .range = 1.0f,
- .offset = 0.0f,
- };
- status.delta_timestamp = 1000;
- status.force_update = true;
- status.accel.x = {
- .value = 0.0f,
- .raw_value = 0.0f,
- .properties = properties,
- };
- status.accel.y = {
- .value = 0.0f,
- .raw_value = 0.0f,
- .properties = properties,
- };
- status.accel.z = {
- .value = 0.0f,
- .raw_value = -1.0f,
- .properties = properties,
- };
- status.gyro.x = {
- .value = 0.0f,
- .raw_value = 0.0f,
- .properties = properties,
- };
- status.gyro.y = {
- .value = 0.0f,
- .raw_value = 0.0f,
- .properties = properties,
- };
- status.gyro.z = {
- .value = 0.0f,
- .raw_value = 0.0f,
- .properties = properties,
- };
- if (TransformToButton(callback).value) {
- std::random_device device;
- std::mt19937 gen(device());
- std::uniform_int_distribution<s16> distribution(-5000, 5000);
- status.accel.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
- status.accel.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
- status.accel.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
- status.gyro.x.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
- status.gyro.y.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
- status.gyro.z.raw_value = static_cast<f32>(distribution(gen)) * 0.001f;
- }
- break;
- }
- case Common::Input::InputType::Motion:
- status = callback.motion_status;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to motion not implemented", callback.type);
- break;
- }
- SanitizeAnalog(status.accel.x, false);
- SanitizeAnalog(status.accel.y, false);
- SanitizeAnalog(status.accel.z, false);
- SanitizeAnalog(status.gyro.x, false);
- SanitizeAnalog(status.gyro.y, false);
- SanitizeAnalog(status.gyro.z, false);
-
- return status;
-}
-
-Common::Input::StickStatus TransformToStick(const Common::Input::CallbackStatus& callback) {
- Common::Input::StickStatus status{};
-
- switch (callback.type) {
- case Common::Input::InputType::Stick:
- status = callback.stick_status;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to stick not implemented", callback.type);
- break;
- }
-
- SanitizeStick(status.x, status.y, true);
- const auto& properties_x = status.x.properties;
- const auto& properties_y = status.y.properties;
- const float x = status.x.value;
- const float y = status.y.value;
-
- // Set directional buttons
- status.right = x > properties_x.threshold;
- status.left = x < -properties_x.threshold;
- status.up = y > properties_y.threshold;
- status.down = y < -properties_y.threshold;
-
- return status;
-}
-
-Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus& callback) {
- Common::Input::TouchStatus status{};
-
- switch (callback.type) {
- case Common::Input::InputType::Touch:
- status = callback.touch_status;
- break;
- case Common::Input::InputType::Stick:
- status.x = callback.stick_status.x;
- status.y = callback.stick_status.y;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to touch not implemented", callback.type);
- break;
- }
-
- SanitizeAnalog(status.x, true);
- SanitizeAnalog(status.y, true);
- float& x = status.x.value;
- float& y = status.y.value;
-
- // Adjust if value is inverted
- x = status.x.properties.inverted ? 1.0f + x : x;
- y = status.y.properties.inverted ? 1.0f + y : y;
-
- // clamp value
- x = std::clamp(x, 0.0f, 1.0f);
- y = std::clamp(y, 0.0f, 1.0f);
-
- if (status.pressed.inverted) {
- status.pressed.value = !status.pressed.value;
- }
-
- return status;
-}
-
-Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackStatus& callback) {
- Common::Input::TriggerStatus status{};
- float& raw_value = status.analog.raw_value;
- bool calculate_button_value = true;
-
- switch (callback.type) {
- case Common::Input::InputType::Analog:
- status.analog.properties = callback.analog_status.properties;
- raw_value = callback.analog_status.raw_value;
- break;
- case Common::Input::InputType::Button:
- status.analog.properties.range = 1.0f;
- status.analog.properties.inverted = callback.button_status.inverted;
- raw_value = callback.button_status.value ? 1.0f : 0.0f;
- break;
- case Common::Input::InputType::Trigger:
- status = callback.trigger_status;
- calculate_button_value = false;
- break;
- case Common::Input::InputType::Motion:
- status.analog.properties.range = 1.0f;
- raw_value = callback.motion_status.accel.x.raw_value;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to trigger not implemented", callback.type);
- break;
- }
-
- SanitizeAnalog(status.analog, true);
- const auto& properties = status.analog.properties;
- float& value = status.analog.value;
-
- // Set button status
- if (calculate_button_value) {
- status.pressed.value = value > properties.threshold;
- }
-
- // Adjust if value is inverted
- value = properties.inverted ? 1.0f + value : value;
-
- // clamp value
- value = std::clamp(value, 0.0f, 1.0f);
-
- return status;
-}
-
-Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback) {
- Common::Input::AnalogStatus status{};
-
- switch (callback.type) {
- case Common::Input::InputType::Analog:
- status.properties = callback.analog_status.properties;
- status.raw_value = callback.analog_status.raw_value;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to analog not implemented", callback.type);
- break;
- }
-
- SanitizeAnalog(status, false);
-
- // Adjust if value is inverted
- status.value = status.properties.inverted ? -status.value : status.value;
-
- return status;
-}
-
-Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatus& callback) {
- Common::Input::CameraStatus camera{};
- switch (callback.type) {
- case Common::Input::InputType::IrSensor:
- camera = {
- .format = callback.camera_status,
- .data = callback.raw_data,
- };
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to camera not implemented", callback.type);
- break;
- }
-
- return camera;
-}
-
-Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback) {
- Common::Input::NfcStatus nfc{};
- switch (callback.type) {
- case Common::Input::InputType::Nfc:
- return callback.nfc_status;
- default:
- LOG_ERROR(Input, "Conversion from type {} to NFC not implemented", callback.type);
- break;
- }
-
- return nfc;
-}
-
-Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback) {
- switch (callback.type) {
- case Common::Input::InputType::Color:
- return callback.color_status;
- break;
- default:
- LOG_ERROR(Input, "Conversion from type {} to color not implemented", callback.type);
- return {};
- break;
- }
-}
-
-void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
- const auto& properties = analog.properties;
- float& raw_value = analog.raw_value;
- float& value = analog.value;
-
- if (!std::isnormal(raw_value)) {
- raw_value = 0;
- }
-
- // Apply center offset
- raw_value -= properties.offset;
-
- // Set initial values to be formatted
- value = raw_value;
-
- // Calculate vector size
- const float r = std::abs(value);
-
- // Return zero if value is smaller than the deadzone
- if (r <= properties.deadzone || properties.deadzone == 1.0f) {
- analog.value = 0;
- return;
- }
-
- // Adjust range of value
- const float deadzone_factor =
- 1.0f / r * (r - properties.deadzone) / (1.0f - properties.deadzone);
- value = value * deadzone_factor / properties.range;
-
- // Invert direction if needed
- if (properties.inverted) {
- value = -value;
- }
-
- // Clamp value
- if (clamp_value) {
- value = std::clamp(value, -1.0f, 1.0f);
- }
-}
-
-void SanitizeStick(Common::Input::AnalogStatus& analog_x, Common::Input::AnalogStatus& analog_y,
- bool clamp_value) {
- const auto& properties_x = analog_x.properties;
- const auto& properties_y = analog_y.properties;
- float& raw_x = analog_x.raw_value;
- float& raw_y = analog_y.raw_value;
- float& x = analog_x.value;
- float& y = analog_y.value;
-
- if (!std::isnormal(raw_x)) {
- raw_x = 0;
- }
- if (!std::isnormal(raw_y)) {
- raw_y = 0;
- }
-
- // Apply center offset
- raw_x += properties_x.offset;
- raw_y += properties_y.offset;
-
- // Apply X scale correction from offset
- if (std::abs(properties_x.offset) < 0.75f) {
- if (raw_x > 0) {
- raw_x /= 1 + properties_x.offset;
- } else {
- raw_x /= 1 - properties_x.offset;
- }
- }
-
- // Apply Y scale correction from offset
- if (std::abs(properties_y.offset) < 0.75f) {
- if (raw_y > 0) {
- raw_y /= 1 + properties_y.offset;
- } else {
- raw_y /= 1 - properties_y.offset;
- }
- }
-
- // Invert direction if needed
- raw_x = properties_x.inverted ? -raw_x : raw_x;
- raw_y = properties_y.inverted ? -raw_y : raw_y;
-
- // Set initial values to be formatted
- x = raw_x;
- y = raw_y;
-
- // Calculate vector size
- float r = x * x + y * y;
- r = std::sqrt(r);
-
- // TODO(German77): Use deadzone and range of both axis
-
- // Return zero if values are smaller than the deadzone
- if (r <= properties_x.deadzone || properties_x.deadzone >= 1.0f) {
- x = 0;
- y = 0;
- return;
- }
-
- // Adjust range of joystick
- const float deadzone_factor =
- 1.0f / r * (r - properties_x.deadzone) / (1.0f - properties_x.deadzone);
- x = x * deadzone_factor / properties_x.range;
- y = y * deadzone_factor / properties_x.range;
- r = r * deadzone_factor / properties_x.range;
-
- // Normalize joystick
- if (clamp_value && r > 1.0f) {
- x /= r;
- y /= r;
- }
-}
-
-} // namespace Core::HID
diff --git a/src/core/hid/input_converter.h b/src/core/hid/input_converter.h
deleted file mode 100644
index c51c03e57..000000000
--- a/src/core/hid/input_converter.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-namespace Common::Input {
-struct CallbackStatus;
-enum class BatteryLevel : u32;
-using BatteryStatus = BatteryLevel;
-struct AnalogStatus;
-struct ButtonStatus;
-struct MotionStatus;
-struct StickStatus;
-struct TouchStatus;
-struct TriggerStatus;
-}; // namespace Common::Input
-
-namespace Core::HID {
-
-/**
- * Converts raw input data into a valid battery status.
- *
- * @param callback Supported callbacks: Analog, Battery, Trigger.
- * @return A valid BatteryStatus object.
- */
-Common::Input::BatteryStatus TransformToBattery(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid button status. Applies invert properties to the output.
- *
- * @param callback Supported callbacks: Analog, Button, Trigger.
- * @return A valid TouchStatus object.
- */
-Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid motion status.
- *
- * @param callback Supported callbacks: Motion.
- * @return A valid TouchStatus object.
- */
-Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid stick status. Applies offset, deadzone, range and invert
- * properties to the output.
- *
- * @param callback Supported callbacks: Stick.
- * @return A valid StickStatus object.
- */
-Common::Input::StickStatus TransformToStick(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid touch status.
- *
- * @param callback Supported callbacks: Touch.
- * @return A valid TouchStatus object.
- */
-Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid trigger status. Applies offset, deadzone, range and
- * invert properties to the output. Button status uses the threshold property if necessary.
- *
- * @param callback Supported callbacks: Analog, Button, Trigger.
- * @return A valid TriggerStatus object.
- */
-Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid analog status. Applies offset, deadzone, range and
- * invert properties to the output.
- *
- * @param callback Supported callbacks: Analog.
- * @return A valid AnalogStatus object.
- */
-Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid camera status.
- *
- * @param callback Supported callbacks: Camera.
- * @return A valid CameraObject object.
- */
-Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid nfc status.
- *
- * @param callback Supported callbacks: Nfc.
- * @return A valid data tag vector.
- */
-Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw input data into a valid color status.
- *
- * @param callback Supported callbacks: Color.
- * @return A valid Color object.
- */
-Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback);
-
-/**
- * Converts raw analog data into a valid analog value
- * @param analog An analog object containing raw data and properties
- * @param clamp_value determines if the value needs to be clamped between -1.0f and 1.0f.
- */
-void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value);
-
-/**
- * Converts raw stick data into a valid stick value
- * @param analog_x raw analog data and properties for the x-axis
- * @param analog_y raw analog data and properties for the y-axis
- * @param clamp_value bool that determines if the value needs to be clamped into the unit circle.
- */
-void SanitizeStick(Common::Input::AnalogStatus& analog_x, Common::Input::AnalogStatus& analog_y,
- bool clamp_value);
-
-} // namespace Core::HID
diff --git a/src/core/hid/input_interpreter.cpp b/src/core/hid/input_interpreter.cpp
deleted file mode 100644
index 072f38a68..000000000
--- a/src/core/hid/input_interpreter.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core.h"
-#include "core/hid/hid_types.h"
-#include "core/hid/input_interpreter.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/hid_server.h"
-#include "core/hle/service/hid/resource_manager.h"
-#include "core/hle/service/sm/sm.h"
-
-InputInterpreter::InputInterpreter(Core::System& system)
- : npad{system.ServiceManager()
- .GetService<Service::HID::IHidServer>("hid")
- ->GetResourceManager()
- ->GetNpad()} {
- ResetButtonStates();
-}
-
-InputInterpreter::~InputInterpreter() = default;
-
-void InputInterpreter::PollInput() {
- if (npad == nullptr) {
- return;
- }
- const auto button_state = npad->GetAndResetPressState();
-
- previous_index = current_index;
- current_index = (current_index + 1) % button_states.size();
-
- button_states[current_index] = button_state;
-}
-
-void InputInterpreter::ResetButtonStates() {
- previous_index = 0;
- current_index = 0;
-
- button_states[0] = Core::HID::NpadButton::All;
-
- for (std::size_t i = 1; i < button_states.size(); ++i) {
- button_states[i] = Core::HID::NpadButton::None;
- }
-}
-
-bool InputInterpreter::IsButtonPressed(Core::HID::NpadButton button) const {
- return True(button_states[current_index] & button);
-}
-
-bool InputInterpreter::IsButtonPressedOnce(Core::HID::NpadButton button) const {
- const bool current_press = True(button_states[current_index] & button);
- const bool previous_press = True(button_states[previous_index] & button);
-
- return current_press && !previous_press;
-}
-
-bool InputInterpreter::IsButtonHeld(Core::HID::NpadButton button) const {
- Core::HID::NpadButton held_buttons{button_states[0]};
-
- for (std::size_t i = 1; i < button_states.size(); ++i) {
- held_buttons &= button_states[i];
- }
-
- return True(held_buttons & button);
-}
diff --git a/src/core/hid/input_interpreter.h b/src/core/hid/input_interpreter.h
deleted file mode 100644
index 3569aac93..000000000
--- a/src/core/hid/input_interpreter.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-
-#include "common/common_types.h"
-
-namespace Core {
-class System;
-}
-
-namespace Core::HID {
-enum class NpadButton : u64;
-}
-
-namespace Service::HID {
-class NPad;
-}
-
-/**
- * The InputInterpreter class interfaces with HID to retrieve button press states.
- * Input is intended to be polled every 50ms so that a button is considered to be
- * held down after 400ms has elapsed since the initial button press and subsequent
- * repeated presses occur every 50ms.
- */
-class InputInterpreter {
-public:
- explicit InputInterpreter(Core::System& system);
- virtual ~InputInterpreter();
-
- /// Gets a button state from HID and inserts it into the array of button states.
- void PollInput();
-
- /// Resets all the button states to their defaults.
- void ResetButtonStates();
-
- /**
- * Checks whether the button is pressed.
- *
- * @param button The button to check.
- *
- * @returns True when the button is pressed.
- */
- [[nodiscard]] bool IsButtonPressed(Core::HID::NpadButton button) const;
-
- /**
- * Checks whether any of the buttons in the parameter list is pressed.
- *
- * @tparam HIDButton The buttons to check.
- *
- * @returns True when at least one of the buttons is pressed.
- */
- template <Core::HID::NpadButton... T>
- [[nodiscard]] bool IsAnyButtonPressed() {
- return (IsButtonPressed(T) || ...);
- }
-
- /**
- * The specified button is considered to be pressed once
- * if it is currently pressed and not pressed previously.
- *
- * @param button The button to check.
- *
- * @returns True when the button is pressed once.
- */
- [[nodiscard]] bool IsButtonPressedOnce(Core::HID::NpadButton button) const;
-
- /**
- * Checks whether any of the buttons in the parameter list is pressed once.
- *
- * @tparam T The buttons to check.
- *
- * @returns True when at least one of the buttons is pressed once.
- */
- template <Core::HID::NpadButton... T>
- [[nodiscard]] bool IsAnyButtonPressedOnce() const {
- return (IsButtonPressedOnce(T) || ...);
- }
-
- /**
- * The specified button is considered to be held down if it is pressed in all 9 button states.
- *
- * @param button The button to check.
- *
- * @returns True when the button is held down.
- */
- [[nodiscard]] bool IsButtonHeld(Core::HID::NpadButton button) const;
-
- /**
- * Checks whether any of the buttons in the parameter list is held down.
- *
- * @tparam T The buttons to check.
- *
- * @returns True when at least one of the buttons is held down.
- */
- template <Core::HID::NpadButton... T>
- [[nodiscard]] bool IsAnyButtonHeld() const {
- return (IsButtonHeld(T) || ...);
- }
-
-private:
- std::shared_ptr<Service::HID::NPad> npad;
-
- /// Stores 9 consecutive button states polled from HID.
- std::array<Core::HID::NpadButton, 9> button_states{};
-
- std::size_t previous_index{};
- std::size_t current_index{};
-};
diff --git a/src/core/hid/irs_types.h b/src/core/hid/irs_types.h
deleted file mode 100644
index 0d1bfe53f..000000000
--- a/src/core/hid/irs_types.h
+++ /dev/null
@@ -1,301 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "core/hid/hid_types.h"
-
-namespace Core::IrSensor {
-
-// This is nn::irsensor::CameraAmbientNoiseLevel
-enum class CameraAmbientNoiseLevel : u32 {
- Low,
- Medium,
- High,
- Unknown3, // This level can't be reached
-};
-
-// This is nn::irsensor::CameraLightTarget
-enum class CameraLightTarget : u32 {
- AllLeds,
- BrightLeds,
- DimLeds,
- None,
-};
-
-// This is nn::irsensor::PackedCameraLightTarget
-enum class PackedCameraLightTarget : u8 {
- AllLeds,
- BrightLeds,
- DimLeds,
- None,
-};
-
-// This is nn::irsensor::AdaptiveClusteringMode
-enum class AdaptiveClusteringMode : u32 {
- StaticFov,
- DynamicFov,
-};
-
-// This is nn::irsensor::AdaptiveClusteringTargetDistance
-enum class AdaptiveClusteringTargetDistance : u32 {
- Near,
- Middle,
- Far,
-};
-
-// This is nn::irsensor::ImageTransferProcessorFormat
-enum class ImageTransferProcessorFormat : u32 {
- Size320x240,
- Size160x120,
- Size80x60,
- Size40x30,
- Size20x15,
-};
-
-// This is nn::irsensor::PackedImageTransferProcessorFormat
-enum class PackedImageTransferProcessorFormat : u8 {
- Size320x240,
- Size160x120,
- Size80x60,
- Size40x30,
- Size20x15,
-};
-
-// This is nn::irsensor::IrCameraStatus
-enum class IrCameraStatus : u32 {
- Available,
- Unsupported,
- Unconnected,
-};
-
-// This is nn::irsensor::IrCameraInternalStatus
-enum class IrCameraInternalStatus : u32 {
- Stopped,
- FirmwareUpdateNeeded,
- Unknown2,
- Unknown3,
- Unknown4,
- FirmwareVersionRequested,
- FirmwareVersionIsInvalid,
- Ready,
- Setting,
-};
-
-// This is nn::irsensor::detail::StatusManager::IrSensorMode
-enum class IrSensorMode : u64 {
- None,
- MomentProcessor,
- ClusteringProcessor,
- ImageTransferProcessor,
- PointingProcessorMarker,
- TeraPluginProcessor,
- IrLedProcessor,
-};
-
-// This is nn::irsensor::ImageProcessorStatus
-enum ImageProcessorStatus : u32 {
- Stopped,
- Running,
-};
-
-// This is nn::irsensor::HandAnalysisMode
-enum class HandAnalysisMode : u32 {
- None,
- Silhouette,
- Image,
- SilhoueteAndImage,
- SilhuetteOnly,
-};
-
-// This is nn::irsensor::IrSensorFunctionLevel
-enum class IrSensorFunctionLevel : u8 {
- unknown0,
- unknown1,
- unknown2,
- unknown3,
- unknown4,
-};
-
-// This is nn::irsensor::MomentProcessorPreprocess
-enum class MomentProcessorPreprocess : u32 {
- Unknown0,
- Unknown1,
-};
-
-// This is nn::irsensor::PackedMomentProcessorPreprocess
-enum class PackedMomentProcessorPreprocess : u8 {
- Unknown0,
- Unknown1,
-};
-
-// This is nn::irsensor::PointingStatus
-enum class PointingStatus : u32 {
- Unknown0,
- Unknown1,
-};
-
-struct IrsRect {
- s16 x;
- s16 y;
- s16 width;
- s16 height;
-};
-
-struct IrsCentroid {
- f32 x;
- f32 y;
-};
-
-struct CameraConfig {
- u64 exposure_time;
- CameraLightTarget light_target;
- u32 gain;
- bool is_negative_used;
- INSERT_PADDING_BYTES(7);
-};
-static_assert(sizeof(CameraConfig) == 0x18, "CameraConfig is an invalid size");
-
-struct PackedCameraConfig {
- u64 exposure_time;
- PackedCameraLightTarget light_target;
- u8 gain;
- bool is_negative_used;
- INSERT_PADDING_BYTES(5);
-};
-static_assert(sizeof(PackedCameraConfig) == 0x10, "PackedCameraConfig is an invalid size");
-
-// This is nn::irsensor::IrCameraHandle
-struct IrCameraHandle {
- u8 npad_id{};
- Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None};
- INSERT_PADDING_BYTES(2);
-};
-static_assert(sizeof(IrCameraHandle) == 4, "IrCameraHandle is an invalid size");
-
-// This is nn::irsensor::PackedMcuVersion
-struct PackedMcuVersion {
- u16 major;
- u16 minor;
-};
-static_assert(sizeof(PackedMcuVersion) == 4, "PackedMcuVersion is an invalid size");
-
-// This is nn::irsensor::PackedMomentProcessorConfig
-struct PackedMomentProcessorConfig {
- PackedCameraConfig camera_config;
- IrsRect window_of_interest;
- PackedMcuVersion required_mcu_version;
- PackedMomentProcessorPreprocess preprocess;
- u8 preprocess_intensity_threshold;
- INSERT_PADDING_BYTES(2);
-};
-static_assert(sizeof(PackedMomentProcessorConfig) == 0x20,
- "PackedMomentProcessorConfig is an invalid size");
-
-// This is nn::irsensor::PackedClusteringProcessorConfig
-struct PackedClusteringProcessorConfig {
- PackedCameraConfig camera_config;
- IrsRect window_of_interest;
- PackedMcuVersion required_mcu_version;
- u32 pixel_count_min;
- u32 pixel_count_max;
- u8 object_intensity_min;
- bool is_external_light_filter_enabled;
- INSERT_PADDING_BYTES(2);
-};
-static_assert(sizeof(PackedClusteringProcessorConfig) == 0x28,
- "PackedClusteringProcessorConfig is an invalid size");
-
-// This is nn::irsensor::PackedImageTransferProcessorConfig
-struct PackedImageTransferProcessorConfig {
- PackedCameraConfig camera_config;
- PackedMcuVersion required_mcu_version;
- PackedImageTransferProcessorFormat format;
- INSERT_PADDING_BYTES(3);
-};
-static_assert(sizeof(PackedImageTransferProcessorConfig) == 0x18,
- "PackedImageTransferProcessorConfig is an invalid size");
-
-// This is nn::irsensor::PackedTeraPluginProcessorConfig
-struct PackedTeraPluginProcessorConfig {
- PackedMcuVersion required_mcu_version;
- u8 mode;
- u8 unknown_1;
- u8 unknown_2;
- u8 unknown_3;
-};
-static_assert(sizeof(PackedTeraPluginProcessorConfig) == 0x8,
- "PackedTeraPluginProcessorConfig is an invalid size");
-
-// This is nn::irsensor::PackedPointingProcessorConfig
-struct PackedPointingProcessorConfig {
- IrsRect window_of_interest;
- PackedMcuVersion required_mcu_version;
-};
-static_assert(sizeof(PackedPointingProcessorConfig) == 0xC,
- "PackedPointingProcessorConfig is an invalid size");
-
-// This is nn::irsensor::PackedFunctionLevel
-struct PackedFunctionLevel {
- IrSensorFunctionLevel function_level;
- INSERT_PADDING_BYTES(3);
-};
-static_assert(sizeof(PackedFunctionLevel) == 0x4, "PackedFunctionLevel is an invalid size");
-
-// This is nn::irsensor::PackedImageTransferProcessorExConfig
-struct PackedImageTransferProcessorExConfig {
- PackedCameraConfig camera_config;
- PackedMcuVersion required_mcu_version;
- PackedImageTransferProcessorFormat origin_format;
- PackedImageTransferProcessorFormat trimming_format;
- u16 trimming_start_x;
- u16 trimming_start_y;
- bool is_external_light_filter_enabled;
- INSERT_PADDING_BYTES(5);
-};
-static_assert(sizeof(PackedImageTransferProcessorExConfig) == 0x20,
- "PackedImageTransferProcessorExConfig is an invalid size");
-
-// This is nn::irsensor::PackedIrLedProcessorConfig
-struct PackedIrLedProcessorConfig {
- PackedMcuVersion required_mcu_version;
- u8 light_target;
- INSERT_PADDING_BYTES(3);
-};
-static_assert(sizeof(PackedIrLedProcessorConfig) == 0x8,
- "PackedIrLedProcessorConfig is an invalid size");
-
-// This is nn::irsensor::HandAnalysisConfig
-struct HandAnalysisConfig {
- HandAnalysisMode mode;
-};
-static_assert(sizeof(HandAnalysisConfig) == 0x4, "HandAnalysisConfig is an invalid size");
-
-// This is nn::irsensor::detail::ProcessorState contents are different for each processor
-struct ProcessorState {
- std::array<u8, 0xE20> processor_raw_data{};
-};
-static_assert(sizeof(ProcessorState) == 0xE20, "ProcessorState is an invalid size");
-
-// This is nn::irsensor::detail::DeviceFormat
-struct DeviceFormat {
- Core::IrSensor::IrCameraStatus camera_status{Core::IrSensor::IrCameraStatus::Unconnected};
- Core::IrSensor::IrCameraInternalStatus camera_internal_status{
- Core::IrSensor::IrCameraInternalStatus::Ready};
- Core::IrSensor::IrSensorMode mode{Core::IrSensor::IrSensorMode::None};
- ProcessorState state{};
-};
-static_assert(sizeof(DeviceFormat) == 0xE30, "DeviceFormat is an invalid size");
-
-// This is nn::irsensor::ImageTransferProcessorState
-struct ImageTransferProcessorState {
- u64 sampling_number;
- Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
- INSERT_PADDING_BYTES(4);
-};
-static_assert(sizeof(ImageTransferProcessorState) == 0x10,
- "ImageTransferProcessorState is an invalid size");
-
-} // namespace Core::IrSensor
diff --git a/src/core/hid/motion_input.cpp b/src/core/hid/motion_input.cpp
deleted file mode 100644
index f56f2ae1d..000000000
--- a/src/core/hid/motion_input.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <cmath>
-
-#include "common/math_util.h"
-#include "core/hid/motion_input.h"
-
-namespace Core::HID {
-
-MotionInput::MotionInput() {
- // Initialize PID constants with default values
- SetPID(0.3f, 0.005f, 0.0f);
- SetGyroThreshold(ThresholdStandard);
- ResetQuaternion();
- ResetRotations();
-}
-
-void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
- kp = new_kp;
- ki = new_ki;
- kd = new_kd;
-}
-
-void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
- accel = acceleration;
-
- accel.x = std::clamp(accel.x, -AccelMaxValue, AccelMaxValue);
- accel.y = std::clamp(accel.y, -AccelMaxValue, AccelMaxValue);
- accel.z = std::clamp(accel.z, -AccelMaxValue, AccelMaxValue);
-}
-
-void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
- gyro = gyroscope - gyro_bias;
-
- gyro.x = std::clamp(gyro.x, -GyroMaxValue, GyroMaxValue);
- gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
- gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue);
-
- // Auto adjust gyro_bias to minimize drift
- if (!IsMoving(IsAtRestRelaxed)) {
- gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
- }
-
- // Adjust drift when calibration mode is enabled
- if (calibration_mode) {
- gyro_bias = (gyro_bias * 0.99f) + (gyroscope * 0.01f);
- StopCalibration();
- }
-
- if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
- gyro = {};
- } else {
- only_accelerometer = false;
- }
-}
-
-void MotionInput::SetQuaternion(const Common::Quaternion<f32>& quaternion) {
- quat = quaternion;
-}
-
-void MotionInput::SetEulerAngles(const Common::Vec3f& euler_angles) {
- const float cr = std::cos(euler_angles.x * 0.5f);
- const float sr = std::sin(euler_angles.x * 0.5f);
- const float cp = std::cos(euler_angles.y * 0.5f);
- const float sp = std::sin(euler_angles.y * 0.5f);
- const float cy = std::cos(euler_angles.z * 0.5f);
- const float sy = std::sin(euler_angles.z * 0.5f);
-
- quat.w = cr * cp * cy + sr * sp * sy;
- quat.xyz.x = sr * cp * cy - cr * sp * sy;
- quat.xyz.y = cr * sp * cy + sr * cp * sy;
- quat.xyz.z = cr * cp * sy - sr * sp * cy;
-}
-
-void MotionInput::SetGyroBias(const Common::Vec3f& bias) {
- gyro_bias = bias;
-}
-
-void MotionInput::SetGyroThreshold(f32 threshold) {
- gyro_threshold = threshold;
-}
-
-void MotionInput::SetUserGyroThreshold(f32 threshold) {
- user_gyro_threshold = threshold / ThresholdStandard;
-}
-
-void MotionInput::EnableReset(bool reset) {
- reset_enabled = reset;
-}
-
-void MotionInput::ResetRotations() {
- rotations = {};
-}
-
-void MotionInput::ResetQuaternion() {
- quat = {{0.0f, 0.0f, -1.0f}, 0.0f};
-}
-
-bool MotionInput::IsMoving(f32 sensitivity) const {
- return gyro.Length() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f;
-}
-
-bool MotionInput::IsCalibrated(f32 sensitivity) const {
- return real_error.Length() < sensitivity;
-}
-
-void MotionInput::UpdateRotation(u64 elapsed_time) {
- const auto sample_period = static_cast<f32>(elapsed_time) / 1000000.0f;
- if (sample_period > 0.1f) {
- return;
- }
- rotations += gyro * sample_period;
-}
-
-void MotionInput::Calibrate() {
- calibration_mode = true;
- calibration_counter = 0;
-}
-
-void MotionInput::StopCalibration() {
- if (calibration_counter++ > CalibrationSamples) {
- calibration_mode = false;
- ResetQuaternion();
- ResetRotations();
- }
-}
-
-// Based on Madgwick's implementation of Mayhony's AHRS algorithm.
-// https://github.com/xioTechnologies/Open-Source-AHRS-With-x-IMU/blob/master/x-IMU%20IMU%20and%20AHRS%20Algorithms/x-IMU%20IMU%20and%20AHRS%20Algorithms/AHRS/MahonyAHRS.cs
-void MotionInput::UpdateOrientation(u64 elapsed_time) {
- if (!IsCalibrated(0.1f)) {
- ResetOrientation();
- }
- // Short name local variable for readability
- f32 q1 = quat.w;
- f32 q2 = quat.xyz[0];
- f32 q3 = quat.xyz[1];
- f32 q4 = quat.xyz[2];
- const auto sample_period = static_cast<f32>(elapsed_time) / 1000000.0f;
-
- // Ignore invalid elapsed time
- if (sample_period > 0.1f) {
- return;
- }
-
- const auto normal_accel = accel.Normalized();
- auto rad_gyro = gyro * Common::PI * 2;
- const f32 swap = rad_gyro.x;
- rad_gyro.x = rad_gyro.y;
- rad_gyro.y = -swap;
- rad_gyro.z = -rad_gyro.z;
-
- // Clear gyro values if there is no gyro present
- if (only_accelerometer) {
- rad_gyro.x = 0;
- rad_gyro.y = 0;
- rad_gyro.z = 0;
- }
-
- // Ignore drift correction if acceleration is not reliable
- if (accel.Length() >= 0.75f && accel.Length() <= 1.25f) {
- const f32 ax = -normal_accel.x;
- const f32 ay = normal_accel.y;
- const f32 az = -normal_accel.z;
-
- // Estimated direction of gravity
- const f32 vx = 2.0f * (q2 * q4 - q1 * q3);
- const f32 vy = 2.0f * (q1 * q2 + q3 * q4);
- const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4;
-
- // Error is cross product between estimated direction and measured direction of gravity
- const Common::Vec3f new_real_error = {
- az * vx - ax * vz,
- ay * vz - az * vy,
- ax * vy - ay * vx,
- };
-
- derivative_error = new_real_error - real_error;
- real_error = new_real_error;
-
- // Prevent integral windup
- if (ki != 0.0f && !IsCalibrated(0.05f)) {
- integral_error += real_error;
- } else {
- integral_error = {};
- }
-
- // Apply feedback terms
- if (!only_accelerometer) {
- rad_gyro += kp * real_error;
- rad_gyro += ki * integral_error;
- rad_gyro += kd * derivative_error;
- } else {
- // Give more weight to accelerometer values to compensate for the lack of gyro
- rad_gyro += 35.0f * kp * real_error;
- rad_gyro += 10.0f * ki * integral_error;
- rad_gyro += 10.0f * kd * derivative_error;
-
- // Emulate gyro values for games that need them
- gyro.x = -rad_gyro.y;
- gyro.y = rad_gyro.x;
- gyro.z = -rad_gyro.z;
- UpdateRotation(elapsed_time);
- }
- }
-
- const f32 gx = rad_gyro.y;
- const f32 gy = rad_gyro.x;
- const f32 gz = rad_gyro.z;
-
- // Integrate rate of change of quaternion
- const f32 pa = q2;
- const f32 pb = q3;
- const f32 pc = q4;
- q1 = q1 + (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * sample_period);
- q2 = pa + (q1 * gx + pb * gz - pc * gy) * (0.5f * sample_period);
- q3 = pb + (q1 * gy - pa * gz + pc * gx) * (0.5f * sample_period);
- q4 = pc + (q1 * gz + pa * gy - pb * gx) * (0.5f * sample_period);
-
- quat.w = q1;
- quat.xyz[0] = q2;
- quat.xyz[1] = q3;
- quat.xyz[2] = q4;
- quat = quat.Normalized();
-}
-
-std::array<Common::Vec3f, 3> MotionInput::GetOrientation() const {
- const Common::Quaternion<float> quad{
- .xyz = {-quat.xyz[1], -quat.xyz[0], -quat.w},
- .w = -quat.xyz[2],
- };
- const std::array<float, 16> matrix4x4 = quad.ToMatrix();
-
- return {Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]),
- Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]),
- Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10])};
-}
-
-Common::Vec3f MotionInput::GetAcceleration() const {
- return accel;
-}
-
-Common::Vec3f MotionInput::GetGyroscope() const {
- return gyro;
-}
-
-Common::Vec3f MotionInput::GetGyroBias() const {
- return gyro_bias;
-}
-
-Common::Quaternion<f32> MotionInput::GetQuaternion() const {
- return quat;
-}
-
-Common::Vec3f MotionInput::GetRotations() const {
- return rotations;
-}
-
-Common::Vec3f MotionInput::GetEulerAngles() const {
- // roll (x-axis rotation)
- const float sinr_cosp = 2 * (quat.w * quat.xyz.x + quat.xyz.y * quat.xyz.z);
- const float cosr_cosp = 1 - 2 * (quat.xyz.x * quat.xyz.x + quat.xyz.y * quat.xyz.y);
-
- // pitch (y-axis rotation)
- const float sinp = std::sqrt(1 + 2 * (quat.w * quat.xyz.y - quat.xyz.x * quat.xyz.z));
- const float cosp = std::sqrt(1 - 2 * (quat.w * quat.xyz.y - quat.xyz.x * quat.xyz.z));
-
- // yaw (z-axis rotation)
- const float siny_cosp = 2 * (quat.w * quat.xyz.z + quat.xyz.x * quat.xyz.y);
- const float cosy_cosp = 1 - 2 * (quat.xyz.y * quat.xyz.y + quat.xyz.z * quat.xyz.z);
-
- return {
- std::atan2(sinr_cosp, cosr_cosp),
- 2 * std::atan2(sinp, cosp) - Common::PI / 2,
- std::atan2(siny_cosp, cosy_cosp),
- };
-}
-
-void MotionInput::ResetOrientation() {
- if (!reset_enabled || only_accelerometer) {
- return;
- }
- if (!IsMoving(IsAtRestRelaxed) && accel.z <= -0.9f) {
- ++reset_counter;
- if (reset_counter > 900) {
- quat.w = 0;
- quat.xyz[0] = 0;
- quat.xyz[1] = 0;
- quat.xyz[2] = -1;
- SetOrientationFromAccelerometer();
- integral_error = {};
- reset_counter = 0;
- }
- } else {
- reset_counter = 0;
- }
-}
-
-void MotionInput::SetOrientationFromAccelerometer() {
- int iterations = 0;
- const f32 sample_period = 0.015f;
-
- const auto normal_accel = accel.Normalized();
-
- while (!IsCalibrated(0.01f) && ++iterations < 100) {
- // Short name local variable for readability
- f32 q1 = quat.w;
- f32 q2 = quat.xyz[0];
- f32 q3 = quat.xyz[1];
- f32 q4 = quat.xyz[2];
-
- Common::Vec3f rad_gyro;
- const f32 ax = -normal_accel.x;
- const f32 ay = normal_accel.y;
- const f32 az = -normal_accel.z;
-
- // Estimated direction of gravity
- const f32 vx = 2.0f * (q2 * q4 - q1 * q3);
- const f32 vy = 2.0f * (q1 * q2 + q3 * q4);
- const f32 vz = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4;
-
- // Error is cross product between estimated direction and measured direction of gravity
- const Common::Vec3f new_real_error = {
- az * vx - ax * vz,
- ay * vz - az * vy,
- ax * vy - ay * vx,
- };
-
- derivative_error = new_real_error - real_error;
- real_error = new_real_error;
-
- rad_gyro += 10.0f * kp * real_error;
- rad_gyro += 5.0f * ki * integral_error;
- rad_gyro += 10.0f * kd * derivative_error;
-
- const f32 gx = rad_gyro.y;
- const f32 gy = rad_gyro.x;
- const f32 gz = rad_gyro.z;
-
- // Integrate rate of change of quaternion
- const f32 pa = q2;
- const f32 pb = q3;
- const f32 pc = q4;
- q1 = q1 + (-q2 * gx - q3 * gy - q4 * gz) * (0.5f * sample_period);
- q2 = pa + (q1 * gx + pb * gz - pc * gy) * (0.5f * sample_period);
- q3 = pb + (q1 * gy - pa * gz + pc * gx) * (0.5f * sample_period);
- q4 = pc + (q1 * gz + pa * gy - pb * gx) * (0.5f * sample_period);
-
- quat.w = q1;
- quat.xyz[0] = q2;
- quat.xyz[1] = q3;
- quat.xyz[2] = q4;
- quat = quat.Normalized();
- }
-}
-} // namespace Core::HID
diff --git a/src/core/hid/motion_input.h b/src/core/hid/motion_input.h
deleted file mode 100644
index 11678983d..000000000
--- a/src/core/hid/motion_input.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "common/quaternion.h"
-#include "common/vector_math.h"
-
-namespace Core::HID {
-
-class MotionInput {
-public:
- static constexpr float ThresholdLoose = 0.01f;
- static constexpr float ThresholdStandard = 0.007f;
- static constexpr float ThresholdThight = 0.002f;
-
- static constexpr float IsAtRestRelaxed = 0.05f;
- static constexpr float IsAtRestLoose = 0.02f;
- static constexpr float IsAtRestStandard = 0.01f;
- static constexpr float IsAtRestThight = 0.005f;
-
- static constexpr float GyroMaxValue = 5.0f;
- static constexpr float AccelMaxValue = 7.0f;
-
- static constexpr std::size_t CalibrationSamples = 300;
-
- explicit MotionInput();
-
- MotionInput(const MotionInput&) = default;
- MotionInput& operator=(const MotionInput&) = default;
-
- MotionInput(MotionInput&&) = default;
- MotionInput& operator=(MotionInput&&) = default;
-
- void SetPID(f32 new_kp, f32 new_ki, f32 new_kd);
- void SetAcceleration(const Common::Vec3f& acceleration);
- void SetGyroscope(const Common::Vec3f& gyroscope);
- void SetQuaternion(const Common::Quaternion<f32>& quaternion);
- void SetEulerAngles(const Common::Vec3f& euler_angles);
- void SetGyroBias(const Common::Vec3f& bias);
- void SetGyroThreshold(f32 threshold);
-
- /// Applies a modifier on top of the normal gyro threshold
- void SetUserGyroThreshold(f32 threshold);
-
- void EnableReset(bool reset);
- void ResetRotations();
- void ResetQuaternion();
-
- void UpdateRotation(u64 elapsed_time);
- void UpdateOrientation(u64 elapsed_time);
-
- void Calibrate();
-
- [[nodiscard]] std::array<Common::Vec3f, 3> GetOrientation() const;
- [[nodiscard]] Common::Vec3f GetAcceleration() const;
- [[nodiscard]] Common::Vec3f GetGyroscope() const;
- [[nodiscard]] Common::Vec3f GetGyroBias() const;
- [[nodiscard]] Common::Vec3f GetRotations() const;
- [[nodiscard]] Common::Quaternion<f32> GetQuaternion() const;
- [[nodiscard]] Common::Vec3f GetEulerAngles() const;
-
- [[nodiscard]] bool IsMoving(f32 sensitivity) const;
- [[nodiscard]] bool IsCalibrated(f32 sensitivity) const;
-
-private:
- void StopCalibration();
- void ResetOrientation();
- void SetOrientationFromAccelerometer();
-
- // PID constants
- f32 kp;
- f32 ki;
- f32 kd;
-
- // PID errors
- Common::Vec3f real_error;
- Common::Vec3f integral_error;
- Common::Vec3f derivative_error;
-
- // Quaternion containing the device orientation
- Common::Quaternion<f32> quat;
-
- // Number of full rotations in each axis
- Common::Vec3f rotations;
-
- // Acceleration vector measurement in G force
- Common::Vec3f accel;
-
- // Gyroscope vector measurement in radians/s.
- Common::Vec3f gyro;
-
- // Vector to be subtracted from gyro measurements
- Common::Vec3f gyro_bias;
-
- // Minimum gyro amplitude to detect if the device is moving
- f32 gyro_threshold = 0.0f;
-
- // Multiplies gyro_threshold by this value
- f32 user_gyro_threshold = 0.0f;
-
- // Number of invalid sequential data
- u32 reset_counter = 0;
-
- // If the provided data is invalid the device will be autocalibrated
- bool reset_enabled = true;
-
- // Use accelerometer values to calculate position
- bool only_accelerometer = true;
-
- // When enabled it will aggressively adjust for gyro drift
- bool calibration_mode = false;
-
- // Used to auto disable calibration mode
- std::size_t calibration_counter = 0;
-};
-
-} // namespace Core::HID
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 24394d222..7d3421929 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -1258,11 +1258,11 @@ ThreadState KThread::RequestTerminate() {
// Change the thread's priority to be higher than any system thread's.
this->IncreaseBasePriority(TerminatingThreadPriority);
- // If the thread is runnable, send a termination interrupt to other cores.
+ // If the thread is runnable, send a termination interrupt to cores it may be running on.
if (this->GetState() == ThreadState::Runnable) {
- if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask() &
- ~(1ULL << GetCurrentCoreId(m_kernel));
- core_mask != 0) {
+ // NOTE: We do not mask the "current core", because this code may not actually be
+ // executing from the thread representing the "current core".
+ if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask(); core_mask != 0) {
Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask);
}
}
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 97eb56ff0..9e05bdafa 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -13,7 +13,6 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/savedata_factory.h"
-#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
@@ -37,7 +36,6 @@
#include "core/hle/service/caps/caps_su.h"
#include "core/hle/service/caps/caps_types.h"
#include "core/hle/service/filesystem/filesystem.h"
-#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
@@ -48,6 +46,8 @@
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_results.h"
#include "core/memory.h"
+#include "hid_core/hid_types.h"
+#include "hid_core/resources/npad/npad.h"
namespace Service::AM {
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
index 3906c0fa4..c2ff444a6 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.cpp
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -5,13 +5,13 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/frontend/applets/cabinet.h"
-#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/applet_cabinet.h"
#include "core/hle/service/mii/mii_manager.h"
#include "core/hle/service/nfc/common/device.h"
+#include "hid_core/hid_core.h"
namespace Service::AM::Applets {
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index 9840d2547..0e4d9cc39 100644
--- a/src/core/hle/service/am/applets/applet_controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -9,13 +9,13 @@
#include "common/string_util.h"
#include "core/core.h"
#include "core/frontend/applets/controller.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hid/hid_types.h"
#include "core/hle/result.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/applet_controller.h"
-#include "core/hle/service/hid/controllers/npad.h"
+#include "hid_core/frontend/emulated_controller.h"
+#include "hid_core/hid_core.h"
+#include "hid_core/hid_types.h"
+#include "hid_core/resources/npad/npad.h"
namespace Service::AM::Applets {
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp
deleted file mode 100644
index b4ff663c2..000000000
--- a/src/core/hle/service/hid/controllers/applet_resource.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/core.h"
-#include "core/hle/kernel/k_shared_memory.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-#include "core/hle/service/hid/errors.h"
-
-namespace Service::HID {
-
-AppletResource::AppletResource(Core::System& system_) : system{system_} {}
-
-AppletResource::~AppletResource() = default;
-
-Result AppletResource::CreateAppletResource(u64 aruid) {
- const u64 index = GetIndexFromAruid(aruid);
-
- if (index >= AruidIndexMax) {
- return ResultAruidNotRegistered;
- }
-
- if (data[index].flag.is_assigned) {
- return ResultAruidAlreadyRegistered;
- }
-
- auto& shared_memory = shared_memory_holder[index];
- if (!shared_memory.IsMapped()) {
- const Result result = shared_memory.Initialize(system);
- if (result.IsError()) {
- return result;
- }
- if (shared_memory.GetAddress() == nullptr) {
- shared_memory.Finalize();
- return ResultSharedMemoryNotInitialized;
- }
- }
-
- auto* shared_memory_format = shared_memory.GetAddress();
- if (shared_memory_format != nullptr) {
- shared_memory_format->Initialize();
- }
-
- data[index].shared_memory_format = shared_memory_format;
- data[index].flag.is_assigned.Assign(true);
- // TODO: InitializeSixAxisControllerConfig(false);
- active_aruid = aruid;
- return ResultSuccess;
-}
-
-Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input) {
- const u64 index = GetIndexFromAruid(aruid);
-
- if (index < AruidIndexMax) {
- return ResultAruidAlreadyRegistered;
- }
-
- std::size_t data_index = AruidIndexMax;
- for (std::size_t i = 0; i < AruidIndexMax; i++) {
- if (!data[i].flag.is_initialized) {
- data_index = i;
- break;
- }
- }
-
- if (data_index == AruidIndexMax) {
- return ResultAruidNoAvailableEntries;
- }
-
- AruidData& aruid_data = data[data_index];
-
- aruid_data.aruid = aruid;
- aruid_data.flag.is_initialized.Assign(true);
- if (enable_input) {
- aruid_data.flag.enable_pad_input.Assign(true);
- aruid_data.flag.enable_six_axis_sensor.Assign(true);
- aruid_data.flag.bit_18.Assign(true);
- aruid_data.flag.enable_touchscreen.Assign(true);
- }
-
- data_index = AruidIndexMax;
- for (std::size_t i = 0; i < AruidIndexMax; i++) {
- if (registration_list.flag[i] == RegistrationStatus::Initialized) {
- if (registration_list.aruid[i] != aruid) {
- continue;
- }
- data_index = i;
- break;
- }
- if (registration_list.flag[i] == RegistrationStatus::None) {
- data_index = i;
- break;
- }
- }
-
- if (data_index == AruidIndexMax) {
- return ResultSuccess;
- }
-
- registration_list.flag[data_index] = RegistrationStatus::Initialized;
- registration_list.aruid[data_index] = aruid;
-
- return ResultSuccess;
-}
-
-void AppletResource::UnregisterAppletResourceUserId(u64 aruid) {
- u64 index = GetIndexFromAruid(aruid);
-
- if (index < AruidIndexMax) {
- if (data[index].flag.is_assigned) {
- data[index].shared_memory_format = nullptr;
- data[index].flag.is_assigned.Assign(false);
- }
- }
-
- index = GetIndexFromAruid(aruid);
- if (index < AruidIndexMax) {
- DestroySevenSixAxisTransferMemory();
- data[index].flag.raw = 0;
- data[index].aruid = 0;
-
- index = GetIndexFromAruid(aruid);
- if (index < AruidIndexMax) {
- registration_list.flag[index] = RegistrationStatus::PendingDelete;
- }
- }
-}
-
-void AppletResource::FreeAppletResourceId(u64 aruid) {
- u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- auto& aruid_data = data[index];
- if (aruid_data.flag.is_assigned) {
- aruid_data.shared_memory_format = nullptr;
- aruid_data.flag.is_assigned.Assign(false);
- }
-}
-
-u64 AppletResource::GetActiveAruid() {
- return active_aruid;
-}
-
-Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
- u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return ResultAruidNotRegistered;
- }
-
- *out_handle = shared_memory_holder[index].GetHandle();
- return ResultSuccess;
-}
-
-Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format,
- u64 aruid) {
- u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return ResultAruidNotRegistered;
- }
-
- *out_shared_memory_format = data[index].shared_memory_format;
- return ResultSuccess;
-}
-
-AruidData* AppletResource::GetAruidData(u64 aruid) {
- const u64 aruid_index = GetIndexFromAruid(aruid);
- if (aruid_index == AruidIndexMax) {
- return nullptr;
- }
- return &data[aruid_index];
-}
-
-AruidData* AppletResource::GetAruidDataByIndex(std::size_t aruid_index) {
- return &data[aruid_index];
-}
-
-bool AppletResource::IsVibrationAruidActive(u64 aruid) const {
- return aruid == 0 || aruid == active_vibration_aruid;
-}
-
-u64 AppletResource::GetIndexFromAruid(u64 aruid) {
- for (std::size_t i = 0; i < AruidIndexMax; i++) {
- if (registration_list.flag[i] == RegistrationStatus::Initialized &&
- registration_list.aruid[i] == aruid) {
- return i;
- }
- }
- return AruidIndexMax;
-}
-
-Result AppletResource::DestroySevenSixAxisTransferMemory() {
- // TODO
- return ResultSuccess;
-}
-
-void AppletResource::EnableInput(u64 aruid, bool is_enabled) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- data[index].flag.enable_pad_input.Assign(is_enabled);
- data[index].flag.enable_touchscreen.Assign(is_enabled);
-}
-
-void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- data[index].flag.enable_six_axis_sensor.Assign(is_enabled);
-}
-
-void AppletResource::EnablePadInput(u64 aruid, bool is_enabled) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- data[index].flag.enable_pad_input.Assign(is_enabled);
-}
-
-void AppletResource::EnableTouchScreen(u64 aruid, bool is_enabled) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- data[index].flag.enable_touchscreen.Assign(is_enabled);
-}
-
-void AppletResource::SetIsPalmaConnectable(u64 aruid, bool is_connectable) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- data[index].flag.is_palma_connectable.Assign(is_connectable);
-}
-
-void AppletResource::EnablePalmaBoostMode(u64 aruid, bool is_enabled) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
-
- data[index].flag.enable_palma_boost_mode.Assign(is_enabled);
-}
-
-Result AppletResource::RegisterCoreAppletResource() {
- if (ref_counter == std::numeric_limits<s32>::max() - 1) {
- return ResultAppletResourceOverflow;
- }
- if (ref_counter == 0) {
- const u64 index = GetIndexFromAruid(0);
- if (index < AruidIndexMax) {
- return ResultAruidAlreadyRegistered;
- }
-
- std::size_t data_index = AruidIndexMax;
- for (std::size_t i = 0; i < AruidIndexMax; i++) {
- if (!data[i].flag.is_initialized) {
- data_index = i;
- break;
- }
- }
-
- if (data_index == AruidIndexMax) {
- return ResultAruidNoAvailableEntries;
- }
-
- AruidData& aruid_data = data[data_index];
-
- aruid_data.aruid = 0;
- aruid_data.flag.is_initialized.Assign(true);
- aruid_data.flag.enable_pad_input.Assign(true);
- aruid_data.flag.enable_six_axis_sensor.Assign(true);
- aruid_data.flag.bit_18.Assign(true);
- aruid_data.flag.enable_touchscreen.Assign(true);
-
- data_index = AruidIndexMax;
- for (std::size_t i = 0; i < AruidIndexMax; i++) {
- if (registration_list.flag[i] == RegistrationStatus::Initialized) {
- if (registration_list.aruid[i] != 0) {
- continue;
- }
- data_index = i;
- break;
- }
- if (registration_list.flag[i] == RegistrationStatus::None) {
- data_index = i;
- break;
- }
- }
-
- Result result = ResultSuccess;
-
- if (data_index == AruidIndexMax) {
- result = CreateAppletResource(0);
- } else {
- registration_list.flag[data_index] = RegistrationStatus::Initialized;
- registration_list.aruid[data_index] = 0;
- }
-
- if (result.IsError()) {
- UnregisterAppletResourceUserId(0);
- return result;
- }
- }
- ref_counter++;
- return ResultSuccess;
-}
-
-Result AppletResource::UnregisterCoreAppletResource() {
- if (ref_counter == 0) {
- return ResultAppletResourceNotInitialized;
- }
-
- if (--ref_counter == 0) {
- UnregisterAppletResourceUserId(0);
- }
-
- return ResultSuccess;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h
deleted file mode 100644
index 52cc4cf42..000000000
--- a/src/core/hle/service/hid/controllers/applet_resource.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <array>
-#include <mutex>
-
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "core/hle/result.h"
-#include "core/hle/service/hid/controllers/shared_memory_holder.h"
-
-namespace Core {
-class System;
-}
-
-namespace Kernel {
-class KSharedMemory;
-}
-
-namespace Service::HID {
-struct SharedMemoryFormat;
-class AppletResource;
-class NPadResource;
-
-static constexpr std::size_t AruidIndexMax = 0x20;
-
-enum class RegistrationStatus : u32 {
- None,
- Initialized,
- PendingDelete,
-};
-
-struct DataStatusFlag {
- union {
- u32 raw{};
-
- BitField<0, 1, u32> is_initialized;
- BitField<1, 1, u32> is_assigned;
- BitField<16, 1, u32> enable_pad_input;
- BitField<17, 1, u32> enable_six_axis_sensor;
- BitField<18, 1, u32> bit_18;
- BitField<19, 1, u32> is_palma_connectable;
- BitField<20, 1, u32> enable_palma_boost_mode;
- BitField<21, 1, u32> enable_touchscreen;
- };
-};
-
-struct AruidRegisterList {
- std::array<RegistrationStatus, AruidIndexMax> flag{};
- std::array<u64, AruidIndexMax> aruid{};
-};
-static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
-
-struct AruidData {
- DataStatusFlag flag{};
- u64 aruid{};
- SharedMemoryFormat* shared_memory_format{nullptr};
-};
-
-struct HandheldConfig {
- bool is_handheld_hid_enabled;
- bool is_force_handheld;
- bool is_joycon_rail_enabled;
- bool is_force_handheld_style_vibration;
-};
-static_assert(sizeof(HandheldConfig) == 0x4, "HandheldConfig is an invalid size");
-
-struct AppletResourceHolder {
- std::shared_ptr<AppletResource> applet_resource{nullptr};
- std::recursive_mutex* shared_mutex{nullptr};
- NPadResource* shared_npad_resource{nullptr};
- std::shared_ptr<HandheldConfig> handheld_config{nullptr};
- long* handle_1;
-};
-
-class AppletResource {
-public:
- explicit AppletResource(Core::System& system_);
- ~AppletResource();
-
- Result CreateAppletResource(u64 aruid);
-
- Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
- void UnregisterAppletResourceUserId(u64 aruid);
-
- void FreeAppletResourceId(u64 aruid);
-
- u64 GetActiveAruid();
- Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
- Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
- AruidData* GetAruidData(u64 aruid);
- AruidData* GetAruidDataByIndex(std::size_t aruid_index);
-
- bool IsVibrationAruidActive(u64 aruid) const;
-
- u64 GetIndexFromAruid(u64 aruid);
-
- Result DestroySevenSixAxisTransferMemory();
-
- void EnableInput(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);
- void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
- void EnablePalmaBoostMode(u64 aruid, bool is_enabled);
-
- Result RegisterCoreAppletResource();
- Result UnregisterCoreAppletResource();
-
-private:
- u64 active_aruid{};
- AruidRegisterList registration_list{};
- std::array<AruidData, AruidIndexMax> data{};
- std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{};
- s32 ref_counter{};
- u64 active_vibration_aruid;
-
- Core::System& system;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/capture_button.cpp b/src/core/hle/service/hid/controllers/capture_button.cpp
deleted file mode 100644
index 8b486fcb5..000000000
--- a/src/core/hle/service/hid/controllers/capture_button.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/capture_button.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-CaptureButton::CaptureButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
-
-CaptureButton::~CaptureButton() = default;
-
-void CaptureButton::OnInit() {}
-
-void CaptureButton::OnRelease() {}
-
-void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- auto& header = data->shared_memory_format->capture_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/capture_button.h b/src/core/hle/service/hid/controllers/capture_button.h
deleted file mode 100644
index dcc4715c5..000000000
--- a/src/core/hle/service/hid/controllers/capture_button.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Service::HID {
-
-class CaptureButton final : public ControllerBase {
-public:
- explicit CaptureButton(Core::HID::HIDCore& hid_core_);
- ~CaptureButton() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- bool smart_update{};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp
deleted file mode 100644
index 8eba2c292..000000000
--- a/src/core/hle/service/hid/controllers/console_six_axis.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hid/emulated_console.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/console_six_axis.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
- console = hid_core.GetEmulatedConsole();
-}
-
-ConsoleSixAxis::~ConsoleSixAxis() = default;
-
-void ConsoleSixAxis::OnInit() {}
-
-void ConsoleSixAxis::OnRelease() {}
-
-void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- ConsoleSixAxisSensorSharedMemoryFormat& shared_memory = data->shared_memory_format->console;
-
- if (!IsControllerActivated()) {
- return;
- }
-
- const auto motion_status = console->GetMotion();
-
- shared_memory.sampling_number++;
- shared_memory.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
- shared_memory.verticalization_error = motion_status.verticalization_error;
- shared_memory.gyro_bias = motion_status.gyro_bias;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h
deleted file mode 100644
index e3351f83c..000000000
--- a/src/core/hle/service/hid/controllers/console_six_axis.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Core::HID {
-class EmulatedConsole;
-} // namespace Core::HID
-
-namespace Service::HID {
-class ConsoleSixAxis final : public ControllerBase {
-public:
- explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_);
- ~ConsoleSixAxis() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- Core::HID::EmulatedConsole* console = nullptr;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp
deleted file mode 100644
index 2083ccfad..000000000
--- a/src/core/hle/service/hid/controllers/controller_base.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Service::HID {
-
-ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {}
-ControllerBase::~ControllerBase() = default;
-
-Result ControllerBase::Activate() {
- if (is_activated) {
- return ResultSuccess;
- }
- is_activated = true;
- OnInit();
- return ResultSuccess;
-}
-
-Result ControllerBase::Activate(u64 aruid) {
- return Activate();
-}
-
-void ControllerBase::DeactivateController() {
- if (is_activated) {
- OnRelease();
- }
- is_activated = false;
-}
-
-bool ControllerBase::IsControllerActivated() const {
- return is_activated;
-}
-
-void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource) {
- applet_resource = resource;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
deleted file mode 100644
index 759ae0053..000000000
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <memory>
-
-#include "common/common_types.h"
-#include "core/hle/result.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-
-namespace Core::Timing {
-class CoreTiming;
-}
-
-namespace Core::HID {
-class HIDCore;
-} // namespace Core::HID
-
-namespace Service::HID {
-class ControllerBase {
-public:
- explicit ControllerBase(Core::HID::HIDCore& hid_core_);
- virtual ~ControllerBase();
-
- // Called when the controller is initialized
- virtual void OnInit() = 0;
-
- // When the controller is released
- virtual void OnRelease() = 0;
-
- // When the controller is requesting an update for the shared memory
- virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing) = 0;
-
- // When the controller is requesting a motion update for the shared memory
- virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
-
- Result Activate();
- Result Activate(u64 aruid);
-
- void DeactivateController();
-
- bool IsControllerActivated() const;
-
- void SetAppletResource(std::shared_ptr<AppletResource> resource);
-
-protected:
- bool is_activated{false};
- std::shared_ptr<AppletResource> applet_resource{nullptr};
-
- Core::HID::HIDCore& hid_core;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_mouse.cpp b/src/core/hle/service/hid/controllers/debug_mouse.cpp
deleted file mode 100644
index f2f1a27f8..000000000
--- a/src/core/hle/service/hid/controllers/debug_mouse.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/frontend/emu_window.h"
-#include "core/hid/emulated_devices.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/debug_mouse.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-DebugMouse::DebugMouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
- emulated_devices = hid_core.GetEmulatedDevices();
-}
-
-DebugMouse::~DebugMouse() = default;
-
-void DebugMouse::OnInit() {}
-void DebugMouse::OnRelease() {}
-
-void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_mouse;
-
- if (!IsControllerActivated()) {
- shared_memory.mouse_lifo.buffer_count = 0;
- shared_memory.mouse_lifo.buffer_tail = 0;
- return;
- }
-
- next_state = {};
-
- const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state;
- next_state.sampling_number = last_entry.sampling_number + 1;
-
- if (Settings::values.mouse_enabled) {
- const auto& mouse_button_state = emulated_devices->GetMouseButtons();
- const auto& mouse_position_state = emulated_devices->GetMousePosition();
- const auto& mouse_wheel_state = emulated_devices->GetMouseWheel();
- next_state.attribute.is_connected.Assign(1);
- next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
- next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
- next_state.delta_x = next_state.x - last_entry.x;
- next_state.delta_y = next_state.y - last_entry.y;
- next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x;
- next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y;
-
- last_mouse_wheel_state = mouse_wheel_state;
- next_state.button = mouse_button_state;
- }
-
- shared_memory.mouse_lifo.WriteNextEntry(next_state);
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_mouse.h b/src/core/hle/service/hid/controllers/debug_mouse.h
deleted file mode 100644
index ec939fa9f..000000000
--- a/src/core/hle/service/hid/controllers/debug_mouse.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Core::HID {
-class EmulatedDevices;
-struct MouseState;
-struct AnalogStickState;
-} // namespace Core::HID
-
-namespace Service::HID {
-class DebugMouse final : public ControllerBase {
-public:
- explicit DebugMouse(Core::HID::HIDCore& hid_core_);
- ~DebugMouse() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- Core::HID::MouseState next_state{};
- Core::HID::AnalogStickState last_mouse_wheel_state{};
- Core::HID::EmulatedDevices* emulated_devices = nullptr;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
deleted file mode 100644
index 1811cf620..000000000
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/settings.h"
-#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hid/hid_types.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-DebugPad::DebugPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
- controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
-}
-
-DebugPad::~DebugPad() = default;
-
-void DebugPad::OnInit() {}
-
-void DebugPad::OnRelease() {}
-
-void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- DebugPadSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_pad;
-
- if (!IsControllerActivated()) {
- shared_memory.debug_pad_lifo.buffer_count = 0;
- shared_memory.debug_pad_lifo.buffer_tail = 0;
- return;
- }
-
- const auto& last_entry = shared_memory.debug_pad_lifo.ReadCurrentEntry().state;
- next_state.sampling_number = last_entry.sampling_number + 1;
-
- if (Settings::values.debug_pad_enabled) {
- next_state.attribute.connected.Assign(1);
-
- const auto& button_state = controller->GetDebugPadButtons();
- const auto& stick_state = controller->GetSticks();
-
- next_state.pad_state = button_state;
- next_state.l_stick = stick_state.left;
- next_state.r_stick = stick_state.right;
- }
-
- shared_memory.debug_pad_lifo.WriteNextEntry(next_state);
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
deleted file mode 100644
index dd00b2402..000000000
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/types/debug_pad_types.h"
-
-namespace Core::HID {
-class HIDCore;
-}
-
-namespace Core::Timing {
-class CoreTiming;
-}
-
-namespace Service::HID {
-class DebugPad final : public ControllerBase {
-public:
- explicit DebugPad(Core::HID::HIDCore& hid_core_);
- ~DebugPad() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- DebugPadState next_state{};
- Core::HID::EmulatedController* controller = nullptr;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/digitizer.cpp b/src/core/hle/service/hid/controllers/digitizer.cpp
deleted file mode 100644
index c01580fd6..000000000
--- a/src/core/hle/service/hid/controllers/digitizer.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/digitizer.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-Digitizer::Digitizer(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
-
-Digitizer::~Digitizer() = default;
-
-void Digitizer::OnInit() {}
-
-void Digitizer::OnRelease() {}
-
-void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- auto& header = data->shared_memory_format->digitizer.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/digitizer.h b/src/core/hle/service/hid/controllers/digitizer.h
deleted file mode 100644
index d81f814c3..000000000
--- a/src/core/hle/service/hid/controllers/digitizer.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Service::HID {
-
-class Digitizer final : public ControllerBase {
-public:
- explicit Digitizer(Core::HID::HIDCore& hid_core_);
- ~Digitizer() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- bool smart_update{};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
deleted file mode 100644
index 6e686fe65..000000000
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/math_util.h"
-#include "common/settings.h"
-#include "core/frontend/emu_window.h"
-#include "core/hid/emulated_console.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-// HW is around 700, value is set to 400 to make it easier to trigger with mouse
-constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s
-constexpr f32 angle_threshold = 0.015f; // Threshold in radians
-constexpr f32 pinch_threshold = 0.5f; // Threshold in pixels
-constexpr f32 press_delay = 0.5f; // Time in seconds
-constexpr f32 double_tap_delay = 0.35f; // Time in seconds
-
-constexpr f32 Square(s32 num) {
- return static_cast<f32>(num * num);
-}
-
-Gesture::Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) {
- console = hid_core.GetEmulatedConsole();
-}
-Gesture::~Gesture() = default;
-
-void Gesture::OnInit() {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- shared_memory = &data->shared_memory_format->gesture;
- shared_memory->gesture_lifo.buffer_count = 0;
- shared_memory->gesture_lifo.buffer_tail = 0;
- force_update = true;
-}
-
-void Gesture::OnRelease() {}
-
-void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- shared_memory = &data->shared_memory_format->gesture;
-
- if (!IsControllerActivated()) {
- shared_memory->gesture_lifo.buffer_count = 0;
- shared_memory->gesture_lifo.buffer_tail = 0;
- return;
- }
-
- ReadTouchInput();
-
- GestureProperties gesture = GetGestureProperties();
- f32 time_difference =
- static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) /
- (1000 * 1000 * 1000);
-
- // Only update if necessary
- if (!ShouldUpdateGesture(gesture, time_difference)) {
- return;
- }
-
- last_update_timestamp = shared_memory->gesture_lifo.timestamp;
- UpdateGestureSharedMemory(gesture, time_difference);
-}
-
-void Gesture::ReadTouchInput() {
- if (!Settings::values.touchscreen.enabled) {
- fingers = {};
- return;
- }
-
- const auto touch_status = console->GetTouch();
- for (std::size_t id = 0; id < fingers.size(); ++id) {
- fingers[id] = touch_status[id];
- }
-}
-
-bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference) {
- const auto& last_entry = GetLastGestureEntry();
- if (force_update) {
- force_update = false;
- return true;
- }
-
- // Update if coordinates change
- for (size_t id = 0; id < MAX_POINTS; id++) {
- if (gesture.points[id] != last_gesture.points[id]) {
- return true;
- }
- }
-
- // Update on press and hold event after 0.5 seconds
- if (last_entry.type == GestureType::Touch && last_entry.point_count == 1 &&
- time_difference > press_delay) {
- return enable_press_and_tap;
- }
-
- return false;
-}
-
-void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) {
- GestureType type = GestureType::Idle;
- GestureAttribute attributes{};
-
- const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state;
-
- // Reset next state to default
- next_state.sampling_number = last_entry.sampling_number + 1;
- next_state.delta = {};
- next_state.vel_x = 0;
- next_state.vel_y = 0;
- next_state.direction = GestureDirection::None;
- next_state.rotation_angle = 0;
- next_state.scale = 0;
-
- if (gesture.active_points > 0) {
- if (last_gesture.active_points == 0) {
- NewGesture(gesture, type, attributes);
- } else {
- UpdateExistingGesture(gesture, type, time_difference);
- }
- } else {
- EndGesture(gesture, last_gesture, type, attributes, time_difference);
- }
-
- // Apply attributes
- next_state.detection_count = gesture.detection_count;
- next_state.type = type;
- next_state.attributes = attributes;
- next_state.pos = gesture.mid_point;
- next_state.point_count = static_cast<s32>(gesture.active_points);
- next_state.points = gesture.points;
- last_gesture = gesture;
-
- shared_memory->gesture_lifo.WriteNextEntry(next_state);
-}
-
-void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
- GestureAttribute& attributes) {
- const auto& last_entry = GetLastGestureEntry();
-
- gesture.detection_count++;
- type = GestureType::Touch;
-
- // New touch after cancel is not considered new
- if (last_entry.type != GestureType::Cancel) {
- attributes.is_new_touch.Assign(1);
- enable_press_and_tap = true;
- }
-}
-
-void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type,
- f32 time_difference) {
- const auto& last_entry = GetLastGestureEntry();
-
- // Promote to pan type if touch moved
- for (size_t id = 0; id < MAX_POINTS; id++) {
- if (gesture.points[id] != last_gesture.points[id]) {
- type = GestureType::Pan;
- break;
- }
- }
-
- // Number of fingers changed cancel the last event and clear data
- if (gesture.active_points != last_gesture.active_points) {
- type = GestureType::Cancel;
- enable_press_and_tap = false;
- gesture.active_points = 0;
- gesture.mid_point = {};
- gesture.points.fill({});
- return;
- }
-
- // Calculate extra parameters of panning
- if (type == GestureType::Pan) {
- UpdatePanEvent(gesture, last_gesture, type, time_difference);
- return;
- }
-
- // Promote to press type
- if (last_entry.type == GestureType::Touch) {
- type = GestureType::Press;
- }
-}
-
-void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, GestureAttribute& attributes, f32 time_difference) {
- const auto& last_entry = GetLastGestureEntry();
-
- if (last_gesture_props.active_points != 0) {
- switch (last_entry.type) {
- case GestureType::Touch:
- if (enable_press_and_tap) {
- SetTapEvent(gesture, last_gesture_props, type, attributes);
- return;
- }
- type = GestureType::Cancel;
- force_update = true;
- break;
- case GestureType::Press:
- case GestureType::Tap:
- case GestureType::Swipe:
- case GestureType::Pinch:
- case GestureType::Rotate:
- type = GestureType::Complete;
- force_update = true;
- break;
- case GestureType::Pan:
- EndPanEvent(gesture, last_gesture_props, type, time_difference);
- break;
- default:
- break;
- }
- return;
- }
- if (last_entry.type == GestureType::Complete || last_entry.type == GestureType::Cancel) {
- gesture.detection_count++;
- }
-}
-
-void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, GestureAttribute& attributes) {
- type = GestureType::Tap;
- gesture = last_gesture_props;
- force_update = true;
- f32 tap_time_difference =
- static_cast<f32>(last_update_timestamp - last_tap_timestamp) / (1000 * 1000 * 1000);
- last_tap_timestamp = last_update_timestamp;
- if (tap_time_difference < double_tap_delay) {
- attributes.is_double_tap.Assign(1);
- }
-}
-
-void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, f32 time_difference) {
- const auto& last_entry = GetLastGestureEntry();
-
- next_state.delta = gesture.mid_point - last_entry.pos;
- next_state.vel_x = static_cast<f32>(next_state.delta.x) / time_difference;
- next_state.vel_y = static_cast<f32>(next_state.delta.y) / time_difference;
- last_pan_time_difference = time_difference;
-
- // Promote to pinch type
- if (std::abs(gesture.average_distance - last_gesture_props.average_distance) >
- pinch_threshold) {
- type = GestureType::Pinch;
- next_state.scale = gesture.average_distance / last_gesture_props.average_distance;
- }
-
- const f32 angle_between_two_lines = std::atan((gesture.angle - last_gesture_props.angle) /
- (1 + (gesture.angle * last_gesture_props.angle)));
- // Promote to rotate type
- if (std::abs(angle_between_two_lines) > angle_threshold) {
- type = GestureType::Rotate;
- next_state.scale = 0;
- next_state.rotation_angle = angle_between_two_lines * 180.0f / Common::PI;
- }
-}
-
-void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, f32 time_difference) {
- const auto& last_entry = GetLastGestureEntry();
- next_state.vel_x =
- static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference);
- next_state.vel_y =
- static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference);
- const f32 curr_vel =
- std::sqrt((next_state.vel_x * next_state.vel_x) + (next_state.vel_y * next_state.vel_y));
-
- // Set swipe event with parameters
- if (curr_vel > swipe_threshold) {
- SetSwipeEvent(gesture, last_gesture_props, type);
- return;
- }
-
- // End panning without swipe
- type = GestureType::Complete;
- next_state.vel_x = 0;
- next_state.vel_y = 0;
- force_update = true;
-}
-
-void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type) {
- const auto& last_entry = GetLastGestureEntry();
-
- type = GestureType::Swipe;
- gesture = last_gesture_props;
- force_update = true;
- next_state.delta = last_entry.delta;
-
- if (std::abs(next_state.delta.x) > std::abs(next_state.delta.y)) {
- if (next_state.delta.x > 0) {
- next_state.direction = GestureDirection::Right;
- return;
- }
- next_state.direction = GestureDirection::Left;
- return;
- }
- if (next_state.delta.y > 0) {
- next_state.direction = GestureDirection::Down;
- return;
- }
- next_state.direction = GestureDirection::Up;
-}
-
-const GestureState& Gesture::GetLastGestureEntry() const {
- return shared_memory->gesture_lifo.ReadCurrentEntry().state;
-}
-
-GestureProperties Gesture::GetGestureProperties() {
- GestureProperties gesture;
- std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers;
- const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(),
- [](const auto& finger) { return finger.pressed; });
- gesture.active_points =
- static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
-
- for (size_t id = 0; id < gesture.active_points; ++id) {
- const auto& [active_x, active_y] = active_fingers[id].position;
- gesture.points[id] = {
- .x = static_cast<s32>(active_x * Layout::ScreenUndocked::Width),
- .y = static_cast<s32>(active_y * Layout::ScreenUndocked::Height),
- };
-
- // Hack: There is no touch in docked but games still allow it
- if (Settings::IsDockedMode()) {
- gesture.points[id] = {
- .x = static_cast<s32>(active_x * Layout::ScreenDocked::Width),
- .y = static_cast<s32>(active_y * Layout::ScreenDocked::Height),
- };
- }
-
- gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points);
- gesture.mid_point.y += static_cast<s32>(gesture.points[id].y / gesture.active_points);
- }
-
- for (size_t id = 0; id < gesture.active_points; ++id) {
- const f32 distance = std::sqrt(Square(gesture.mid_point.x - gesture.points[id].x) +
- Square(gesture.mid_point.y - gesture.points[id].y));
- gesture.average_distance += distance / static_cast<f32>(gesture.active_points);
- }
-
- gesture.angle = std::atan2(static_cast<f32>(gesture.mid_point.y - gesture.points[0].y),
- static_cast<f32>(gesture.mid_point.x - gesture.points[0].x));
-
- gesture.detection_count = last_gesture.detection_count;
-
- return gesture;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
deleted file mode 100644
index 78da1552a..000000000
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-
-#include "common/common_types.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/types/touch_types.h"
-
-namespace Core::HID {
-class EmulatedConsole;
-}
-
-namespace Service::HID {
-struct GestureSharedMemoryFormat;
-
-class Gesture final : public ControllerBase {
-public:
- explicit Gesture(Core::HID::HIDCore& hid_core_);
- ~Gesture() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- // Reads input from all available input engines
- void ReadTouchInput();
-
- // Returns true if gesture state needs to be updated
- bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference);
-
- // Updates the shared memory to the next state
- void UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference);
-
- // Initializes new gesture
- void NewGesture(GestureProperties& gesture, GestureType& type, GestureAttribute& attributes);
-
- // Updates existing gesture state
- void UpdateExistingGesture(GestureProperties& gesture, GestureType& type, f32 time_difference);
-
- // Terminates exiting gesture
- void EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, GestureAttribute& attributes, f32 time_difference);
-
- // Set current event to a tap event
- void SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, GestureAttribute& attributes);
-
- // Calculates and set the extra parameters related to a pan event
- void UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, f32 time_difference);
-
- // Terminates the pan event
- void EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type, f32 time_difference);
-
- // Set current event to a swipe event
- void SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
- GestureType& type);
-
- // Retrieves the last gesture entry, as indicated by shared memory indices.
- [[nodiscard]] const GestureState& GetLastGestureEntry() const;
-
- // Returns the average distance, angle and middle point of the active fingers
- GestureProperties GetGestureProperties();
-
- GestureState next_state{};
- GestureSharedMemoryFormat* shared_memory;
- Core::HID::EmulatedConsole* console = nullptr;
-
- std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
- GestureProperties last_gesture{};
- s64 last_update_timestamp{};
- s64 last_tap_timestamp{};
- f32 last_pan_time_difference{};
- bool force_update{false};
- bool enable_press_and_tap{false};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/home_button.cpp b/src/core/hle/service/hid/controllers/home_button.cpp
deleted file mode 100644
index 71dd9bc08..000000000
--- a/src/core/hle/service/hid/controllers/home_button.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/home_button.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-HomeButton::HomeButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
-
-HomeButton::~HomeButton() = default;
-
-void HomeButton::OnInit() {}
-
-void HomeButton::OnRelease() {}
-
-void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- auto& header = data->shared_memory_format->home_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/home_button.h b/src/core/hle/service/hid/controllers/home_button.h
deleted file mode 100644
index e91c2aa5d..000000000
--- a/src/core/hle/service/hid/controllers/home_button.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Service::HID {
-
-class HomeButton final : public ControllerBase {
-public:
- explicit HomeButton(Core::HID::HIDCore& hid_core_);
- ~HomeButton() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- bool smart_update{};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
deleted file mode 100644
index c72b3e5ce..000000000
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/settings.h"
-#include "core/core_timing.h"
-#include "core/hid/emulated_devices.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-Keyboard::Keyboard(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
- emulated_devices = hid_core.GetEmulatedDevices();
-}
-
-Keyboard::~Keyboard() = default;
-
-void Keyboard::OnInit() {}
-
-void Keyboard::OnRelease() {}
-
-void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- KeyboardSharedMemoryFormat& shared_memory = data->shared_memory_format->keyboard;
-
- if (!IsControllerActivated()) {
- shared_memory.keyboard_lifo.buffer_count = 0;
- shared_memory.keyboard_lifo.buffer_tail = 0;
- return;
- }
-
- const auto& last_entry = shared_memory.keyboard_lifo.ReadCurrentEntry().state;
- next_state.sampling_number = last_entry.sampling_number + 1;
-
- if (Settings::values.keyboard_enabled) {
- const auto& keyboard_state = emulated_devices->GetKeyboard();
- const auto& keyboard_modifier_state = emulated_devices->GetKeyboardModifier();
-
- next_state.key = keyboard_state;
- next_state.modifier = keyboard_modifier_state;
- next_state.attribute.is_connected.Assign(1);
- }
-
- shared_memory.keyboard_lifo.WriteNextEntry(next_state);
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
deleted file mode 100644
index e8ca326c6..000000000
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/types/keyboard_types.h"
-
-namespace Service::HID {
-class Keyboard final : public ControllerBase {
-public:
- explicit Keyboard(Core::HID::HIDCore& hid_core_);
- ~Keyboard() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- KeyboardState next_state{};
- Core::HID::EmulatedDevices* emulated_devices = nullptr;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
deleted file mode 100644
index 58deafbc5..000000000
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/frontend/emu_window.h"
-#include "core/hid/emulated_devices.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/mouse.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-Mouse::Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
- emulated_devices = hid_core.GetEmulatedDevices();
-}
-
-Mouse::~Mouse() = default;
-
-void Mouse::OnInit() {}
-void Mouse::OnRelease() {}
-
-void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->mouse;
-
- if (!IsControllerActivated()) {
- shared_memory.mouse_lifo.buffer_count = 0;
- shared_memory.mouse_lifo.buffer_tail = 0;
- return;
- }
-
- next_state = {};
-
- const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state;
- next_state.sampling_number = last_entry.sampling_number + 1;
-
- if (Settings::values.mouse_enabled) {
- const auto& mouse_button_state = emulated_devices->GetMouseButtons();
- const auto& mouse_position_state = emulated_devices->GetMousePosition();
- const auto& mouse_wheel_state = emulated_devices->GetMouseWheel();
- next_state.attribute.is_connected.Assign(1);
- next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
- next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
- next_state.delta_x = next_state.x - last_entry.x;
- next_state.delta_y = next_state.y - last_entry.y;
- next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x;
- next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y;
-
- last_mouse_wheel_state = mouse_wheel_state;
- next_state.button = mouse_button_state;
- }
-
- shared_memory.mouse_lifo.WriteNextEntry(next_state);
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
deleted file mode 100644
index cefad956c..000000000
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Core::HID {
-class EmulatedDevices;
-struct MouseState;
-struct AnalogStickState;
-} // namespace Core::HID
-
-namespace Service::HID {
-class Mouse final : public ControllerBase {
-public:
- explicit Mouse(Core::HID::HIDCore& hid_core_);
- ~Mouse() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- Core::HID::MouseState next_state{};
- Core::HID::AnalogStickState last_mouse_wheel_state{};
- Core::HID::EmulatedDevices* emulated_devices = nullptr;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
deleted file mode 100644
index c7aa606bc..000000000
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ /dev/null
@@ -1,1346 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <algorithm>
-#include <array>
-#include <chrono>
-#include <cstring>
-
-#include "common/assert.h"
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "common/logging/log.h"
-#include "common/settings.h"
-#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-#include "core/hle/service/hid/errors.h"
-#include "core/hle/service/hid/hid_util.h"
-#include "core/hle/service/kernel_helpers.h"
-
-namespace Service::HID {
-constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
- Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3,
- Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6,
- Core::HID::NpadIdType::Player7, Core::HID::NpadIdType::Player8, Core::HID::NpadIdType::Other,
- Core::HID::NpadIdType::Handheld,
-};
-
-NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
- : ControllerBase{hid_core_}, service_context{service_context_} {
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[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); },
- .is_npad_service = true,
- };
- controller.callback_key = controller.device->SetCallback(engine_callback);
- }
-}
-
-NPad::~NPad() {
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[i];
- controller.device->DeleteCallback(controller.callback_key);
- }
- OnRelease();
-}
-
-void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) {
- if (type == Core::HID::ControllerTriggerType::All) {
- ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
- ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx);
- return;
- }
- if (controller_idx >= controller_data.size()) {
- return;
- }
-
- auto& controller = controller_data[controller_idx];
- const auto is_connected = controller.device->IsConnected();
- const auto npad_type = controller.device->GetNpadStyleIndex();
- const auto npad_id = controller.device->GetNpadIdType();
- switch (type) {
- case Core::HID::ControllerTriggerType::Connected:
- case Core::HID::ControllerTriggerType::Disconnected:
- if (is_connected == controller.is_connected) {
- return;
- }
- UpdateControllerAt(npad_type, npad_id, is_connected);
- break;
- case Core::HID::ControllerTriggerType::Battery: {
- if (!controller.device->IsConnected()) {
- return;
- }
- auto* shared_memory = controller.shared_memory;
- const auto& battery_level = controller.device->GetBattery();
- shared_memory->battery_level_dual = battery_level.dual.battery_level;
- shared_memory->battery_level_left = battery_level.left.battery_level;
- shared_memory->battery_level_right = battery_level.right.battery_level;
- break;
- }
- default:
- break;
- }
-}
-
-void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
- auto& controller = GetControllerFromNpadIdType(npad_id);
- if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) {
- return;
- }
- LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
- const auto controller_type = controller.device->GetNpadStyleIndex();
- const auto& body_colors = controller.device->GetColors();
- const auto& battery_level = controller.device->GetBattery();
- auto* shared_memory = controller.shared_memory;
- if (controller_type == Core::HID::NpadStyleIndex::None) {
- controller.styleset_changed_event->Signal();
- return;
- }
-
- // Reset memory values
- shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None;
- shared_memory->device_type.raw = 0;
- shared_memory->system_properties.raw = 0;
- shared_memory->joycon_color.attribute = ColorAttribute::NoController;
- shared_memory->joycon_color.attribute = ColorAttribute::NoController;
- shared_memory->fullkey_color = {};
- shared_memory->joycon_color.left = {};
- shared_memory->joycon_color.right = {};
- shared_memory->battery_level_dual = {};
- shared_memory->battery_level_left = {};
- shared_memory->battery_level_right = {};
-
- switch (controller_type) {
- case Core::HID::NpadStyleIndex::None:
- ASSERT(false);
- break;
- case Core::HID::NpadStyleIndex::ProController:
- shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
- shared_memory->fullkey_color.fullkey = body_colors.fullkey;
- shared_memory->battery_level_dual = battery_level.dual.battery_level;
- shared_memory->style_tag.fullkey.Assign(1);
- shared_memory->device_type.fullkey.Assign(1);
- shared_memory->system_properties.is_vertical.Assign(1);
- shared_memory->system_properties.use_plus.Assign(1);
- shared_memory->system_properties.use_minus.Assign(1);
- shared_memory->system_properties.is_charging_joy_dual.Assign(
- battery_level.dual.is_charging);
- shared_memory->applet_footer_type = AppletFooterUiType::SwitchProController;
- shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::Handheld:
- shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
- shared_memory->joycon_color.attribute = ColorAttribute::Ok;
- shared_memory->fullkey_color.fullkey = body_colors.fullkey;
- shared_memory->joycon_color.left = body_colors.left;
- shared_memory->joycon_color.right = body_colors.right;
- shared_memory->style_tag.handheld.Assign(1);
- shared_memory->device_type.handheld_left.Assign(1);
- shared_memory->device_type.handheld_right.Assign(1);
- shared_memory->system_properties.is_vertical.Assign(1);
- shared_memory->system_properties.use_plus.Assign(1);
- shared_memory->system_properties.use_minus.Assign(1);
- shared_memory->system_properties.use_directional_buttons.Assign(1);
- shared_memory->system_properties.is_charging_joy_dual.Assign(
- battery_level.left.is_charging);
- shared_memory->system_properties.is_charging_joy_left.Assign(
- battery_level.left.is_charging);
- shared_memory->system_properties.is_charging_joy_right.Assign(
- battery_level.right.is_charging);
- shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
- shared_memory->applet_footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
- shared_memory->sixaxis_handheld_properties.is_newly_assigned.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::JoyconDual:
- shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
- shared_memory->joycon_color.attribute = ColorAttribute::Ok;
- shared_memory->style_tag.joycon_dual.Assign(1);
- if (controller.is_dual_left_connected) {
- shared_memory->joycon_color.left = body_colors.left;
- shared_memory->battery_level_left = battery_level.left.battery_level;
- shared_memory->device_type.joycon_left.Assign(1);
- shared_memory->system_properties.use_minus.Assign(1);
- shared_memory->system_properties.is_charging_joy_left.Assign(
- battery_level.left.is_charging);
- shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1);
- }
- if (controller.is_dual_right_connected) {
- shared_memory->joycon_color.right = body_colors.right;
- shared_memory->battery_level_right = battery_level.right.battery_level;
- shared_memory->device_type.joycon_right.Assign(1);
- shared_memory->system_properties.use_plus.Assign(1);
- shared_memory->system_properties.is_charging_joy_right.Assign(
- battery_level.right.is_charging);
- shared_memory->sixaxis_dual_right_properties.is_newly_assigned.Assign(1);
- }
- shared_memory->system_properties.use_directional_buttons.Assign(1);
- shared_memory->system_properties.is_vertical.Assign(1);
- shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
-
- if (controller.is_dual_left_connected && controller.is_dual_right_connected) {
- shared_memory->applet_footer_type = AppletFooterUiType::JoyDual;
- shared_memory->fullkey_color.fullkey = body_colors.left;
- shared_memory->battery_level_dual = battery_level.left.battery_level;
- shared_memory->system_properties.is_charging_joy_dual.Assign(
- battery_level.left.is_charging);
- } else if (controller.is_dual_left_connected) {
- shared_memory->applet_footer_type = AppletFooterUiType::JoyDualLeftOnly;
- shared_memory->fullkey_color.fullkey = body_colors.left;
- shared_memory->battery_level_dual = battery_level.left.battery_level;
- shared_memory->system_properties.is_charging_joy_dual.Assign(
- battery_level.left.is_charging);
- } else {
- shared_memory->applet_footer_type = AppletFooterUiType::JoyDualRightOnly;
- shared_memory->fullkey_color.fullkey = body_colors.right;
- shared_memory->battery_level_dual = battery_level.right.battery_level;
- shared_memory->system_properties.is_charging_joy_dual.Assign(
- battery_level.right.is_charging);
- }
- break;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
- shared_memory->fullkey_color.fullkey = body_colors.left;
- shared_memory->joycon_color.attribute = ColorAttribute::Ok;
- shared_memory->joycon_color.left = body_colors.left;
- shared_memory->battery_level_dual = battery_level.left.battery_level;
- shared_memory->style_tag.joycon_left.Assign(1);
- shared_memory->device_type.joycon_left.Assign(1);
- shared_memory->system_properties.is_horizontal.Assign(1);
- shared_memory->system_properties.use_minus.Assign(1);
- shared_memory->system_properties.is_charging_joy_left.Assign(
- battery_level.left.is_charging);
- shared_memory->applet_footer_type = AppletFooterUiType::JoyLeftHorizontal;
- shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::JoyconRight:
- shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
- shared_memory->fullkey_color.fullkey = body_colors.right;
- shared_memory->joycon_color.attribute = ColorAttribute::Ok;
- shared_memory->joycon_color.right = body_colors.right;
- shared_memory->battery_level_right = battery_level.right.battery_level;
- shared_memory->style_tag.joycon_right.Assign(1);
- shared_memory->device_type.joycon_right.Assign(1);
- shared_memory->system_properties.is_horizontal.Assign(1);
- shared_memory->system_properties.use_plus.Assign(1);
- shared_memory->system_properties.is_charging_joy_right.Assign(
- battery_level.right.is_charging);
- shared_memory->applet_footer_type = AppletFooterUiType::JoyRightHorizontal;
- shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::GameCube:
- shared_memory->style_tag.gamecube.Assign(1);
- shared_memory->device_type.fullkey.Assign(1);
- shared_memory->system_properties.is_vertical.Assign(1);
- shared_memory->system_properties.use_plus.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::Pokeball:
- shared_memory->style_tag.palma.Assign(1);
- shared_memory->device_type.palma.Assign(1);
- shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::NES:
- shared_memory->style_tag.lark.Assign(1);
- shared_memory->device_type.fullkey.Assign(1);
- break;
- case Core::HID::NpadStyleIndex::SNES:
- shared_memory->style_tag.lucia.Assign(1);
- shared_memory->device_type.fullkey.Assign(1);
- shared_memory->applet_footer_type = AppletFooterUiType::Lucia;
- break;
- case Core::HID::NpadStyleIndex::N64:
- shared_memory->style_tag.lagoon.Assign(1);
- shared_memory->device_type.fullkey.Assign(1);
- shared_memory->applet_footer_type = AppletFooterUiType::Lagon;
- break;
- case Core::HID::NpadStyleIndex::SegaGenesis:
- shared_memory->style_tag.lager.Assign(1);
- shared_memory->device_type.fullkey.Assign(1);
- break;
- default:
- break;
- }
-
- controller.is_connected = true;
- controller.device->Connect();
- controller.device->SetLedPattern();
- if (controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
- if (controller.is_dual_left_connected) {
- controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::LeftIndex,
- Common::Input::PollingMode::Active);
- }
- if (controller.is_dual_right_connected) {
- controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
- Common::Input::PollingMode::Active);
- }
- } else {
- controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
- Common::Input::PollingMode::Active);
- }
-
- SignalStyleSetChangedEvent(npad_id);
- WriteEmptyEntry(controller.shared_memory);
- hid_core.SetLastActiveController(npad_id);
-}
-
-void NPad::OnInit() {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- if (!IsControllerActivated()) {
- return;
- }
-
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[i];
- controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
- controller.styleset_changed_event =
- service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
- }
-
- supported_npad_id_types.resize(npad_id_list.size());
- std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
- npad_id_list.size() * sizeof(Core::HID::NpadIdType));
-
- // Prefill controller buffers
- for (auto& controller : controller_data) {
- auto* npad = controller.shared_memory;
- npad->fullkey_color = {
- .attribute = ColorAttribute::NoController,
- .fullkey = {},
- };
- npad->joycon_color = {
- .attribute = ColorAttribute::NoController,
- .left = {},
- .right = {},
- };
- // HW seems to initialize the first 19 entries
- for (std::size_t i = 0; i < 19; ++i) {
- WriteEmptyEntry(npad);
- }
- }
-}
-
-void NPad::WriteEmptyEntry(NpadInternalState* npad) {
- NPadGenericState dummy_pad_state{};
- NpadGcTriggerState dummy_gc_state{};
- dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->fullkey_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad->handheld_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->handheld_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad->joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->joy_dual_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad->joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->joy_left_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad->joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->joy_right_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad->palma_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->palma_lifo.WriteNextEntry(dummy_pad_state);
- dummy_pad_state.sampling_number = npad->system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->system_ext_lifo.WriteNextEntry(dummy_pad_state);
- dummy_gc_state.sampling_number = npad->gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
- npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
-}
-
-void NPad::OnRelease() {
- is_controller_initialized = false;
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[i];
- if (controller.styleset_changed_event) {
- service_context.CloseEvent(controller.styleset_changed_event);
- }
- for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
- VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_idx, {});
- }
- }
-}
-
-void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
- std::scoped_lock lock{mutex};
- auto& controller = GetControllerFromNpadIdType(npad_id);
- const auto controller_type = controller.device->GetNpadStyleIndex();
-
- if (!controller.device->IsConnected() && controller.is_connected) {
- DisconnectNpad(npad_id);
- return;
- }
- if (!controller.device->IsConnected()) {
- return;
- }
- if (controller.device->IsConnected() && !controller.is_connected) {
- InitNewlyAddedController(npad_id);
- }
-
- // This function is unique to yuzu for the turbo buttons and motion to work properly
- controller.device->StatusUpdate();
-
- auto& pad_entry = controller.npad_pad_state;
- auto& trigger_entry = controller.npad_trigger_state;
- const auto button_state = controller.device->GetNpadButtons();
- const auto stick_state = controller.device->GetSticks();
-
- using btn = Core::HID::NpadButton;
- pad_entry.npad_buttons.raw = btn::None;
- if (controller_type != Core::HID::NpadStyleIndex::JoyconLeft) {
- constexpr btn right_button_mask = btn::A | btn::B | btn::X | btn::Y | btn::StickR | btn::R |
- btn::ZR | btn::Plus | btn::StickRLeft | btn::StickRUp |
- btn::StickRRight | btn::StickRDown;
- pad_entry.npad_buttons.raw = button_state.raw & right_button_mask;
- pad_entry.r_stick = stick_state.right;
- }
-
- if (controller_type != Core::HID::NpadStyleIndex::JoyconRight) {
- constexpr btn left_button_mask =
- btn::Left | btn::Up | btn::Right | btn::Down | btn::StickL | btn::L | btn::ZL |
- btn::Minus | btn::StickLLeft | btn::StickLUp | btn::StickLRight | btn::StickLDown;
- pad_entry.npad_buttons.raw |= button_state.raw & left_button_mask;
- pad_entry.l_stick = stick_state.left;
- }
-
- if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft ||
- controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
- pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
- pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
- }
-
- if (controller_type == Core::HID::NpadStyleIndex::JoyconRight ||
- controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
- pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
- pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
- }
-
- if (controller_type == Core::HID::NpadStyleIndex::GameCube) {
- const auto& trigger_state = controller.device->GetTriggers();
- trigger_entry.l_analog = trigger_state.left;
- trigger_entry.r_analog = trigger_state.right;
- pad_entry.npad_buttons.zl.Assign(false);
- pad_entry.npad_buttons.zr.Assign(button_state.r);
- pad_entry.npad_buttons.l.Assign(button_state.zl);
- pad_entry.npad_buttons.r.Assign(button_state.zr);
- }
-
- if (pad_entry.npad_buttons.raw != Core::HID::NpadButton::None) {
- hid_core.SetLastActiveController(npad_id);
- }
-}
-
-void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- if (!IsControllerActivated()) {
- return;
- }
-
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[i];
- controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
- auto* npad = controller.shared_memory;
-
- const auto& controller_type = controller.device->GetNpadStyleIndex();
-
- if (controller_type == Core::HID::NpadStyleIndex::None ||
- !controller.device->IsConnected()) {
- continue;
- }
-
- RequestPadStateUpdate(controller.device->GetNpadIdType());
- auto& pad_state = controller.npad_pad_state;
- auto& libnx_state = controller.npad_libnx_state;
- auto& trigger_state = controller.npad_trigger_state;
-
- // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
- // any controllers.
- libnx_state.connection_status.raw = 0;
- libnx_state.connection_status.is_connected.Assign(1);
- switch (controller_type) {
- case Core::HID::NpadStyleIndex::None:
- ASSERT(false);
- break;
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::NES:
- case Core::HID::NpadStyleIndex::SNES:
- case Core::HID::NpadStyleIndex::N64:
- case Core::HID::NpadStyleIndex::SegaGenesis:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- pad_state.connection_status.is_wired.Assign(1);
-
- libnx_state.connection_status.is_wired.Assign(1);
- pad_state.sampling_number =
- npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->fullkey_lifo.WriteNextEntry(pad_state);
- break;
- case Core::HID::NpadStyleIndex::Handheld:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- pad_state.connection_status.is_wired.Assign(1);
- pad_state.connection_status.is_left_connected.Assign(1);
- pad_state.connection_status.is_right_connected.Assign(1);
- pad_state.connection_status.is_left_wired.Assign(1);
- pad_state.connection_status.is_right_wired.Assign(1);
-
- libnx_state.connection_status.is_wired.Assign(1);
- libnx_state.connection_status.is_left_connected.Assign(1);
- libnx_state.connection_status.is_right_connected.Assign(1);
- libnx_state.connection_status.is_left_wired.Assign(1);
- libnx_state.connection_status.is_right_wired.Assign(1);
- pad_state.sampling_number =
- npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->handheld_lifo.WriteNextEntry(pad_state);
- break;
- case Core::HID::NpadStyleIndex::JoyconDual:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- if (controller.is_dual_left_connected) {
- pad_state.connection_status.is_left_connected.Assign(1);
- libnx_state.connection_status.is_left_connected.Assign(1);
- }
- if (controller.is_dual_right_connected) {
- pad_state.connection_status.is_right_connected.Assign(1);
- libnx_state.connection_status.is_right_connected.Assign(1);
- }
-
- pad_state.sampling_number =
- npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->joy_dual_lifo.WriteNextEntry(pad_state);
- break;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- pad_state.connection_status.is_left_connected.Assign(1);
-
- libnx_state.connection_status.is_left_connected.Assign(1);
- pad_state.sampling_number =
- npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->joy_left_lifo.WriteNextEntry(pad_state);
- break;
- case Core::HID::NpadStyleIndex::JoyconRight:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- pad_state.connection_status.is_right_connected.Assign(1);
-
- libnx_state.connection_status.is_right_connected.Assign(1);
- pad_state.sampling_number =
- npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->joy_right_lifo.WriteNextEntry(pad_state);
- break;
- case Core::HID::NpadStyleIndex::GameCube:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- pad_state.connection_status.is_wired.Assign(1);
-
- libnx_state.connection_status.is_wired.Assign(1);
- pad_state.sampling_number =
- npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
- trigger_state.sampling_number =
- npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->fullkey_lifo.WriteNextEntry(pad_state);
- npad->gc_trigger_lifo.WriteNextEntry(trigger_state);
- break;
- case Core::HID::NpadStyleIndex::Pokeball:
- pad_state.connection_status.raw = 0;
- pad_state.connection_status.is_connected.Assign(1);
- pad_state.sampling_number =
- npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
- npad->palma_lifo.WriteNextEntry(pad_state);
- break;
- default:
- break;
- }
-
- libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
- libnx_state.l_stick = pad_state.l_stick;
- libnx_state.r_stick = pad_state.r_stick;
- npad->system_ext_lifo.WriteNextEntry(pad_state);
-
- press_state |= static_cast<u64>(pad_state.npad_buttons.raw);
- }
-}
-
-void NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
- hid_core.SetSupportedStyleTag(style_set);
-
- if (is_controller_initialized) {
- return;
- }
-
- // Once SetSupportedStyleSet is called controllers are fully initialized
- is_controller_initialized = true;
-}
-
-Core::HID::NpadStyleTag NPad::GetSupportedStyleSet() const {
- if (!is_controller_initialized) {
- return {Core::HID::NpadStyleSet::None};
- }
- return hid_core.GetSupportedStyleTag();
-}
-
-Result NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
- constexpr std::size_t max_number_npad_ids = 0xa;
- const auto length = data.size();
- ASSERT(length > 0 && (length % sizeof(u32)) == 0);
- const std::size_t elements = length / sizeof(u32);
-
- if (elements > max_number_npad_ids) {
- return InvalidArraySize;
- }
-
- supported_npad_id_types.clear();
- supported_npad_id_types.resize(elements);
- std::memcpy(supported_npad_id_types.data(), data.data(), length);
- return ResultSuccess;
-}
-
-void NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
- const auto copy_amount = supported_npad_id_types.size() * sizeof(u32);
- ASSERT(max_length <= copy_amount);
- std::memcpy(data, supported_npad_id_types.data(), copy_amount);
-}
-
-std::size_t NPad::GetSupportedNpadIdTypesSize() const {
- return supported_npad_id_types.size();
-}
-
-void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
- if (joy_hold_type != NpadJoyHoldType::Horizontal &&
- joy_hold_type != NpadJoyHoldType::Vertical) {
- LOG_ERROR(Service_HID, "Npad joy hold type needs to be valid, joy_hold_type={}",
- joy_hold_type);
- return;
- }
- hold_type = joy_hold_type;
-}
-
-NpadJoyHoldType NPad::GetHoldType() const {
- return hold_type;
-}
-
-void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode) {
- if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
- ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
- return;
- }
-
- handheld_activation_mode = activation_mode;
-}
-
-NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const {
- return handheld_activation_mode;
-}
-
-void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
- communication_mode = communication_mode_;
-}
-
-NpadCommunicationMode NPad::GetNpadCommunicationMode() const {
- return communication_mode;
-}
-
-bool NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
- NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- return false;
- }
-
- auto& controller = GetControllerFromNpadIdType(npad_id);
- if (controller.shared_memory->assignment_mode != assignment_mode) {
- controller.shared_memory->assignment_mode = assignment_mode;
- }
-
- if (!controller.device->IsConnected()) {
- return false;
- }
-
- if (assignment_mode == NpadJoyAssignmentMode::Dual) {
- if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) {
- DisconnectNpad(npad_id);
- controller.is_dual_left_connected = true;
- controller.is_dual_right_connected = false;
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
- return false;
- }
- if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
- DisconnectNpad(npad_id);
- controller.is_dual_left_connected = false;
- controller.is_dual_right_connected = true;
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
- return false;
- }
- return false;
- }
-
- // This is for NpadJoyAssignmentMode::Single
-
- // Only JoyconDual get affected by this function
- if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) {
- return false;
- }
-
- if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
- DisconnectNpad(npad_id);
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
- return false;
- }
- if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
- DisconnectNpad(npad_id);
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
- return false;
- }
-
- // We have two controllers connected to the same npad_id we need to split them
- new_npad_id = hid_core.GetFirstDisconnectedNpadId();
- auto& controller_2 = GetControllerFromNpadIdType(new_npad_id);
- DisconnectNpad(npad_id);
- if (npad_device_type == NpadJoyDeviceType::Left) {
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
- controller_2.is_dual_left_connected = false;
- controller_2.is_dual_right_connected = true;
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
- } else {
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
- controller_2.is_dual_left_connected = true;
- controller_2.is_dual_right_connected = false;
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
- }
- return true;
-}
-
-bool NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
- const Core::HID::VibrationValue& vibration_value) {
- auto& controller = GetControllerFromNpadIdType(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(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(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(controller.device->GetNpadIdType(), device_index,
- vibration_value)) {
- controller.vibration[device_index].latest_vibration_value = vibration_value;
- }
-}
-
-void NPad::VibrateControllers(
- 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(vibration_device_handles[i], vibration_values[i]);
- }
-}
-
-Core::HID::VibrationValue NPad::GetLastVibration(
- const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
- return {};
- }
-
- const auto& controller = GetControllerFromHandle(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 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);
- InitializeVibrationDeviceAtIndex(npad_index, device_index);
-}
-
-void NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id,
- std::size_t device_index) {
- auto& controller = GetControllerFromNpadIdType(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(
- const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
- if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
- return false;
- }
-
- const auto& controller = GetControllerFromHandle(vibration_device_handle);
- const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
- return controller.vibration[device_index].device_mounted;
-}
-
-Kernel::KReadableEvent& NPad::GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id) {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- // Fallback to player 1
- const auto& controller = GetControllerFromNpadIdType(Core::HID::NpadIdType::Player1);
- return controller.styleset_changed_event->GetReadableEvent();
- }
-
- const auto& controller = GetControllerFromNpadIdType(npad_id);
- return controller.styleset_changed_event->GetReadableEvent();
-}
-
-void NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
- const auto& controller = GetControllerFromNpadIdType(npad_id);
- controller.styleset_changed_event->Signal();
-}
-
-void NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id) {
- UpdateControllerAt(controller, npad_id, true);
-}
-
-void NPad::UpdateControllerAt(Core::HID::NpadStyleIndex type, Core::HID::NpadIdType npad_id,
- bool connected) {
- auto& controller = GetControllerFromNpadIdType(npad_id);
- if (!connected) {
- DisconnectNpad(npad_id);
- return;
- }
-
- controller.device->SetNpadStyleIndex(type);
- InitNewlyAddedController(npad_id);
-}
-
-Result NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- return InvalidNpadId;
- }
-
- LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id);
- auto& controller = GetControllerFromNpadIdType(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(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
- shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
- shared_memory->device_type.raw = 0;
- shared_memory->system_properties.raw = 0;
- shared_memory->button_properties.raw = 0;
- shared_memory->sixaxis_fullkey_properties.raw = 0;
- shared_memory->sixaxis_handheld_properties.raw = 0;
- shared_memory->sixaxis_dual_left_properties.raw = 0;
- shared_memory->sixaxis_dual_right_properties.raw = 0;
- shared_memory->sixaxis_left_properties.raw = 0;
- shared_memory->sixaxis_right_properties.raw = 0;
- shared_memory->battery_level_dual = Core::HID::NpadBatteryLevel::Empty;
- shared_memory->battery_level_left = Core::HID::NpadBatteryLevel::Empty;
- shared_memory->battery_level_right = Core::HID::NpadBatteryLevel::Empty;
- shared_memory->fullkey_color = {
- .attribute = ColorAttribute::NoController,
- .fullkey = {},
- };
- shared_memory->joycon_color = {
- .attribute = ColorAttribute::NoController,
- .left = {},
- .right = {},
- };
- shared_memory->applet_footer_type = AppletFooterUiType::None;
-
- controller.is_dual_left_connected = true;
- controller.is_dual_right_connected = true;
- controller.is_connected = false;
- controller.device->Disconnect();
- SignalStyleSetChangedEvent(npad_id);
- WriteEmptyEntry(shared_memory);
- return ResultSuccess;
-}
-
-Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle);
- is_firmware_available = sixaxis_properties.is_firmware_update_available != 0;
- return ResultSuccess;
-}
-
-Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& sixaxis_properties = GetSixaxisProperties(sixaxis_handle);
- sixaxis_properties.is_newly_assigned.Assign(0);
-
- return ResultSuccess;
-}
-
-Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
- Core::HID::NpadIdType npad_id_2) {
- if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
- npad_id_2);
- return InvalidNpadId;
- }
- auto& controller_1 = GetControllerFromNpadIdType(npad_id_1);
- auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
- auto controller_style_1 = controller_1.device->GetNpadStyleIndex();
- auto controller_style_2 = controller_2.device->GetNpadStyleIndex();
-
- // Simplify this code by converting dualjoycon with only a side connected to single joycons
- if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual) {
- if (controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) {
- controller_style_1 = Core::HID::NpadStyleIndex::JoyconLeft;
- }
- if (!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) {
- controller_style_1 = Core::HID::NpadStyleIndex::JoyconRight;
- }
- }
- if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) {
- if (controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) {
- controller_style_2 = Core::HID::NpadStyleIndex::JoyconLeft;
- }
- if (!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) {
- controller_style_2 = Core::HID::NpadStyleIndex::JoyconRight;
- }
- }
-
- // Invalid merge errors
- if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual ||
- controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) {
- return NpadIsDualJoycon;
- }
- if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft &&
- controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft) {
- return NpadIsSameType;
- }
- if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight &&
- controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) {
- return NpadIsSameType;
- }
-
- // These exceptions are handled as if they where dual joycon
- if (controller_style_1 != Core::HID::NpadStyleIndex::JoyconLeft &&
- controller_style_1 != Core::HID::NpadStyleIndex::JoyconRight) {
- return NpadIsDualJoycon;
- }
- if (controller_style_2 != Core::HID::NpadStyleIndex::JoyconLeft &&
- controller_style_2 != Core::HID::NpadStyleIndex::JoyconRight) {
- return NpadIsDualJoycon;
- }
-
- // Disconnect the joycons and connect them as dual joycon at the first index.
- DisconnectNpad(npad_id_1);
- DisconnectNpad(npad_id_2);
- controller_1.is_dual_left_connected = true;
- controller_1.is_dual_right_connected = true;
- AddNewControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_1);
- return ResultSuccess;
-}
-
-void NPad::StartLRAssignmentMode() {
- // Nothing internally is used for lr assignment mode. Since we have the ability to set the
- // controller types from boot, it doesn't really matter about showing a selection screen
- is_in_lr_assignment_mode = true;
-}
-
-void NPad::StopLRAssignmentMode() {
- is_in_lr_assignment_mode = false;
-}
-
-Result NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2) {
- if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1,
- npad_id_2);
- return InvalidNpadId;
- }
- if (npad_id_1 == Core::HID::NpadIdType::Handheld ||
- npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other ||
- npad_id_2 == Core::HID::NpadIdType::Other) {
- return ResultSuccess;
- }
- const auto& controller_1 = GetControllerFromNpadIdType(npad_id_1).device;
- const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device;
- const auto type_index_1 = controller_1->GetNpadStyleIndex();
- const auto type_index_2 = controller_2->GetNpadStyleIndex();
- const auto is_connected_1 = controller_1->IsConnected();
- const auto is_connected_2 = controller_2->IsConnected();
-
- if (!IsControllerSupported(type_index_1) && is_connected_1) {
- return NpadNotConnected;
- }
- if (!IsControllerSupported(type_index_2) && is_connected_2) {
- return NpadNotConnected;
- }
-
- UpdateControllerAt(type_index_2, npad_id_1, is_connected_2);
- UpdateControllerAt(type_index_1, npad_id_2, is_connected_1);
-
- return ResultSuccess;
-}
-
-Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- return InvalidNpadId;
- }
- const auto& controller = GetControllerFromNpadIdType(npad_id).device;
- pattern = controller->GetLedPattern();
- return ResultSuccess;
-}
-
-Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
- bool& is_valid) const {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- return InvalidNpadId;
- }
- const auto& controller = GetControllerFromNpadIdType(npad_id);
- is_valid = controller.unintended_home_button_input_protection;
- return ResultSuccess;
-}
-
-Result NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
- Core::HID::NpadIdType npad_id) {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- return InvalidNpadId;
- }
- auto& controller = GetControllerFromNpadIdType(npad_id);
- controller.unintended_home_button_input_protection = is_protection_enabled;
- return ResultSuccess;
-}
-
-void NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
- analog_stick_use_center_clamp = use_center_clamp;
-}
-
-void NPad::ClearAllConnectedControllers() {
- for (auto& controller : controller_data) {
- if (controller.device->IsConnected() &&
- controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) {
- controller.device->Disconnect();
- controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
- }
- }
-}
-
-void NPad::DisconnectAllConnectedControllers() {
- for (auto& controller : controller_data) {
- controller.device->Disconnect();
- }
-}
-
-void NPad::ConnectAllDisconnectedControllers() {
- for (auto& controller : controller_data) {
- if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None &&
- !controller.device->IsConnected()) {
- controller.device->Connect();
- }
- }
-}
-
-void NPad::ClearAllControllers() {
- for (auto& controller : controller_data) {
- controller.device->Disconnect();
- controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None);
- }
-}
-
-Core::HID::NpadButton NPad::GetAndResetPressState() {
- return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
-}
-
-void NPad::ApplyNpadSystemCommonPolicy() {
- Core::HID::NpadStyleTag styletag{};
- styletag.fullkey.Assign(1);
- styletag.handheld.Assign(1);
- styletag.joycon_dual.Assign(1);
- styletag.system_ext.Assign(1);
- styletag.system.Assign(1);
- SetSupportedStyleSet(styletag);
-
- SetNpadHandheldActivationMode(NpadHandheldActivationMode::Dual);
-
- supported_npad_id_types.clear();
- supported_npad_id_types.resize(10);
- supported_npad_id_types[0] = Core::HID::NpadIdType::Player1;
- supported_npad_id_types[1] = Core::HID::NpadIdType::Player2;
- supported_npad_id_types[2] = Core::HID::NpadIdType::Player3;
- supported_npad_id_types[3] = Core::HID::NpadIdType::Player4;
- supported_npad_id_types[4] = Core::HID::NpadIdType::Player5;
- supported_npad_id_types[5] = Core::HID::NpadIdType::Player6;
- supported_npad_id_types[6] = Core::HID::NpadIdType::Player7;
- supported_npad_id_types[7] = Core::HID::NpadIdType::Player8;
- supported_npad_id_types[8] = Core::HID::NpadIdType::Other;
- supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
-}
-
-bool NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
- if (controller == Core::HID::NpadStyleIndex::Handheld) {
- const bool support_handheld =
- std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
- Core::HID::NpadIdType::Handheld) != supported_npad_id_types.end();
- // Handheld is not even a supported type, lets stop here
- if (!support_handheld) {
- return false;
- }
- // Handheld shouldn't be supported in docked mode
- if (Settings::IsDockedMode()) {
- return false;
- }
-
- return true;
- }
-
- if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(),
- [](Core::HID::NpadIdType npad_id) {
- return npad_id <= Core::HID::NpadIdType::Player8;
- })) {
- Core::HID::NpadStyleTag style = GetSupportedStyleSet();
- switch (controller) {
- case Core::HID::NpadStyleIndex::ProController:
- return style.fullkey.As<bool>();
- case Core::HID::NpadStyleIndex::JoyconDual:
- return style.joycon_dual.As<bool>();
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return style.joycon_left.As<bool>();
- case Core::HID::NpadStyleIndex::JoyconRight:
- return style.joycon_right.As<bool>();
- case Core::HID::NpadStyleIndex::GameCube:
- return style.gamecube.As<bool>();
- case Core::HID::NpadStyleIndex::Pokeball:
- return style.palma.As<bool>();
- case Core::HID::NpadStyleIndex::NES:
- return style.lark.As<bool>();
- case Core::HID::NpadStyleIndex::SNES:
- return style.lucia.As<bool>();
- case Core::HID::NpadStyleIndex::N64:
- return style.lagoon.As<bool>();
- case Core::HID::NpadStyleIndex::SegaGenesis:
- return style.lager.As<bool>();
- default:
- return false;
- }
- }
-
- return false;
-}
-
-NPad::NpadControllerData& NPad::GetControllerFromHandle(
- const Core::HID::VibrationDeviceHandle& device_handle) {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(npad_id);
-}
-
-const NPad::NpadControllerData& NPad::GetControllerFromHandle(
- const Core::HID::VibrationDeviceHandle& device_handle) const {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(npad_id);
-}
-
-NPad::NpadControllerData& NPad::GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(npad_id);
-}
-
-const NPad::NpadControllerData& NPad::GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) const {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(npad_id);
-}
-
-NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- npad_id = Core::HID::NpadIdType::Player1;
- }
- const auto npad_index = NpadIdTypeToIndex(npad_id);
- return controller_data[npad_index];
-}
-
-const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(
- Core::HID::NpadIdType npad_id) const {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- npad_id = Core::HID::NpadIdType::Player1;
- }
- const auto npad_index = NpadIdTypeToIndex(npad_id);
- return controller_data[npad_index];
-}
-
-Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- switch (sixaxis_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
- return controller.shared_memory->sixaxis_fullkey_properties;
- case Core::HID::NpadStyleIndex::Handheld:
- return controller.shared_memory->sixaxis_handheld_properties;
- case Core::HID::NpadStyleIndex::JoyconDual:
- if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
- return controller.shared_memory->sixaxis_dual_left_properties;
- }
- return controller.shared_memory->sixaxis_dual_right_properties;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return controller.shared_memory->sixaxis_left_properties;
- case Core::HID::NpadStyleIndex::JoyconRight:
- return controller.shared_memory->sixaxis_right_properties;
- default:
- return controller.shared_memory->sixaxis_fullkey_properties;
- }
-}
-
-const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
- const auto& controller = GetControllerFromHandle(sixaxis_handle);
- switch (sixaxis_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
- return controller.shared_memory->sixaxis_fullkey_properties;
- case Core::HID::NpadStyleIndex::Handheld:
- return controller.shared_memory->sixaxis_handheld_properties;
- case Core::HID::NpadStyleIndex::JoyconDual:
- if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
- return controller.shared_memory->sixaxis_dual_left_properties;
- }
- return controller.shared_memory->sixaxis_dual_right_properties;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return controller.shared_memory->sixaxis_left_properties;
- case Core::HID::NpadStyleIndex::JoyconRight:
- return controller.shared_memory->sixaxis_right_properties;
- default:
- return controller.shared_memory->sixaxis_fullkey_properties;
- }
-}
-
-AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) {
- const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory;
-
- return {
- .ui_variant = 0,
- .footer = shared_memory->applet_footer_type,
- };
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
deleted file mode 100644
index 80cfcb2bb..000000000
--- a/src/core/hle/service/hid/controllers/npad.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <atomic>
-#include <mutex>
-#include <span>
-
-#include "common/common_types.h"
-#include "core/hid/hid_types.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/types/npad_types.h"
-
-namespace Core::HID {
-class EmulatedController;
-enum class ControllerTriggerType;
-} // namespace Core::HID
-
-namespace Kernel {
-class KEvent;
-class KReadableEvent;
-} // namespace Kernel
-
-namespace Service::KernelHelpers {
-class ServiceContext;
-} // namespace Service::KernelHelpers
-
-union Result;
-
-namespace Service::HID {
-class AppletResource;
-struct NpadInternalState;
-struct NpadSixAxisSensorLifo;
-struct NpadSharedMemoryFormat;
-
-class NPad final : public ControllerBase {
-public:
- explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
- ~NPad() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
- void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
- Core::HID::NpadStyleTag GetSupportedStyleSet() const;
-
- Result SetSupportedNpadIdTypes(std::span<const u8> data);
- void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
- std::size_t GetSupportedNpadIdTypesSize() const;
-
- void SetHoldType(NpadJoyHoldType joy_hold_type);
- NpadJoyHoldType GetHoldType() const;
-
- void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
- NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
-
- void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
- NpadCommunicationMode GetNpadCommunicationMode() const;
-
- bool SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
- NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
-
- bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
- const Core::HID::VibrationValue& vibration_value);
-
- void VibrateController(const Core::HID::VibrationDeviceHandle& vibration_device_handle,
- const Core::HID::VibrationValue& vibration_value);
-
- void VibrateControllers(
- std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
- std::span<const Core::HID::VibrationValue> vibration_values);
-
- Core::HID::VibrationValue GetLastVibration(
- const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
-
- void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
-
- void InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index);
-
- void SetPermitVibrationSession(bool permit_vibration_session);
-
- bool IsVibrationDeviceMounted(
- const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
-
- Kernel::KReadableEvent& GetStyleSetChangedEvent(Core::HID::NpadIdType npad_id);
- void SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const;
-
- // Adds a new controller at an index.
- void AddNewControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id);
- // Adds a new controller at an index with connection status.
- void UpdateControllerAt(Core::HID::NpadStyleIndex controller, Core::HID::NpadIdType npad_id,
- bool connected);
-
- Result DisconnectNpad(Core::HID::NpadIdType npad_id);
-
- Result IsFirmwareUpdateAvailableForSixAxisSensor(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const;
- Result ResetIsSixAxisSensorDeviceNewlyAssigned(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle);
-
- Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
- Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
- bool& is_enabled) const;
- Result SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
- Core::HID::NpadIdType npad_id);
- void SetAnalogStickUseCenterClamp(bool use_center_clamp);
- void ClearAllConnectedControllers();
- void DisconnectAllConnectedControllers();
- void ConnectAllDisconnectedControllers();
- void ClearAllControllers();
-
- Result MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
- Core::HID::NpadIdType npad_id_2);
- void StartLRAssignmentMode();
- void StopLRAssignmentMode();
- Result SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2);
-
- // Logical OR for all buttons presses on all controllers
- // Specifically for cheat engine and other features.
- Core::HID::NpadButton GetAndResetPressState();
-
- void ApplyNpadSystemCommonPolicy();
-
- AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
-
-private:
- struct VibrationData {
- bool device_mounted{};
- Core::HID::VibrationValue latest_vibration_value{};
- std::chrono::steady_clock::time_point last_vibration_timepoint{};
- };
-
- struct NpadControllerData {
- Kernel::KEvent* styleset_changed_event{};
- NpadInternalState* shared_memory = nullptr;
- Core::HID::EmulatedController* device = nullptr;
-
- std::array<VibrationData, 2> vibration{};
- bool unintended_home_button_input_protection{};
- bool is_connected{};
-
- // Dual joycons can have only one side connected
- bool is_dual_left_connected{true};
- bool is_dual_right_connected{true};
-
- // Current pad state
- NPadGenericState npad_pad_state{};
- NPadGenericState npad_libnx_state{};
- NpadGcTriggerState npad_trigger_state{};
- int callback_key{};
- };
-
- void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
- void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
- bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
- void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
- void WriteEmptyEntry(NpadInternalState* npad);
-
- NpadControllerData& GetControllerFromHandle(
- const Core::HID::VibrationDeviceHandle& device_handle);
- const NpadControllerData& GetControllerFromHandle(
- const Core::HID::VibrationDeviceHandle& device_handle) const;
- NpadControllerData& GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle);
- const NpadControllerData& GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) const;
- NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
- const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
-
- Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
- const Core::HID::SixAxisSensorHandle& device_handle);
- const Core::HID::SixAxisSensorProperties& GetSixaxisProperties(
- const Core::HID::SixAxisSensorHandle& device_handle) const;
-
- std::atomic<u64> press_state{};
-
- std::array<NpadControllerData, NpadCount> controller_data{};
- KernelHelpers::ServiceContext& service_context;
- std::mutex mutex;
- std::vector<Core::HID::NpadIdType> supported_npad_id_types{};
- NpadJoyHoldType hold_type{NpadJoyHoldType::Vertical};
- NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
- NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
- bool permit_vibration_session_enabled{false};
- bool analog_stick_use_center_clamp{false};
- bool is_in_lr_assignment_mode{false};
- bool is_controller_initialized{false};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
deleted file mode 100644
index aa0454b5e..000000000
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hid/hid_types.h"
-#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/service/hid/controllers/palma.h"
-#include "core/hle/service/kernel_helpers.h"
-
-namespace Service::HID {
-
-Palma::Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
- : ControllerBase{hid_core_}, service_context{service_context_} {
- controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
- operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
-}
-
-Palma::~Palma() {
- service_context.CloseEvent(operation_complete_event);
-};
-
-void Palma::OnInit() {}
-
-void Palma::OnRelease() {}
-
-void Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!IsControllerActivated()) {
- return;
- }
-}
-
-Result Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
- PalmaConnectionHandle& handle) {
- active_handle.npad_id = npad_id;
- handle = active_handle;
- return ResultSuccess;
-}
-
-Result Palma::InitializePalma(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- Activate();
- return ResultSuccess;
-}
-
-Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent(
- const PalmaConnectionHandle& handle) const {
- if (handle.npad_id != active_handle.npad_id) {
- LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id);
- }
- return operation_complete_event->GetReadableEvent();
-}
-
-Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
- PalmaOperationType& operation_type,
- PalmaOperationData& data) const {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation_type = operation.operation;
- data = operation.data;
- return ResultSuccess;
-}
-
-Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::PlayActivity;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- fr_mode = fr_mode_;
- return ResultSuccess;
-}
-
-Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::ReadStep;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-Result Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- return ResultSuccess;
-}
-
-Result Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- return ResultSuccess;
-}
-
-void Palma::ReadPalmaApplicationSection() {}
-
-void Palma::WritePalmaApplicationSection() {}
-
-Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::ReadUniqueCode;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::SetUniqueCodeInvalid;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-void Palma::WritePalmaActivityEntry() {}
-
-Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::WriteRgbLedPatternEntry;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
- Common::ProcessAddress t_mem, u64 size) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::WriteWaveEntry;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
- s32 database_id_version_) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- database_id_version = database_id_version_;
- operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
- operation.result = PalmaResultSuccess;
- operation.data[0] = {};
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
- operation.result = PalmaResultSuccess;
- operation.data = {};
- operation.data[0] = static_cast<u8>(database_id_version);
- operation_complete_event->Signal();
- return ResultSuccess;
-}
-
-void Palma::SuspendPalmaFeature() {}
-
-Result Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- return operation.result;
-}
-void Palma::ReadPalmaPlayLog() {}
-
-void Palma::ResetPalmaPlayLog() {}
-
-void Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
- // If true controllers are able to be paired
- is_connectable = is_all_connectable;
-}
-
-void Palma::SetIsPalmaPairedConnectable() {}
-
-Result Palma::PairPalma(const PalmaConnectionHandle& handle) {
- if (handle.npad_id != active_handle.npad_id) {
- return InvalidPalmaHandle;
- }
- // TODO: Do something
- return ResultSuccess;
-}
-
-void Palma::SetPalmaBoostMode(bool boost_mode) {}
-
-void Palma::CancelWritePalmaWaveEntry() {}
-
-void Palma::EnablePalmaBoostMode() {}
-
-void Palma::GetPalmaBluetoothAddress() {}
-
-void Palma::SetDisallowedPalmaConnection() {}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
deleted file mode 100644
index 73884230d..000000000
--- a/src/core/hle/service/hid/controllers/palma.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include "common/common_funcs.h"
-#include "common/typed_address.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/errors.h"
-
-namespace Kernel {
-class KEvent;
-class KReadableEvent;
-} // namespace Kernel
-
-namespace Service::KernelHelpers {
-class ServiceContext;
-}
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::HID {
-class Palma final : public ControllerBase {
-public:
- using PalmaOperationData = std::array<u8, 0x140>;
-
- // This is nn::hid::PalmaOperationType
- enum class PalmaOperationType {
- PlayActivity,
- SetFrModeType,
- ReadStep,
- EnableStep,
- ResetStep,
- ReadApplicationSection,
- WriteApplicationSection,
- ReadUniqueCode,
- SetUniqueCodeInvalid,
- WriteActivityEntry,
- WriteRgbLedPatternEntry,
- WriteWaveEntry,
- ReadDataBaseIdentificationVersion,
- WriteDataBaseIdentificationVersion,
- SuspendFeature,
- ReadPlayLog,
- ResetPlayLog,
- };
-
- // This is nn::hid::PalmaWaveSet
- enum class PalmaWaveSet : u64 {
- Small,
- Medium,
- Large,
- };
-
- // This is nn::hid::PalmaFrModeType
- enum class PalmaFrModeType : u64 {
- Off,
- B01,
- B02,
- B03,
- Downloaded,
- };
-
- // This is nn::hid::PalmaFeature
- enum class PalmaFeature : u64 {
- FrMode,
- RumbleFeedback,
- Step,
- MuteSwitch,
- };
-
- // This is nn::hid::PalmaOperationInfo
- struct PalmaOperationInfo {
- PalmaOperationType operation{};
- Result result{PalmaResultSuccess};
- PalmaOperationData data{};
- };
- static_assert(sizeof(PalmaOperationInfo) == 0x148, "PalmaOperationInfo is an invalid size");
-
- // This is nn::hid::PalmaActivityEntry
- struct PalmaActivityEntry {
- u32 rgb_led_pattern_index;
- INSERT_PADDING_BYTES(2);
- PalmaWaveSet wave_set;
- u32 wave_index;
- INSERT_PADDING_BYTES(12);
- };
- static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size");
-
- struct PalmaConnectionHandle {
- Core::HID::NpadIdType npad_id;
- INSERT_PADDING_BYTES(4); // Unknown
- };
- static_assert(sizeof(PalmaConnectionHandle) == 0x8,
- "PalmaConnectionHandle has incorrect size.");
-
- explicit Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
- ~Palma() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
- Result GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, PalmaConnectionHandle& handle);
- Result InitializePalma(const PalmaConnectionHandle& handle);
- Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent(
- const PalmaConnectionHandle& handle) const;
- Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
- PalmaOperationType& operation_type,
- PalmaOperationData& data) const;
- Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity);
- Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_);
- Result ReadPalmaStep(const PalmaConnectionHandle& handle);
- Result EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled);
- Result ResetPalmaStep(const PalmaConnectionHandle& handle);
- Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
- Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
- Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
- Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
- Common::ProcessAddress t_mem, u64 size);
- Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
- s32 database_id_version_);
- Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle);
- Result GetPalmaOperationResult(const PalmaConnectionHandle& handle) const;
- void SetIsPalmaAllConnectable(bool is_all_connectable);
- Result PairPalma(const PalmaConnectionHandle& handle);
- void SetPalmaBoostMode(bool boost_mode);
-
-private:
- void ReadPalmaApplicationSection();
- void WritePalmaApplicationSection();
- void WritePalmaActivityEntry();
- void SuspendPalmaFeature();
- void ReadPalmaPlayLog();
- void ResetPalmaPlayLog();
- void SetIsPalmaPairedConnectable();
- void CancelWritePalmaWaveEntry();
- void EnablePalmaBoostMode();
- void GetPalmaBluetoothAddress();
- void SetDisallowedPalmaConnection();
-
- bool is_connectable{};
- s32 database_id_version{};
- PalmaOperationInfo operation{};
- PalmaFrModeType fr_mode{};
- PalmaConnectionHandle active_handle{};
-
- Core::HID::EmulatedController* controller;
-
- Kernel::KEvent* operation_complete_event;
- KernelHelpers::ServiceContext& service_context;
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/seven_six_axis.cpp b/src/core/hle/service/hid/controllers/seven_six_axis.cpp
deleted file mode 100644
index 495568484..000000000
--- a/src/core/hle/service/hid/controllers/seven_six_axis.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include <cstring>
-#include "common/common_types.h"
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/frontend/emu_window.h"
-#include "core/hid/emulated_console.h"
-#include "core/hid/emulated_devices.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/seven_six_axis.h"
-#include "core/memory.h"
-
-namespace Service::HID {
-SevenSixAxis::SevenSixAxis(Core::System& system_)
- : ControllerBase{system_.HIDCore()}, system{system_} {
- console = hid_core.GetEmulatedConsole();
-}
-
-SevenSixAxis::~SevenSixAxis() = default;
-
-void SevenSixAxis::OnInit() {}
-void SevenSixAxis::OnRelease() {}
-
-void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!IsControllerActivated() || transfer_memory == 0) {
- seven_sixaxis_lifo.buffer_count = 0;
- seven_sixaxis_lifo.buffer_tail = 0;
- return;
- }
-
- const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state;
- next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1;
-
- const auto motion_status = console->GetMotion();
- last_global_timestamp = core_timing.GetGlobalTimeNs().count();
-
- // This value increments every time the switch goes to sleep
- next_seven_sixaxis_state.unknown = 1;
- next_seven_sixaxis_state.timestamp = last_global_timestamp - last_saved_timestamp;
- next_seven_sixaxis_state.accel = motion_status.accel;
- next_seven_sixaxis_state.gyro = motion_status.gyro;
- next_seven_sixaxis_state.quaternion = {
- {
- motion_status.quaternion.xyz.y,
- motion_status.quaternion.xyz.x,
- -motion_status.quaternion.w,
- },
- -motion_status.quaternion.xyz.z,
- };
-
- seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
- system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo,
- sizeof(seven_sixaxis_lifo));
-}
-
-void SevenSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
- transfer_memory = t_mem;
-}
-
-void SevenSixAxis::ResetTimestamp() {
- last_saved_timestamp = last_global_timestamp;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/seven_six_axis.h b/src/core/hle/service/hid/controllers/seven_six_axis.h
deleted file mode 100644
index 40e3f5d12..000000000
--- a/src/core/hle/service/hid/controllers/seven_six_axis.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "common/quaternion.h"
-#include "common/typed_address.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/ring_lifo.h"
-
-namespace Core {
-class System;
-} // namespace Core
-
-namespace Core::HID {
-class EmulatedConsole;
-} // namespace Core::HID
-
-namespace Service::HID {
-class SevenSixAxis final : public ControllerBase {
-public:
- explicit SevenSixAxis(Core::System& system_);
- ~SevenSixAxis() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
- // Called on InitializeSevenSixAxisSensor
- void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
-
- // Called on ResetSevenSixAxisSensorTimestamp
- void ResetTimestamp();
-
-private:
- struct SevenSixAxisState {
- INSERT_PADDING_WORDS(2); // unused
- u64 timestamp{};
- u64 sampling_number{};
- u64 unknown{};
- Common::Vec3f accel{};
- Common::Vec3f gyro{};
- Common::Quaternion<f32> quaternion{};
- };
- static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size");
-
- Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
- static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
-
- u64 last_saved_timestamp{};
- u64 last_global_timestamp{};
-
- SevenSixAxisState next_seven_sixaxis_state{};
- Common::ProcessAddress transfer_memory{};
- Core::HID::EmulatedConsole* console = nullptr;
-
- Core::System& system;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
deleted file mode 100644
index 0bc5169c6..000000000
--- a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/core.h"
-#include "core/hle/kernel/k_shared_memory.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/shared_memory_holder.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-#include "core/hle/service/hid/errors.h"
-
-namespace Service::HID {
-SharedMemoryHolder::SharedMemoryHolder() {}
-
-SharedMemoryHolder::~SharedMemoryHolder() {
- Finalize();
-}
-
-Result SharedMemoryHolder::Initialize(Core::System& system) {
- shared_memory = Kernel::KSharedMemory::Create(system.Kernel());
- const Result result = shared_memory->Initialize(
- system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None,
- Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat));
- if (result.IsError()) {
- return result;
- }
- Kernel::KSharedMemory::Register(system.Kernel(), shared_memory);
-
- is_created = true;
- is_mapped = true;
- address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer()));
- return ResultSuccess;
-}
-
-void SharedMemoryHolder::Finalize() {
- if (address != nullptr) {
- shared_memory->Close();
- }
- is_created = false;
- is_mapped = false;
- address = nullptr;
-}
-
-bool SharedMemoryHolder::IsMapped() {
- return is_mapped;
-}
-
-SharedMemoryFormat* SharedMemoryHolder::GetAddress() {
- return address;
-}
-
-Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() {
- return shared_memory;
-}
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.h b/src/core/hle/service/hid/controllers/shared_memory_holder.h
deleted file mode 100644
index 943407c00..000000000
--- a/src/core/hle/service/hid/controllers/shared_memory_holder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "core/hle/result.h"
-
-namespace Core {
-class System;
-}
-
-namespace Kernel {
-class KSharedMemory;
-}
-
-namespace Service::HID {
-struct SharedMemoryFormat;
-
-// This is nn::hid::detail::SharedMemoryHolder
-class SharedMemoryHolder {
-public:
- SharedMemoryHolder();
- ~SharedMemoryHolder();
-
- Result Initialize(Core::System& system);
- void Finalize();
-
- bool IsMapped();
- SharedMemoryFormat* GetAddress();
- Kernel::KSharedMemory* GetHandle();
-
-private:
- bool is_owner{};
- bool is_created{};
- bool is_mapped{};
- INSERT_PADDING_BYTES(0x5);
- Kernel::KSharedMemory* shared_memory;
- INSERT_PADDING_BYTES(0x38);
- SharedMemoryFormat* address = nullptr;
-};
-// Correct size is 0x50 bytes
-static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size");
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp
deleted file mode 100644
index a5a67dea6..000000000
--- a/src/core/hle/service/hid/controllers/six_axis.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "common/common_types.h"
-#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/six_axis.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-#include "core/hle/service/hid/errors.h"
-#include "core/hle/service/hid/hid_util.h"
-
-namespace Service::HID {
-
-SixAxis::SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_)
- : ControllerBase{hid_core_}, npad{npad_} {
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- auto& controller = controller_data[i];
- controller.device = hid_core.GetEmulatedControllerByIndex(i);
- }
-}
-
-SixAxis::~SixAxis() = default;
-
-void SixAxis::OnInit() {}
-void SixAxis::OnRelease() {}
-
-void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- if (!IsControllerActivated()) {
- return;
- }
-
- for (std::size_t i = 0; i < controller_data.size(); ++i) {
- NpadSharedMemoryEntry& shared_memory = data->shared_memory_format->npad.npad_entry[i];
- auto& controller = controller_data[i];
- const auto& controller_type = controller.device->GetNpadStyleIndex();
-
- if (controller_type == Core::HID::NpadStyleIndex::None ||
- !controller.device->IsConnected()) {
- continue;
- }
-
- const auto& motion_state = controller.device->GetMotions();
- auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
- auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
- auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
- auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
- auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
- auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
-
- auto& sixaxis_fullkey_lifo = shared_memory.internal_state.sixaxis_fullkey_lifo;
- auto& sixaxis_handheld_lifo = shared_memory.internal_state.sixaxis_handheld_lifo;
- auto& sixaxis_dual_left_lifo = shared_memory.internal_state.sixaxis_dual_left_lifo;
- auto& sixaxis_dual_right_lifo = shared_memory.internal_state.sixaxis_dual_right_lifo;
- auto& sixaxis_left_lifo = shared_memory.internal_state.sixaxis_left_lifo;
- auto& sixaxis_right_lifo = shared_memory.internal_state.sixaxis_right_lifo;
-
- // Clear previous state
- sixaxis_fullkey_state = {};
- sixaxis_handheld_state = {};
- sixaxis_dual_left_state = {};
- sixaxis_dual_right_state = {};
- sixaxis_left_lifo_state = {};
- sixaxis_right_lifo_state = {};
-
- if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) {
- controller.sixaxis_at_rest = true;
- for (std::size_t e = 0; e < motion_state.size(); ++e) {
- controller.sixaxis_at_rest =
- controller.sixaxis_at_rest && motion_state[e].is_at_rest;
- }
- }
-
- const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state,
- const Core::HID::ControllerMotion& hid_state) {
- using namespace std::literals::chrono_literals;
- static constexpr Core::HID::SixAxisSensorState default_motion_state = {
- .delta_time = std::chrono::nanoseconds(5ms).count(),
- .accel = {0, 0, -1.0f},
- .orientation =
- {
- Common::Vec3f{1.0f, 0, 0},
- Common::Vec3f{0, 1.0f, 0},
- Common::Vec3f{0, 0, 1.0f},
- },
- .attribute = {1},
- };
- if (!controller.sixaxis_sensor_enabled) {
- state = default_motion_state;
- return;
- }
- if (!Settings::values.motion_enabled.GetValue()) {
- state = default_motion_state;
- return;
- }
- state.attribute.is_connected.Assign(1);
- state.delta_time = std::chrono::nanoseconds(5ms).count();
- state.accel = hid_state.accel;
- state.gyro = hid_state.gyro;
- state.rotation = hid_state.rotation;
- state.orientation = hid_state.orientation;
- };
-
- switch (controller_type) {
- case Core::HID::NpadStyleIndex::None:
- ASSERT(false);
- break;
- case Core::HID::NpadStyleIndex::ProController:
- set_motion_state(sixaxis_fullkey_state, motion_state[0]);
- break;
- case Core::HID::NpadStyleIndex::Handheld:
- set_motion_state(sixaxis_handheld_state, motion_state[0]);
- break;
- case Core::HID::NpadStyleIndex::JoyconDual:
- set_motion_state(sixaxis_dual_left_state, motion_state[0]);
- set_motion_state(sixaxis_dual_right_state, motion_state[1]);
- break;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- set_motion_state(sixaxis_left_lifo_state, motion_state[0]);
- break;
- case Core::HID::NpadStyleIndex::JoyconRight:
- set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
- break;
- case Core::HID::NpadStyleIndex::Pokeball:
- using namespace std::literals::chrono_literals;
- set_motion_state(sixaxis_fullkey_state, motion_state[0]);
- sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
- break;
- default:
- break;
- }
-
- sixaxis_fullkey_state.sampling_number =
- sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_handheld_state.sampling_number =
- sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_dual_left_state.sampling_number =
- sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_dual_right_state.sampling_number =
- sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_left_lifo_state.sampling_number =
- sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
- sixaxis_right_lifo_state.sampling_number =
- sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
-
- if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
- // This buffer only is updated on handheld on HW
- sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state);
- } else {
- // Handheld doesn't update this buffer on HW
- sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state);
- }
-
- sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state);
- sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state);
- sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state);
- sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state);
- }
-}
-
-Result SixAxis::SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode drift_mode) {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- sixaxis.gyroscope_zero_drift_mode = drift_mode;
- controller.device->SetGyroscopeZeroDriftMode(drift_mode);
-
- return ResultSuccess;
-}
-
-Result SixAxis::GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- drift_mode = sixaxis.gyroscope_zero_drift_mode;
-
- return ResultSuccess;
-}
-
-Result SixAxis::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_at_rest) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& controller = GetControllerFromHandle(sixaxis_handle);
- is_at_rest = controller.sixaxis_at_rest;
- return ResultSuccess;
-}
-
-Result SixAxis::LoadSixAxisSensorCalibrationParameter(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorCalibrationParameter& calibration) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- // TODO: Request this data to the controller. On error return 0xd8ca
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- calibration = sixaxis.calibration;
- return ResultSuccess;
-}
-
-Result SixAxis::GetSixAxisSensorIcInformation(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorIcInformation& ic_information) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- // TODO: Request this data to the controller. On error return 0xd8ca
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- ic_information = sixaxis.ic_information;
- return ResultSuccess;
-}
-
-Result SixAxis::EnableSixAxisSensorUnalteredPassthrough(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- sixaxis.unaltered_passtrough = is_enabled;
- return ResultSuccess;
-}
-
-Result SixAxis::IsSixAxisSensorUnalteredPassthroughEnabled(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- is_enabled = sixaxis.unaltered_passtrough;
- return ResultSuccess;
-}
-
-Result SixAxis::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool sixaxis_status) {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- controller.sixaxis_sensor_enabled = sixaxis_status;
- return ResultSuccess;
-}
-
-Result SixAxis::IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_fusion_enabled) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- is_fusion_enabled = sixaxis.is_fusion_enabled;
-
- return ResultSuccess;
-}
-Result SixAxis::SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool is_fusion_enabled) {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- sixaxis.is_fusion_enabled = is_fusion_enabled;
-
- return ResultSuccess;
-}
-
-Result SixAxis::SetSixAxisFusionParameters(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto param1 = sixaxis_fusion_parameters.parameter1;
- if (param1 < 0.0f || param1 > 1.0f) {
- return InvalidSixAxisFusionRange;
- }
-
- auto& sixaxis = GetSixaxisState(sixaxis_handle);
- sixaxis.fusion = sixaxis_fusion_parameters;
-
- return ResultSuccess;
-}
-
-Result SixAxis::GetSixAxisFusionParameters(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters& parameters) const {
- const auto is_valid = IsSixaxisHandleValid(sixaxis_handle);
- if (is_valid.IsError()) {
- LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
- return is_valid;
- }
-
- const auto& sixaxis = GetSixaxisState(sixaxis_handle);
- parameters = sixaxis.fusion;
-
- return ResultSuccess;
-}
-
-SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) {
- auto& controller = GetControllerFromHandle(sixaxis_handle);
- switch (sixaxis_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
- return controller.sixaxis_fullkey;
- case Core::HID::NpadStyleIndex::Handheld:
- return controller.sixaxis_handheld;
- case Core::HID::NpadStyleIndex::JoyconDual:
- if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
- return controller.sixaxis_dual_left;
- }
- return controller.sixaxis_dual_right;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return controller.sixaxis_left;
- case Core::HID::NpadStyleIndex::JoyconRight:
- return controller.sixaxis_right;
- default:
- return controller.sixaxis_unknown;
- }
-}
-
-const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle) const {
- const auto& controller = GetControllerFromHandle(sixaxis_handle);
- switch (sixaxis_handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
- return controller.sixaxis_fullkey;
- case Core::HID::NpadStyleIndex::Handheld:
- return controller.sixaxis_handheld;
- case Core::HID::NpadStyleIndex::JoyconDual:
- if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) {
- return controller.sixaxis_dual_left;
- }
- return controller.sixaxis_dual_right;
- case Core::HID::NpadStyleIndex::JoyconLeft:
- return controller.sixaxis_left;
- case Core::HID::NpadStyleIndex::JoyconRight:
- return controller.sixaxis_right;
- default:
- return controller.sixaxis_unknown;
- }
-}
-
-SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(npad_id);
-}
-
-const SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) const {
- const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
- return GetControllerFromNpadIdType(npad_id);
-}
-
-SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- npad_id = Core::HID::NpadIdType::Player1;
- }
- const auto npad_index = NpadIdTypeToIndex(npad_id);
- return controller_data[npad_index];
-}
-
-const SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(
- Core::HID::NpadIdType npad_id) const {
- if (!IsNpadIdValid(npad_id)) {
- LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- npad_id = Core::HID::NpadIdType::Player1;
- }
- const auto npad_index = NpadIdTypeToIndex(npad_id);
- return controller_data[npad_index];
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.h b/src/core/hle/service/hid/controllers/six_axis.h
deleted file mode 100644
index 4c4f5dc7b..000000000
--- a/src/core/hle/service/hid/controllers/six_axis.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hid/hid_types.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/ring_lifo.h"
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::HID {
-class NPad;
-
-class SixAxis final : public ControllerBase {
-public:
- explicit SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_);
- ~SixAxis() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
- Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode drift_mode);
- Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
- Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_at_rest) const;
- Result EnableSixAxisSensorUnalteredPassthrough(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled);
- Result IsSixAxisSensorUnalteredPassthroughEnabled(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const;
- Result LoadSixAxisSensorCalibrationParameter(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorCalibrationParameter& calibration) const;
- Result GetSixAxisSensorIcInformation(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorIcInformation& ic_information) const;
- Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool sixaxis_status);
- Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool& is_fusion_enabled) const;
- Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- bool is_fusion_enabled);
- Result SetSixAxisFusionParameters(
- const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters);
- Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
- Core::HID::SixAxisSensorFusionParameters& parameters) const;
-
-private:
- static constexpr std::size_t NPAD_COUNT = 10;
-
- struct SixaxisParameters {
- bool is_fusion_enabled{true};
- bool unaltered_passtrough{false};
- Core::HID::SixAxisSensorFusionParameters fusion{};
- Core::HID::SixAxisSensorCalibrationParameter calibration{};
- Core::HID::SixAxisSensorIcInformation ic_information{};
- Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
- Core::HID::GyroscopeZeroDriftMode::Standard};
- };
-
- struct NpadControllerData {
- Core::HID::EmulatedController* device = nullptr;
-
- // Motion parameters
- bool sixaxis_at_rest{true};
- bool sixaxis_sensor_enabled{true};
- SixaxisParameters sixaxis_fullkey{};
- SixaxisParameters sixaxis_handheld{};
- SixaxisParameters sixaxis_dual_left{};
- SixaxisParameters sixaxis_dual_right{};
- SixaxisParameters sixaxis_left{};
- SixaxisParameters sixaxis_right{};
- SixaxisParameters sixaxis_unknown{};
-
- // Current pad state
- Core::HID::SixAxisSensorState sixaxis_fullkey_state{};
- Core::HID::SixAxisSensorState sixaxis_handheld_state{};
- Core::HID::SixAxisSensorState sixaxis_dual_left_state{};
- Core::HID::SixAxisSensorState sixaxis_dual_right_state{};
- Core::HID::SixAxisSensorState sixaxis_left_lifo_state{};
- Core::HID::SixAxisSensorState sixaxis_right_lifo_state{};
- int callback_key{};
- };
-
- SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle);
- const SixaxisParameters& GetSixaxisState(
- const Core::HID::SixAxisSensorHandle& device_handle) const;
-
- NpadControllerData& GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle);
- const NpadControllerData& GetControllerFromHandle(
- const Core::HID::SixAxisSensorHandle& device_handle) const;
- NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
- const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
-
- std::shared_ptr<NPad> npad;
- std::array<NpadControllerData, NPAD_COUNT> controller_data{};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/sleep_button.cpp b/src/core/hle/service/hid/controllers/sleep_button.cpp
deleted file mode 100644
index 978dc4c1f..000000000
--- a/src/core/hle/service/hid/controllers/sleep_button.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/sleep_button.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-SleepButton::SleepButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
-
-SleepButton::~SleepButton() = default;
-
-void SleepButton::OnInit() {}
-
-void SleepButton::OnRelease() {}
-
-void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- auto& header = data->shared_memory_format->capture_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/sleep_button.h b/src/core/hle/service/hid/controllers/sleep_button.h
deleted file mode 100644
index 59964bf63..000000000
--- a/src/core/hle/service/hid/controllers/sleep_button.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Service::HID {
-
-class SleepButton final : public ControllerBase {
-public:
- explicit SleepButton(Core::HID::HIDCore& hid_core_);
- ~SleepButton() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- bool smart_update{};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
deleted file mode 100644
index 291dc707e..000000000
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <algorithm>
-#include "common/common_types.h"
-#include "common/settings.h"
-#include "core/core_timing.h"
-#include "core/frontend/emu_window.h"
-#include "core/hid/emulated_console.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-
-namespace Service::HID {
-
-TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_)
- : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width),
- touchscreen_height(Layout::ScreenUndocked::Height) {
- console = hid_core.GetEmulatedConsole();
-}
-
-TouchScreen::~TouchScreen() = default;
-
-void TouchScreen::OnInit() {}
-
-void TouchScreen::OnRelease() {}
-
-void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- TouchScreenSharedMemoryFormat& shared_memory = data->shared_memory_format->touch_screen;
- shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
-
- if (!IsControllerActivated()) {
- shared_memory.touch_screen_lifo.buffer_count = 0;
- shared_memory.touch_screen_lifo.buffer_tail = 0;
- return;
- }
-
- const auto touch_status = console->GetTouch();
- for (std::size_t id = 0; id < MAX_FINGERS; id++) {
- const auto& current_touch = touch_status[id];
- auto& finger = fingers[id];
- finger.id = current_touch.id;
-
- if (finger.attribute.start_touch) {
- finger.attribute.raw = 0;
- continue;
- }
-
- if (finger.attribute.end_touch) {
- finger.attribute.raw = 0;
- finger.pressed = false;
- continue;
- }
-
- if (!finger.pressed && current_touch.pressed) {
- // Ignore all touch fingers if disabled
- if (!Settings::values.touchscreen.enabled) {
- continue;
- }
-
- finger.attribute.start_touch.Assign(1);
- finger.pressed = true;
- finger.position = current_touch.position;
- continue;
- }
-
- if (finger.pressed && !current_touch.pressed) {
- finger.attribute.raw = 0;
- finger.attribute.end_touch.Assign(1);
- continue;
- }
-
- // Only update position if touch is not on a special frame
- finger.position = current_touch.position;
- }
-
- std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers;
- const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(),
- [](const auto& finger) { return finger.pressed; });
- const auto active_fingers_count =
- static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
-
- const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count());
- const auto& last_entry = shared_memory.touch_screen_lifo.ReadCurrentEntry().state;
-
- next_state.sampling_number = last_entry.sampling_number + 1;
- next_state.entry_count = static_cast<s32>(active_fingers_count);
-
- for (std::size_t id = 0; id < MAX_FINGERS; ++id) {
- auto& touch_entry = next_state.states[id];
- if (id < active_fingers_count) {
- const auto& [active_x, active_y] = active_fingers[id].position;
- touch_entry.position = {
- .x = static_cast<u16>(active_x * static_cast<float>(touchscreen_width)),
- .y = static_cast<u16>(active_y * static_cast<float>(touchscreen_height)),
- };
- touch_entry.diameter_x = Settings::values.touchscreen.diameter_x;
- touch_entry.diameter_y = Settings::values.touchscreen.diameter_y;
- touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle;
- touch_entry.delta_time = timestamp - active_fingers[id].last_touch;
- fingers[active_fingers[id].id].last_touch = timestamp;
- touch_entry.finger = active_fingers[id].id;
- touch_entry.attribute.raw = active_fingers[id].attribute.raw;
- } else {
- // Clear touch entry
- touch_entry.attribute.raw = 0;
- touch_entry.position = {};
- touch_entry.diameter_x = 0;
- touch_entry.diameter_y = 0;
- touch_entry.rotation_angle = 0;
- touch_entry.delta_time = 0;
- touch_entry.finger = 0;
- }
- }
-
- shared_memory.touch_screen_lifo.WriteNextEntry(next_state);
-}
-
-void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) {
- touchscreen_width = width;
- touchscreen_height = height;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
deleted file mode 100644
index 945d359be..000000000
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-
-#include "core/hid/hid_types.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/types/touch_types.h"
-
-namespace Core::HID {
-class EmulatedConsole;
-} // namespace Core::HID
-
-namespace Service::HID {
-struct TouchScreenSharedMemoryFormat;
-
-class TouchScreen final : public ControllerBase {
-public:
- explicit TouchScreen(Core::HID::HIDCore& hid_core_);
- ~TouchScreen() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
- void SetTouchscreenDimensions(u32 width, u32 height);
-
-private:
- TouchScreenState next_state{};
- Core::HID::EmulatedConsole* console = nullptr;
-
- std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
- u32 touchscreen_width;
- u32 touchscreen_height;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/debug_pad_types.h b/src/core/hle/service/hid/controllers/types/debug_pad_types.h
deleted file mode 100644
index a96171b62..000000000
--- a/src/core/hle/service/hid/controllers/types/debug_pad_types.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "core/hid/hid_types.h"
-
-namespace Service::HID {
-
-// This is nn::hid::DebugPadAttribute
-struct DebugPadAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> connected;
- };
-};
-static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size");
-
-// This is nn::hid::DebugPadState
-struct DebugPadState {
- s64 sampling_number{};
- DebugPadAttribute attribute{};
- Core::HID::DebugPadButton pad_state{};
- Core::HID::AnalogStickState r_stick{};
- Core::HID::AnalogStickState l_stick{};
-};
-static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/gesture_types.h b/src/core/hle/service/hid/controllers/types/gesture_types.h
deleted file mode 100644
index b4f034cd3..000000000
--- a/src/core/hle/service/hid/controllers/types/gesture_types.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <array>
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "common/point.h"
-
-namespace Service::HID {
-static constexpr size_t MAX_FINGERS = 16;
-static constexpr size_t MAX_POINTS = 4;
-
-// This is nn::hid::GestureType
-enum class GestureType : u32 {
- Idle, // Nothing touching the screen
- Complete, // Set at the end of a touch event
- Cancel, // Set when the number of fingers change
- Touch, // A finger just touched the screen
- Press, // Set if last type is touch and the finger hasn't moved
- Tap, // Fast press then release
- Pan, // All points moving together across the screen
- Swipe, // Fast press movement and release of a single point
- Pinch, // All points moving away/closer to the midpoint
- Rotate, // All points rotating from the midpoint
-};
-
-// This is nn::hid::GestureDirection
-enum class GestureDirection : u32 {
- None,
- Left,
- Up,
- Right,
- Down,
-};
-
-// This is nn::hid::GestureAttribute
-struct GestureAttribute {
- union {
- u32 raw{};
-
- BitField<4, 1, u32> is_new_touch;
- BitField<8, 1, u32> is_double_tap;
- };
-};
-static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size");
-
-// This is nn::hid::GestureState
-struct GestureState {
- s64 sampling_number{};
- s64 detection_count{};
- GestureType type{GestureType::Idle};
- GestureDirection direction{GestureDirection::None};
- Common::Point<s32> pos{};
- Common::Point<s32> delta{};
- f32 vel_x{};
- f32 vel_y{};
- GestureAttribute attributes{};
- f32 scale{};
- f32 rotation_angle{};
- s32 point_count{};
- std::array<Common::Point<s32>, 4> points{};
-};
-static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
-
-struct GestureProperties {
- std::array<Common::Point<s32>, MAX_POINTS> points{};
- std::size_t active_points{};
- Common::Point<s32> mid_point{};
- s64 detection_count{};
- u64 delta_time{};
- f32 average_distance{};
- f32 angle{};
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/keyboard_types.h b/src/core/hle/service/hid/controllers/types/keyboard_types.h
deleted file mode 100644
index f44a536b9..000000000
--- a/src/core/hle/service/hid/controllers/types/keyboard_types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hid/hid_types.h"
-
-namespace Service::HID {
-
-// This is nn::hid::detail::KeyboardState
-struct KeyboardState {
- s64 sampling_number{};
- Core::HID::KeyboardModifier modifier{};
- Core::HID::KeyboardAttribute attribute{};
- Core::HID::KeyboardKey key{};
-};
-static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/mouse_types.h b/src/core/hle/service/hid/controllers/types/mouse_types.h
deleted file mode 100644
index 8bd6e167c..000000000
--- a/src/core/hle/service/hid/controllers/types/mouse_types.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-
-namespace Service::HID {} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/npad_types.h b/src/core/hle/service/hid/controllers/types/npad_types.h
deleted file mode 100644
index a5ce2562b..000000000
--- a/src/core/hle/service/hid/controllers/types/npad_types.h
+++ /dev/null
@@ -1,254 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/bit_field.h"
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "core/hid/hid_types.h"
-
-namespace Service::HID {
-static constexpr std::size_t NpadCount = 10;
-
-// This is nn::hid::NpadJoyHoldType
-enum class NpadJoyHoldType : u64 {
- Vertical = 0,
- Horizontal = 1,
-};
-
-// This is nn::hid::NpadJoyAssignmentMode
-enum class NpadJoyAssignmentMode : u32 {
- Dual = 0,
- Single = 1,
-};
-
-// This is nn::hid::NpadJoyDeviceType
-enum class NpadJoyDeviceType : s64 {
- Left = 0,
- Right = 1,
-};
-
-// This is nn::hid::NpadHandheldActivationMode
-enum class NpadHandheldActivationMode : u64 {
- Dual = 0,
- Single = 1,
- None = 2,
- MaxActivationMode = 3,
-};
-
-// This is nn::hid::system::AppletFooterUiAttributesSet
-struct AppletFooterUiAttributes {
- INSERT_PADDING_BYTES(0x4);
-};
-
-// This is nn::hid::system::AppletFooterUiType
-enum class AppletFooterUiType : u8 {
- None = 0,
- HandheldNone = 1,
- HandheldJoyConLeftOnly = 2,
- HandheldJoyConRightOnly = 3,
- HandheldJoyConLeftJoyConRight = 4,
- JoyDual = 5,
- JoyDualLeftOnly = 6,
- JoyDualRightOnly = 7,
- JoyLeftHorizontal = 8,
- JoyLeftVertical = 9,
- JoyRightHorizontal = 10,
- JoyRightVertical = 11,
- SwitchProController = 12,
- CompatibleProController = 13,
- CompatibleJoyCon = 14,
- LarkHvc1 = 15,
- LarkHvc2 = 16,
- LarkNesLeft = 17,
- LarkNesRight = 18,
- Lucia = 19,
- Verification = 20,
- Lagon = 21,
-};
-
-using AppletFooterUiVariant = u8;
-
-// This is "nn::hid::system::AppletDetailedUiType".
-struct AppletDetailedUiType {
- AppletFooterUiVariant ui_variant;
- INSERT_PADDING_BYTES(0x2);
- AppletFooterUiType footer;
-};
-static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
-// This is nn::hid::NpadCommunicationMode
-enum class NpadCommunicationMode : u64 {
- Mode_5ms = 0,
- Mode_10ms = 1,
- Mode_15ms = 2,
- Default = 3,
-};
-
-enum class NpadRevision : u32 {
- Revision0 = 0,
- Revision1 = 1,
- Revision2 = 2,
- Revision3 = 3,
-};
-
-// This is nn::hid::detail::ColorAttribute
-enum class ColorAttribute : u32 {
- Ok = 0,
- ReadError = 1,
- NoController = 2,
-};
-static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size");
-
-// This is nn::hid::detail::NpadFullKeyColorState
-struct NpadFullKeyColorState {
- ColorAttribute attribute{ColorAttribute::NoController};
- Core::HID::NpadControllerColor fullkey{};
-};
-static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
-
-// This is nn::hid::detail::NpadJoyColorState
-struct NpadJoyColorState {
- ColorAttribute attribute{ColorAttribute::NoController};
- Core::HID::NpadControllerColor left{};
- Core::HID::NpadControllerColor right{};
-};
-static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
-
-// This is nn::hid::NpadAttribute
-struct NpadAttribute {
- union {
- u32 raw{};
- BitField<0, 1, u32> is_connected;
- BitField<1, 1, u32> is_wired;
- BitField<2, 1, u32> is_left_connected;
- BitField<3, 1, u32> is_left_wired;
- BitField<4, 1, u32> is_right_connected;
- BitField<5, 1, u32> is_right_wired;
- };
-};
-static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size");
-
-// This is nn::hid::NpadFullKeyState
-// This is nn::hid::NpadHandheldState
-// This is nn::hid::NpadJoyDualState
-// This is nn::hid::NpadJoyLeftState
-// This is nn::hid::NpadJoyRightState
-// This is nn::hid::NpadPalmaState
-// This is nn::hid::NpadSystemExtState
-struct NPadGenericState {
- s64_le sampling_number{};
- Core::HID::NpadButtonState npad_buttons{};
- Core::HID::AnalogStickState l_stick{};
- Core::HID::AnalogStickState r_stick{};
- NpadAttribute connection_status{};
- INSERT_PADDING_BYTES(4); // Reserved
-};
-static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
-
-// This is nn::hid::server::NpadGcTriggerState
-struct NpadGcTriggerState {
- s64 sampling_number{};
- s32 l_analog{};
- s32 r_analog{};
-};
-static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
-
-// This is nn::hid::NpadSystemProperties
-struct NPadSystemProperties {
- union {
- s64 raw{};
- BitField<0, 1, s64> is_charging_joy_dual;
- BitField<1, 1, s64> is_charging_joy_left;
- BitField<2, 1, s64> is_charging_joy_right;
- BitField<3, 1, s64> is_powered_joy_dual;
- BitField<4, 1, s64> is_powered_joy_left;
- BitField<5, 1, s64> is_powered_joy_right;
- BitField<9, 1, s64> is_system_unsupported_button;
- BitField<10, 1, s64> is_system_ext_unsupported_button;
- BitField<11, 1, s64> is_vertical;
- BitField<12, 1, s64> is_horizontal;
- BitField<13, 1, s64> use_plus;
- BitField<14, 1, s64> use_minus;
- BitField<15, 1, s64> use_directional_buttons;
- };
-};
-static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
-
-// This is nn::hid::NpadSystemButtonProperties
-struct NpadSystemButtonProperties {
- union {
- s32 raw{};
- BitField<0, 1, s32> is_home_button_protection_enabled;
- };
-};
-static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size");
-
-// This is nn::hid::system::DeviceType
-struct DeviceType {
- union {
- u32 raw{};
- BitField<0, 1, s32> fullkey;
- BitField<1, 1, s32> debug_pad;
- BitField<2, 1, s32> handheld_left;
- BitField<3, 1, s32> handheld_right;
- BitField<4, 1, s32> joycon_left;
- BitField<5, 1, s32> joycon_right;
- BitField<6, 1, s32> palma;
- BitField<7, 1, s32> lark_hvc_left;
- BitField<8, 1, s32> lark_hvc_right;
- BitField<9, 1, s32> lark_nes_left;
- BitField<10, 1, s32> lark_nes_right;
- BitField<11, 1, s32> handheld_lark_hvc_left;
- BitField<12, 1, s32> handheld_lark_hvc_right;
- BitField<13, 1, s32> handheld_lark_nes_left;
- BitField<14, 1, s32> handheld_lark_nes_right;
- BitField<15, 1, s32> lucia;
- BitField<16, 1, s32> lagon;
- BitField<17, 1, s32> lager;
- BitField<31, 1, s32> system;
- };
-};
-
-// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
-struct NfcXcdDeviceHandleStateImpl {
- u64 handle{};
- bool is_available{};
- bool is_activated{};
- INSERT_PADDING_BYTES(0x6); // Reserved
- u64 sampling_number{};
-};
-static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
- "NfcXcdDeviceHandleStateImpl is an invalid size");
-
-// This is nn::hid::NpadLarkType
-enum class NpadLarkType : u32 {
- Invalid,
- H1,
- H2,
- NL,
- NR,
-};
-
-// This is nn::hid::NpadLuciaType
-enum class NpadLuciaType : u32 {
- Invalid,
- J,
- E,
- U,
-};
-
-// This is nn::hid::NpadLagonType
-enum class NpadLagonType : u32 {
- Invalid,
-};
-
-// This is nn::hid::NpadLagerType
-enum class NpadLagerType : u32 {
- Invalid,
- J,
- E,
- U,
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/shared_memory_format.h b/src/core/hle/service/hid/controllers/types/shared_memory_format.h
deleted file mode 100644
index 2986c113e..000000000
--- a/src/core/hle/service/hid/controllers/types/shared_memory_format.h
+++ /dev/null
@@ -1,240 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "common/vector_math.h"
-#include "core/hid/hid_types.h"
-#include "core/hle/service/hid//controllers/types/debug_pad_types.h"
-#include "core/hle/service/hid//controllers/types/keyboard_types.h"
-#include "core/hle/service/hid//controllers/types/mouse_types.h"
-#include "core/hle/service/hid//controllers/types/npad_types.h"
-#include "core/hle/service/hid//controllers/types/touch_types.h"
-#include "core/hle/service/hid/ring_lifo.h"
-
-namespace Service::HID {
-static const std::size_t HidEntryCount = 17;
-
-struct CommonHeader {
- s64 timestamp{};
- s64 total_entry_count{};
- s64 last_entry_index{};
- s64 entry_count{};
-};
-static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
-
-// This is nn::hid::detail::DebugPadSharedMemoryFormat
-struct DebugPadSharedMemoryFormat {
- // This is nn::hid::detail::DebugPadLifo
- Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{};
- static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
- INSERT_PADDING_WORDS(0x4E);
-};
-static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400,
- "DebugPadSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::TouchScreenSharedMemoryFormat
-struct TouchScreenSharedMemoryFormat {
- // This is nn::hid::detail::TouchScreenLifo
- Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{};
- static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
- INSERT_PADDING_WORDS(0xF2);
-};
-static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000,
- "TouchScreenSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::MouseSharedMemoryFormat
-struct MouseSharedMemoryFormat {
- // This is nn::hid::detail::MouseLifo
- Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{};
- static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
- INSERT_PADDING_WORDS(0x2C);
-};
-static_assert(sizeof(MouseSharedMemoryFormat) == 0x400,
- "MouseSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::KeyboardSharedMemoryFormat
-struct KeyboardSharedMemoryFormat {
- // This is nn::hid::detail::KeyboardLifo
- Lifo<KeyboardState, HidEntryCount> keyboard_lifo{};
- static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size");
- INSERT_PADDING_WORDS(0xA);
-};
-static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400,
- "KeyboardSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::DigitizerSharedMemoryFormat
-struct DigitizerSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0xFE0);
-};
-static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000,
- "DigitizerSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::HomeButtonSharedMemoryFormat
-struct HomeButtonSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x1E0);
-};
-static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200,
- "HomeButtonSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::SleepButtonSharedMemoryFormat
-struct SleepButtonSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x1E0);
-};
-static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200,
- "SleepButtonSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::CaptureButtonSharedMemoryFormat
-struct CaptureButtonSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x1E0);
-};
-static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200,
- "CaptureButtonSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::InputDetectorSharedMemoryFormat
-struct InputDetectorSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x7E0);
-};
-static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800,
- "InputDetectorSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::UniquePadSharedMemoryFormat
-struct UniquePadSharedMemoryFormat {
- CommonHeader header;
- INSERT_PADDING_BYTES(0x3FE0);
-};
-static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000,
- "UniquePadSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::NpadSixAxisSensorLifo
-struct NpadSixAxisSensorLifo {
- Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo;
-};
-
-// This is nn::hid::detail::NpadInternalState
-struct NpadInternalState {
- Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
- NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual};
- NpadFullKeyColorState fullkey_color{};
- NpadJoyColorState joycon_color{};
- Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{};
- Lifo<NPadGenericState, HidEntryCount> handheld_lifo{};
- Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{};
- Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{};
- Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{};
- Lifo<NPadGenericState, HidEntryCount> palma_lifo{};
- Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{};
- NpadSixAxisSensorLifo sixaxis_fullkey_lifo{};
- NpadSixAxisSensorLifo sixaxis_handheld_lifo{};
- NpadSixAxisSensorLifo sixaxis_dual_left_lifo{};
- NpadSixAxisSensorLifo sixaxis_dual_right_lifo{};
- NpadSixAxisSensorLifo sixaxis_left_lifo{};
- NpadSixAxisSensorLifo sixaxis_right_lifo{};
- DeviceType device_type{};
- INSERT_PADDING_BYTES(0x4); // Reserved
- NPadSystemProperties system_properties{};
- NpadSystemButtonProperties button_properties{};
- Core::HID::NpadBatteryLevel battery_level_dual{};
- Core::HID::NpadBatteryLevel battery_level_left{};
- Core::HID::NpadBatteryLevel battery_level_right{};
- AppletFooterUiAttributes applet_footer_attributes{};
- AppletFooterUiType applet_footer_type{AppletFooterUiType::None};
- INSERT_PADDING_BYTES(0x5B); // Reserved
- INSERT_PADDING_BYTES(0x20); // Unknown
- Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{};
- NpadLarkType lark_type_l_and_main{};
- NpadLarkType lark_type_r{};
- NpadLuciaType lucia_type{};
- NpadLagerType lager_type{};
- Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties;
- Core::HID::SixAxisSensorProperties sixaxis_handheld_properties;
- Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties;
- Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties;
- Core::HID::SixAxisSensorProperties sixaxis_left_properties;
- Core::HID::SixAxisSensorProperties sixaxis_right_properties;
-};
-static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size");
-
-// This is nn::hid::detail::NpadSharedMemoryEntry
-struct NpadSharedMemoryEntry {
- NpadInternalState internal_state;
- INSERT_PADDING_BYTES(0xC08);
-};
-static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size");
-
-// This is nn::hid::detail::NpadSharedMemoryFormat
-struct NpadSharedMemoryFormat {
- std::array<NpadSharedMemoryEntry, NpadCount> npad_entry;
-};
-static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000,
- "NpadSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::GestureSharedMemoryFormat
-struct GestureSharedMemoryFormat {
- // This is nn::hid::detail::GestureLifo
- Lifo<GestureState, HidEntryCount> gesture_lifo{};
- static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
- INSERT_PADDING_WORDS(0x3E);
-};
-static_assert(sizeof(GestureSharedMemoryFormat) == 0x800,
- "GestureSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
-struct ConsoleSixAxisSensorSharedMemoryFormat {
- u64 sampling_number{};
- bool is_seven_six_axis_sensor_at_rest{};
- INSERT_PADDING_BYTES(3); // padding
- f32 verticalization_error{};
- Common::Vec3f gyro_bias{};
- INSERT_PADDING_BYTES(4); // padding
-};
-static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20,
- "ConsoleSixAxisSensorSharedMemoryFormat is an invalid size");
-
-// This is nn::hid::detail::SharedMemoryFormat
-struct SharedMemoryFormat {
- void Initialize() {}
-
- DebugPadSharedMemoryFormat debug_pad;
- TouchScreenSharedMemoryFormat touch_screen;
- MouseSharedMemoryFormat mouse;
- KeyboardSharedMemoryFormat keyboard;
- DigitizerSharedMemoryFormat digitizer;
- HomeButtonSharedMemoryFormat home_button;
- SleepButtonSharedMemoryFormat sleep_button;
- CaptureButtonSharedMemoryFormat capture_button;
- InputDetectorSharedMemoryFormat input_detector;
- UniquePadSharedMemoryFormat unique_pad;
- NpadSharedMemoryFormat npad;
- GestureSharedMemoryFormat gesture;
- ConsoleSixAxisSensorSharedMemoryFormat console;
- INSERT_PADDING_BYTES(0x19E0);
- MouseSharedMemoryFormat debug_mouse;
- INSERT_PADDING_BYTES(0x2000);
-};
-static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00,
- "sleep_button has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000,
- "capture_button has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200,
- "input_detector has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset");
-static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset");
-static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size");
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/touch_types.h b/src/core/hle/service/hid/controllers/types/touch_types.h
deleted file mode 100644
index efeaa796d..000000000
--- a/src/core/hle/service/hid/controllers/types/touch_types.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <array>
-
-#include <array>
-#include "common/bit_field.h"
-#include "common/common_funcs.h"
-#include "common/common_types.h"
-#include "common/point.h"
-#include "core/hid/hid_types.h"
-
-namespace Service::HID {
-static constexpr std::size_t MAX_FINGERS = 16;
-static constexpr size_t MAX_POINTS = 4;
-
-// This is nn::hid::GestureType
-enum class GestureType : u32 {
- Idle, // Nothing touching the screen
- Complete, // Set at the end of a touch event
- Cancel, // Set when the number of fingers change
- Touch, // A finger just touched the screen
- Press, // Set if last type is touch and the finger hasn't moved
- Tap, // Fast press then release
- Pan, // All points moving together across the screen
- Swipe, // Fast press movement and release of a single point
- Pinch, // All points moving away/closer to the midpoint
- Rotate, // All points rotating from the midpoint
-};
-
-// This is nn::hid::GestureDirection
-enum class GestureDirection : u32 {
- None,
- Left,
- Up,
- Right,
- Down,
-};
-
-// This is nn::hid::GestureAttribute
-struct GestureAttribute {
- union {
- u32 raw{};
-
- BitField<4, 1, u32> is_new_touch;
- BitField<8, 1, u32> is_double_tap;
- };
-};
-static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size");
-
-// This is nn::hid::GestureState
-struct GestureState {
- s64 sampling_number{};
- s64 detection_count{};
- GestureType type{GestureType::Idle};
- GestureDirection direction{GestureDirection::None};
- Common::Point<s32> pos{};
- Common::Point<s32> delta{};
- f32 vel_x{};
- f32 vel_y{};
- GestureAttribute attributes{};
- f32 scale{};
- f32 rotation_angle{};
- s32 point_count{};
- std::array<Common::Point<s32>, 4> points{};
-};
-static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
-
-struct GestureProperties {
- std::array<Common::Point<s32>, MAX_POINTS> points{};
- std::size_t active_points{};
- Common::Point<s32> mid_point{};
- s64 detection_count{};
- u64 delta_time{};
- f32 average_distance{};
- f32 angle{};
-};
-
-// This is nn::hid::TouchScreenState
-struct TouchScreenState {
- s64 sampling_number{};
- s32 entry_count{};
- INSERT_PADDING_BYTES(4); // Reserved
- std::array<Core::HID::TouchState, MAX_FINGERS> states{};
-};
-static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size");
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/unique_pad.cpp b/src/core/hle/service/hid/controllers/unique_pad.cpp
deleted file mode 100644
index 8230501a5..000000000
--- a/src/core/hle/service/hid/controllers/unique_pad.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-#include "core/hle/service/hid/controllers/unique_pad.h"
-
-namespace Service::HID {
-
-UniquePad::UniquePad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
-
-UniquePad::~UniquePad() = default;
-
-void UniquePad::OnInit() {}
-
-void UniquePad::OnRelease() {}
-
-void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
- const u64 aruid = applet_resource->GetActiveAruid();
- auto* data = applet_resource->GetAruidData(aruid);
-
- if (data == nullptr) {
- return;
- }
-
- auto& header = data->shared_memory_format->capture_button.header;
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/unique_pad.h b/src/core/hle/service/hid/controllers/unique_pad.h
deleted file mode 100644
index 966368264..000000000
--- a/src/core/hle/service/hid/controllers/unique_pad.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hid/controllers/controller_base.h"
-
-namespace Service::HID {
-
-class UniquePad final : public ControllerBase {
-public:
- explicit UniquePad(Core::HID::HIDCore& hid_core_);
- ~UniquePad() override;
-
- // Called when the controller is initialized
- void OnInit() override;
-
- // When the controller is released
- void OnRelease() override;
-
- // When the controller is requesting an update for the shared memory
- void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
-
-private:
- bool smart_update{};
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
deleted file mode 100644
index 6dc976fe1..000000000
--- a/src/core/hle/service/hid/errors.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/result.h"
-
-namespace Service::HID {
-
-constexpr Result PalmaResultSuccess{ErrorModule::HID, 0};
-constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};
-constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
-constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122};
-constexpr Result VibrationInvalidNpadId{ErrorModule::HID, 123};
-constexpr Result VibrationDeviceIndexOutOfRange{ErrorModule::HID, 124};
-constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423};
-constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
-constexpr Result NpadIsSameType{ErrorModule::HID, 602};
-constexpr Result InvalidNpadId{ErrorModule::HID, 709};
-constexpr Result NpadNotConnected{ErrorModule::HID, 710};
-constexpr Result InvalidArraySize{ErrorModule::HID, 715};
-
-constexpr Result ResultAppletResourceOverflow{ErrorModule::HID, 1041};
-constexpr Result ResultAppletResourceNotInitialized{ErrorModule::HID, 1042};
-constexpr Result ResultSharedMemoryNotInitialized{ErrorModule::HID, 1043};
-constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044};
-constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046};
-constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047};
-
-constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
-
-} // namespace Service::HID
-
-namespace Service::IRS {
-
-constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78};
-constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204};
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index afbcb019f..fc8a3ab66 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -5,14 +5,14 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/hid_debug_server.h"
-#include "core/hle/service/hid/hid_firmware_settings.h"
#include "core/hle/service/hid/hid_server.h"
#include "core/hle/service/hid/hid_system_server.h"
#include "core/hle/service/hid/hidbus.h"
#include "core/hle/service/hid/irs.h"
-#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/hid/xcd.h"
#include "core/hle/service/server_manager.h"
+#include "hid_core/resource_manager.h"
+#include "hid_core/resources/hid_firmware_settings.h"
namespace Service::HID {
@@ -25,6 +25,7 @@ void LoopProcess(Core::System& system) {
// TODO: Remove this hack until this service is emulated properly.
const auto process_list = system.Kernel().GetProcessList();
if (!process_list.empty()) {
+ resouce_manager->Initialize();
resouce_manager->RegisterAppletResourceUserId(process_list[0]->GetId(), true);
}
diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp
index 6294f3dfb..f2a767d37 100644
--- a/src/core/hle/service/hid/hid_debug_server.cpp
+++ b/src/core/hle/service/hid/hid_debug_server.cpp
@@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_debug_server.h"
-#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
+#include "hid_core/resource_manager.h"
namespace Service::HID {
diff --git a/src/core/hle/service/hid/hid_firmware_settings.cpp b/src/core/hle/service/hid/hid_firmware_settings.cpp
deleted file mode 100644
index 59bd6825c..000000000
--- a/src/core/hle/service/hid/hid_firmware_settings.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/hle/service/hid/hid_firmware_settings.h"
-
-namespace Service::HID {
-
-HidFirmwareSettings::HidFirmwareSettings() {
- LoadSettings(true);
-}
-
-void HidFirmwareSettings::Reload() {
- LoadSettings(true);
-}
-
-void HidFirmwareSettings::LoadSettings(bool reload_config) {
- if (is_initalized && !reload_config) {
- return;
- }
-
- // TODO: Use nn::settings::fwdbg::GetSettingsItemValue to load config values
-
- is_debug_pad_enabled = true;
- is_device_managed = true;
- is_touch_i2c_managed = is_device_managed;
- is_future_devices_emulated = false;
- is_mcu_hardware_error_emulated = false;
- is_rail_enabled = true;
- is_firmware_update_failure_emulated = false;
- is_firmware_update_failure = {};
- is_ble_disabled = false;
- is_dscale_disabled = false;
- is_handheld_forced = true;
- features_per_id_disabled = {};
- is_touch_firmware_auto_update_disabled = false;
- is_initalized = true;
-}
-
-bool HidFirmwareSettings::IsDebugPadEnabled() {
- LoadSettings(false);
- return is_debug_pad_enabled;
-}
-
-bool HidFirmwareSettings::IsDeviceManaged() {
- LoadSettings(false);
- return is_device_managed;
-}
-
-bool HidFirmwareSettings::IsEmulateFutureDevice() {
- LoadSettings(false);
- return is_future_devices_emulated;
-}
-
-bool HidFirmwareSettings::IsTouchI2cManaged() {
- LoadSettings(false);
- return is_touch_i2c_managed;
-}
-
-bool HidFirmwareSettings::IsHandheldForced() {
- LoadSettings(false);
- return is_handheld_forced;
-}
-
-bool HidFirmwareSettings::IsRailEnabled() {
- LoadSettings(false);
- return is_rail_enabled;
-}
-
-bool HidFirmwareSettings::IsHardwareErrorEmulated() {
- LoadSettings(false);
- return is_mcu_hardware_error_emulated;
-}
-
-bool HidFirmwareSettings::IsBleDisabled() {
- LoadSettings(false);
- return is_ble_disabled;
-}
-
-bool HidFirmwareSettings::IsDscaleDisabled() {
- LoadSettings(false);
- return is_dscale_disabled;
-}
-
-bool HidFirmwareSettings::IsTouchAutoUpdateDisabled() {
- LoadSettings(false);
- return is_touch_firmware_auto_update_disabled;
-}
-
-HidFirmwareSettings::FirmwareSetting HidFirmwareSettings::GetFirmwareUpdateFailure() {
- LoadSettings(false);
- return is_firmware_update_failure;
-}
-
-HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId() {
- LoadSettings(false);
- return features_per_id_disabled;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_firmware_settings.h b/src/core/hle/service/hid/hid_firmware_settings.h
deleted file mode 100644
index 6c10c440b..000000000
--- a/src/core/hle/service/hid/hid_firmware_settings.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-
-namespace Service::HID {
-
-/// Loads firmware config from nn::settings::fwdbg
-class HidFirmwareSettings {
-public:
- using FirmwareSetting = std::array<u8, 4>;
- using FeaturesPerId = std::array<bool, 0xA8>;
-
- HidFirmwareSettings();
-
- void Reload();
- void LoadSettings(bool reload_config);
-
- bool IsDebugPadEnabled();
- bool IsDeviceManaged();
- bool IsEmulateFutureDevice();
- bool IsTouchI2cManaged();
- bool IsHandheldForced();
- bool IsRailEnabled();
- bool IsHardwareErrorEmulated();
- bool IsBleDisabled();
- bool IsDscaleDisabled();
- bool IsTouchAutoUpdateDisabled();
-
- FirmwareSetting GetFirmwareUpdateFailure();
- FeaturesPerId FeaturesDisabledPerId();
-
-private:
- bool is_initalized{};
-
- // Debug settings
- bool is_debug_pad_enabled{};
- bool is_device_managed{};
- bool is_touch_i2c_managed{};
- bool is_future_devices_emulated{};
- bool is_mcu_hardware_error_emulated{};
- bool is_rail_enabled{};
- bool is_firmware_update_failure_emulated{};
- bool is_ble_disabled{};
- bool is_dscale_disabled{};
- bool is_handheld_forced{};
- bool is_touch_firmware_auto_update_disabled{};
- FirmwareSetting is_firmware_update_failure{};
- FeaturesPerId features_per_id_disabled{};
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 3174672af..2ff00d30d 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -5,30 +5,29 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/settings.h"
-#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/service/hid/errors.h"
-#include "core/hle/service/hid/hid_firmware_settings.h"
#include "core/hle/service/hid/hid_server.h"
-#include "core/hle/service/hid/hid_util.h"
-#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/memory.h"
-
-#include "core/hle/service/hid/controllers/console_six_axis.h"
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/hle/service/hid/controllers/mouse.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/palma.h"
-#include "core/hle/service/hid/controllers/seven_six_axis.h"
-#include "core/hle/service/hid/controllers/six_axis.h"
-#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/hle/service/hid/controllers/types/npad_types.h"
+#include "hid_core/hid_result.h"
+#include "hid_core/hid_util.h"
+#include "hid_core/resource_manager.h"
+#include "hid_core/resources/hid_firmware_settings.h"
+
+#include "hid_core/resources/controller_base.h"
+#include "hid_core/resources/debug_pad/debug_pad.h"
+#include "hid_core/resources/keyboard/keyboard.h"
+#include "hid_core/resources/mouse/mouse.h"
+#include "hid_core/resources/npad/npad.h"
+#include "hid_core/resources/npad/npad_types.h"
+#include "hid_core/resources/palma/palma.h"
+#include "hid_core/resources/six_axis/console_six_axis.h"
+#include "hid_core/resources/six_axis/seven_six_axis.h"
+#include "hid_core/resources/six_axis/six_axis.h"
+#include "hid_core/resources/touch_screen/gesture.h"
+#include "hid_core/resources/touch_screen/touch_screen.h"
namespace Service::HID {
@@ -785,8 +784,8 @@ void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ct
bool is_firmware_available{};
auto controller = GetResourceManager()->GetNpad();
- controller->IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
- is_firmware_available);
+ controller->IsFirmwareUpdateAvailableForSixAxisSensor(
+ parameters.applet_resource_user_id, parameters.sixaxis_handle, is_firmware_available);
LOG_WARNING(
Service_HID,
@@ -924,8 +923,8 @@ void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx)
const auto parameters{rp.PopRaw<Parameters>()};
auto controller = GetResourceManager()->GetNpad();
- const auto result =
- controller->ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
+ const auto result = controller->ResetIsSixAxisSensorDeviceNewlyAssigned(
+ parameters.applet_resource_user_id, parameters.sixaxis_handle);
LOG_WARNING(
Service_HID,
@@ -970,7 +969,7 @@ void IHidServer::ActivateGesture(HLERequestContext& ctx) {
void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
- Core::HID::NpadStyleSet supported_styleset;
+ Core::HID::NpadStyleSet supported_style_set;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
@@ -978,13 +977,25 @@ void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- GetResourceManager()->GetNpad()->SetSupportedStyleSet({parameters.supported_styleset});
+ LOG_DEBUG(Service_HID, "called, supported_style_set={}, applet_resource_user_id={}",
+ parameters.supported_style_set, parameters.applet_resource_user_id);
- LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
- parameters.supported_styleset, parameters.applet_resource_user_id);
+ const auto npad = GetResourceManager()->GetNpad();
+ const Result result = npad->SetSupportedNpadStyleSet(parameters.applet_resource_user_id,
+ parameters.supported_style_set);
+
+ if (result.IsSuccess()) {
+ Core::HID::NpadStyleTag style_tag{parameters.supported_style_set};
+ const auto revision = npad->GetRevision(parameters.applet_resource_user_id);
+
+ if (style_tag.palma != 0 && revision < NpadRevision::Revision3) {
+ // GetResourceManager()->GetPalma()->EnableBoostMode(parameters.applet_resource_user_id,
+ // true);
+ }
+ }
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
@@ -993,19 +1004,31 @@ void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ Core::HID::NpadStyleSet supported_style_set{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->GetSupportedNpadStyleSet(applet_resource_user_id, supported_style_set);
+
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw);
+ rb.Push(result);
+ rb.PushEnum(supported_style_set);
}
void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
-
- const auto result = GetResourceManager()->GetNpad()->SetSupportedNpadIdTypes(ctx.ReadBuffer());
+ const auto buffer = ctx.ReadBuffer();
+ const std::size_t elements = ctx.GetReadBufferNumElements<Core::HID::NpadIdType>();
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ std::vector<Core::HID::NpadIdType> supported_npad_list(elements);
+ memcpy(supported_npad_list.data(), buffer.data(), buffer.size());
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const Result result =
+ npad->SetSupportedNpadIdType(applet_resource_user_id, supported_npad_list);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
@@ -1018,7 +1041,7 @@ void IHidServer::ActivateNpad(HLERequestContext& ctx) {
auto npad = GetResourceManager()->GetNpad();
- // TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
+ npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
const Result result = npad->Activate(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -1052,13 +1075,13 @@ void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
- // Games expect this event to be signaled after calling this function
- GetResourceManager()->GetNpad()->SignalStyleSetChangedEvent(parameters.npad_id);
+ Kernel::KReadableEvent* style_set_update_event;
+ const auto result = GetResourceManager()->GetNpad()->AcquireNpadStyleSetUpdateEventHandle(
+ parameters.applet_resource_user_id, &style_set_update_event, parameters.npad_id);
IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(
- GetResourceManager()->GetNpad()->GetStyleSetChangedEvent(parameters.npad_id));
+ rb.Push(result);
+ rb.PushCopyObjects(style_set_update_event);
}
void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
@@ -1073,7 +1096,7 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
auto controller = GetResourceManager()->GetNpad();
- controller->DisconnectNpad(parameters.npad_id);
+ controller->DisconnectNpad(parameters.applet_resource_user_id, parameters.npad_id);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
@@ -1113,7 +1136,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
auto npad = GetResourceManager()->GetNpad();
- // TODO: npad->SetRevision(applet_resource_user_id, revision);
+ npad->SetRevision(parameters.applet_resource_user_id, parameters.revision);
const auto result = npad->Activate(parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -1125,13 +1148,19 @@ void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto hold_type{rp.PopEnum<NpadJoyHoldType>()};
- GetResourceManager()->GetNpad()->SetHoldType(hold_type);
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
applet_resource_user_id, hold_type);
+ if (hold_type != NpadJoyHoldType::Horizontal && hold_type != NpadJoyHoldType::Vertical) {
+ // This should crash console
+ ASSERT_MSG(false, "Invalid npad joy hold type");
+ }
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->SetNpadJoyHoldType(applet_resource_user_id, hold_type);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
@@ -1140,9 +1169,13 @@ void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ NpadJoyHoldType hold_type{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->GetNpadJoyHoldType(applet_resource_user_id, hold_type);
+
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetHoldType());
+ rb.Push(result);
+ rb.PushEnum(hold_type);
}
void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
@@ -1158,8 +1191,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx)
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
- controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left,
- NpadJoyAssignmentMode::Single);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
+ NpadJoyDeviceType::Left, NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
@@ -1182,8 +1215,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
- controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
- NpadJoyAssignmentMode::Single);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
+ parameters.npad_joy_device_type, NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
parameters.npad_id, parameters.applet_resource_user_id,
@@ -1206,7 +1239,8 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
- controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id, {},
+ NpadJoyAssignmentMode::Dual);
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id); // Spams a lot when controller applet is open
@@ -1222,7 +1256,8 @@ void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
auto controller = GetResourceManager()->GetNpad();
- const auto result = controller->MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
+ const auto result =
+ controller->MergeSingleJoyAsDualJoy(applet_resource_user_id, npad_id_1, npad_id_2);
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
@@ -1235,10 +1270,10 @@ void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- GetResourceManager()->GetNpad()->StartLRAssignmentMode();
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ GetResourceManager()->GetNpad()->StartLrAssignmentMode(applet_resource_user_id);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -1247,10 +1282,10 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
- GetResourceManager()->GetNpad()->StopLRAssignmentMode();
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ GetResourceManager()->GetNpad()->StopLrAssignmentMode(applet_resource_user_id);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -1260,13 +1295,23 @@ void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()};
- GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode);
-
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
applet_resource_user_id, activation_mode);
+ if (activation_mode >= NpadHandheldActivationMode::MaxActivationMode) {
+ // Console should crash here
+ ASSERT_MSG(false, "Activation mode should be always None, Single or Dual");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ return;
+ }
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->SetNpadHandheldActivationMode(applet_resource_user_id, activation_mode);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(result);
}
void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
@@ -1275,9 +1320,14 @@ void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ NpadHandheldActivationMode activation_mode{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->GetNpadHandheldActivationMode(applet_resource_user_id, activation_mode);
+
IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadHandheldActivationMode());
+ rb.Push(result);
+ rb.PushEnum(activation_mode);
}
void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
@@ -1286,12 +1336,12 @@ void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
- auto controller = GetResourceManager()->GetNpad();
- const auto result = controller->SwapNpadAssignment(npad_id_1, npad_id_2);
-
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
npad_id_1, npad_id_2, applet_resource_user_id);
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->SwapNpadAssignment(applet_resource_user_id, npad_id_1, npad_id_2);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
@@ -1307,13 +1357,19 @@ void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext&
const auto parameters{rp.PopRaw<Parameters>()};
- bool is_enabled = false;
- auto controller = GetResourceManager()->GetNpad();
- const auto result =
- controller->IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
+ parameters.applet_resource_user_id);
- LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
- parameters.npad_id, parameters.applet_resource_user_id);
+ if (!IsNpadIdValid(parameters.npad_id)) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultInvalidNpadId);
+ return;
+ }
+
+ bool is_enabled{};
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->IsUnintendedHomeButtonInputProtectionEnabled(
+ is_enabled, parameters.applet_resource_user_id, parameters.npad_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(result);
@@ -1332,13 +1388,18 @@ void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ct
const auto parameters{rp.PopRaw<Parameters>()};
- auto controller = GetResourceManager()->GetNpad();
- const auto result = controller->SetUnintendedHomeButtonInputProtectionEnabled(
- parameters.is_enabled, parameters.npad_id);
+ LOG_INFO(Service_HID, "called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
+ parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
- LOG_DEBUG(Service_HID,
- "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
- parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
+ if (!IsNpadIdValid(parameters.npad_id)) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultInvalidNpadId);
+ return;
+ }
+
+ const auto npad = GetResourceManager()->GetNpad();
+ const auto result = npad->EnableUnintendedHomeButtonInputProtection(
+ parameters.applet_resource_user_id, parameters.npad_id, parameters.is_enabled);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
@@ -1359,8 +1420,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
Core::HID::NpadIdType new_npad_id{};
auto controller = GetResourceManager()->GetNpad();
const auto is_reassigned =
- controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
- NpadJoyAssignmentMode::Single);
+ controller->SetNpadMode(parameters.applet_resource_user_id, new_npad_id, parameters.npad_id,
+ parameters.npad_joy_device_type, NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
parameters.npad_id, parameters.applet_resource_user_id,
@@ -1375,7 +1436,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
- bool analog_stick_use_center_clamp;
+ bool use_center_clamp;
INSERT_PADDING_BYTES_NOINIT(7);
u64 applet_resource_user_id;
};
@@ -1383,12 +1444,11 @@ void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- GetResourceManager()->GetNpad()->SetAnalogStickUseCenterClamp(
- parameters.analog_stick_use_center_clamp);
+ LOG_WARNING(Service_HID, "(STUBBED) called, use_center_clamp={}, applet_resource_user_id={}",
+ parameters.use_center_clamp, parameters.applet_resource_user_id);
- LOG_WARNING(Service_HID,
- "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
- parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
+ GetResourceManager()->GetNpad()->SetNpadAnalogStickUseCenterClamp(
+ parameters.applet_resource_user_id, parameters.use_center_clamp);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -1496,7 +1556,8 @@ void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
+ GetResourceManager()->GetNpad()->VibrateController(parameters.applet_resource_user_id,
+ parameters.vibration_device_handle,
parameters.vibration_value);
LOG_DEBUG(Service_HID,
@@ -1528,8 +1589,8 @@ void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess);
- rb.PushRaw(
- GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle));
+ rb.PushRaw(GetResourceManager()->GetNpad()->GetLastVibration(
+ parameters.applet_resource_user_id, parameters.vibration_device_handle));
}
void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
@@ -1580,7 +1641,8 @@ void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
auto vibration_values = std::span(
reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
- GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values);
+ GetResourceManager()->GetNpad()->VibrateControllers(applet_resource_user_id,
+ vibration_device_handles, vibration_values);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
@@ -1634,8 +1696,8 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
}
}();
- GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle,
- vibration_value);
+ GetResourceManager()->GetNpad()->VibrateController(
+ parameters.applet_resource_user_id, parameters.vibration_device_handle, vibration_value);
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
@@ -1659,8 +1721,8 @@ void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
- const auto last_vibration =
- GetResourceManager()->GetNpad()->GetLastVibration(parameters.vibration_device_handle);
+ const auto last_vibration = GetResourceManager()->GetNpad()->GetLastVibration(
+ parameters.applet_resource_user_id, parameters.vibration_device_handle);
const auto gc_erm_command = [last_vibration] {
if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
@@ -1732,7 +1794,7 @@ void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted(
- parameters.vibration_device_handle));
+ parameters.applet_resource_user_id, parameters.vibration_device_handle));
}
void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
@@ -2315,10 +2377,10 @@ void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
const auto applet_resource_user_id{rp.Pop<u64>()};
const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()};
- GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode);
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, communication_mode={}",
+ applet_resource_user_id, communication_mode);
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
- applet_resource_user_id, communication_mode);
+ // This function has been stubbed since 2.0.0+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -2326,12 +2388,15 @@ void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_WARNING(Service_HID, "(STUBBED) called");
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ // This function has been stubbed since 2.0.0+
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
- rb.PushEnum(GetResourceManager()->GetNpad()->GetNpadCommunicationMode());
+ rb.PushEnum(NpadCommunicationMode::Default);
}
void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 5cc88c4a1..2a65615e8 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -1,15 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/palma.h"
-#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/hle/service/hid/controllers/types/npad_types.h"
-#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_system_server.h"
-#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
+#include "hid_core/hid_result.h"
+#include "hid_core/resource_manager.h"
+#include "hid_core/resources/npad/npad.h"
+#include "hid_core/resources/npad/npad_types.h"
+#include "hid_core/resources/palma/palma.h"
+#include "hid_core/resources/touch_screen/touch_screen.h"
namespace Service::HID {
@@ -82,7 +81,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{522, nullptr, "SetJoyConRailEnabled"},
{523, nullptr, "IsJoyConRailEnabled"},
{524, nullptr, "IsHandheldHidsEnabled"},
- {525, nullptr, "IsJoyConAttachedOnAllRail"},
+ {525, &IHidSystemServer::IsJoyConAttachedOnAllRail, "IsJoyConAttachedOnAllRail"},
{540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
{541, nullptr, "GetPlayReportControllerUsages"},
{542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
@@ -132,7 +131,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1001, nullptr, "GetFirmwareVersion"},
{1002, nullptr, "GetAvailableFirmwareVersion"},
{1003, nullptr, "IsFirmwareUpdateAvailable"},
- {1004, nullptr, "CheckFirmwareUpdateRequired"},
+ {1004, &IHidSystemServer::CheckFirmwareUpdateRequired, "CheckFirmwareUpdateRequired"},
{1005, nullptr, "StartFirmwareUpdate"},
{1006, nullptr, "AbortFirmwareUpdate"},
{1007, nullptr, "GetFirmwareUpdateState"},
@@ -145,9 +144,9 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
{1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
{1100, nullptr, "GetHidbusSystemServiceObject"},
- {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
- {1130, nullptr, "InitializeUsbFirmwareUpdate"},
- {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
+ {1120, &IHidSystemServer::SetFirmwareHotfixUpdateSkipEnabled, "SetFirmwareHotfixUpdateSkipEnabled"},
+ {1130, &IHidSystemServer::InitializeUsbFirmwareUpdate, "InitializeUsbFirmwareUpdate"},
+ {1131, &IHidSystemServer::FinalizeUsbFirmwareUpdate, "FinalizeUsbFirmwareUpdate"},
{1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
{1133, nullptr, "StartUsbFirmwareUpdate"},
{1134, nullptr, "GetUsbFirmwareUpdateState"},
@@ -197,7 +196,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{1268, nullptr, "DeleteButtonConfigStorageFull"},
{1269, nullptr, "DeleteButtonConfigStorageLeft"},
{1270, nullptr, "DeleteButtonConfigStorageRight"},
- {1271, nullptr, "IsUsingCustomButtonConfig"},
+ {1271, &IHidSystemServer::IsUsingCustomButtonConfig, "IsUsingCustomButtonConfig"},
{1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
{1273, nullptr, "SetAllCustomButtonConfigEnabled"},
{1274, nullptr, "SetDefaultButtonConfig"},
@@ -240,9 +239,12 @@ IHidSystemServer::~IHidSystemServer() {
};
void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "called");
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
+ GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -267,13 +269,16 @@ void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.PushEnum(system.HIDCore().GetLastActiveController());
+ rb.Push(0); // Dont forget to fix this
}
void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
- LOG_WARNING(Service_HID, "called");
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
- GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicy();
+ LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+ GetResourceManager()->GetNpad()->ApplyNpadSystemCommonPolicyFull(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -298,28 +303,32 @@ void IHidSystemServer::GetNpadFullKeyGripColor(HLERequestContext& ctx) {
void IHidSystemServer::GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_INFO(Service_HID, "(STUBBED) called");
+ LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- Core::HID::NpadStyleSet supported_styleset =
- GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
+ Core::HID::NpadStyleSet supported_styleset{};
+ const auto& npad = GetResourceManager()->GetNpad();
+ const Result result =
+ npad->GetMaskedSupportedNpadStyleSet(applet_resource_user_id, supported_styleset);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
+ rb.Push(result);
rb.PushEnum(supported_styleset);
}
void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
- LOG_INFO(Service_HID, "(STUBBED) called");
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- Core::HID::NpadStyleSet supported_styleset =
- GetResourceManager()->GetNpad()->GetSupportedStyleSet().raw;
+ const auto& npad = GetResourceManager()->GetNpad();
+ const auto result =
+ npad->SetSupportedNpadStyleSet(applet_resource_user_id, Core::HID::NpadStyleSet::All);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(supported_styleset);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
}
void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
@@ -546,6 +555,16 @@ void IHidSystemServer::EnableAppletToGetTouchScreen(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void IHidSystemServer::IsJoyConAttachedOnAllRail(HLERequestContext& ctx) {
+ const bool is_attached = true;
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, is_attached={}", is_attached);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(is_attached);
+}
+
void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
LOG_INFO(Service_AM, "(STUBBED) called");
@@ -632,6 +651,34 @@ void IHidSystemServer::InitializeFirmwareUpdate(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void IHidSystemServer::CheckFirmwareUpdateRequired(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::SetFirmwareHotfixUpdateSkipEnabled(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::InitializeUsbFirmwareUpdate(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IHidSystemServer::FinalizeUsbFirmwareUpdate(HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called");
@@ -656,6 +703,16 @@ void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx
rb.PushRaw(touchscreen_config);
}
+void IHidSystemServer::IsUsingCustomButtonConfig(HLERequestContext& ctx) {
+ const bool is_enabled = false;
+
+ LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(is_enabled);
+}
+
std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() {
resource_manager->Initialize();
return resource_manager;
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
index 1e623dfc2..f467e2aa8 100644
--- a/src/core/hle/service/hid/hid_system_server.h
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -44,6 +44,7 @@ private:
void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx);
void EnableAppletToGetPadInput(HLERequestContext& ctx);
void EnableAppletToGetTouchScreen(HLERequestContext& ctx);
+ void IsJoyConAttachedOnAllRail(HLERequestContext& ctx);
void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
void GetRegisteredDevices(HLERequestContext& ctx);
@@ -53,8 +54,13 @@ private:
void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
void InitializeFirmwareUpdate(HLERequestContext& ctx);
+ void CheckFirmwareUpdateRequired(HLERequestContext& ctx);
+ void SetFirmwareHotfixUpdateSkipEnabled(HLERequestContext& ctx);
+ void InitializeUsbFirmwareUpdate(HLERequestContext& ctx);
+ void FinalizeUsbFirmwareUpdate(HLERequestContext& ctx);
void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
+ void IsUsingCustomButtonConfig(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> GetResourceManager();
diff --git a/src/core/hle/service/hid/hid_util.h b/src/core/hle/service/hid/hid_util.h
deleted file mode 100644
index b87cc10e3..000000000
--- a/src/core/hle/service/hid/hid_util.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "core/hid/hid_types.h"
-#include "core/hle/service/hid/errors.h"
-
-namespace Service::HID {
-
-constexpr bool IsNpadIdValid(const Core::HID::NpadIdType npad_id) {
- switch (npad_id) {
- case Core::HID::NpadIdType::Player1:
- case Core::HID::NpadIdType::Player2:
- case Core::HID::NpadIdType::Player3:
- case Core::HID::NpadIdType::Player4:
- case Core::HID::NpadIdType::Player5:
- case Core::HID::NpadIdType::Player6:
- case Core::HID::NpadIdType::Player7:
- case Core::HID::NpadIdType::Player8:
- case Core::HID::NpadIdType::Other:
- case Core::HID::NpadIdType::Handheld:
- return true;
- default:
- return false;
- }
-}
-
-constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& handle) {
- const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id));
- const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
-
- if (!npad_id) {
- return InvalidNpadId;
- }
- if (!device_index) {
- return NpadDeviceIndexOutOfRange;
- }
-
- return ResultSuccess;
-}
-
-constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) {
- switch (handle.npad_type) {
- case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Handheld:
- case Core::HID::NpadStyleIndex::JoyconDual:
- case Core::HID::NpadStyleIndex::JoyconLeft:
- case Core::HID::NpadStyleIndex::JoyconRight:
- case Core::HID::NpadStyleIndex::GameCube:
- case Core::HID::NpadStyleIndex::N64:
- case Core::HID::NpadStyleIndex::SystemExt:
- case Core::HID::NpadStyleIndex::System:
- // These support vibration
- break;
- default:
- return VibrationInvalidStyleIndex;
- }
-
- if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) {
- return VibrationInvalidNpadId;
- }
-
- if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) {
- return VibrationDeviceIndexOutOfRange;
- }
-
- return ResultSuccess;
-}
-
-/// Converts a Core::HID::NpadIdType to an array index.
-constexpr size_t NpadIdTypeToIndex(Core::HID::NpadIdType npad_id_type) {
- switch (npad_id_type) {
- case Core::HID::NpadIdType::Player1:
- return 0;
- case Core::HID::NpadIdType::Player2:
- return 1;
- case Core::HID::NpadIdType::Player3:
- return 2;
- case Core::HID::NpadIdType::Player4:
- return 3;
- case Core::HID::NpadIdType::Player5:
- return 4;
- case Core::HID::NpadIdType::Player6:
- return 5;
- case Core::HID::NpadIdType::Player7:
- return 6;
- case Core::HID::NpadIdType::Player8:
- return 7;
- case Core::HID::NpadIdType::Handheld:
- return 8;
- case Core::HID::NpadIdType::Other:
- return 9;
- default:
- return 8;
- }
-}
-
-/// Converts an array index to a Core::HID::NpadIdType
-constexpr Core::HID::NpadIdType IndexToNpadIdType(size_t index) {
- switch (index) {
- case 0:
- return Core::HID::NpadIdType::Player1;
- case 1:
- return Core::HID::NpadIdType::Player2;
- case 2:
- return Core::HID::NpadIdType::Player3;
- case 3:
- return Core::HID::NpadIdType::Player4;
- case 4:
- return Core::HID::NpadIdType::Player5;
- case 5:
- return Core::HID::NpadIdType::Player6;
- case 6:
- return Core::HID::NpadIdType::Player7;
- case 7:
- return Core::HID::NpadIdType::Player8;
- case 8:
- return Core::HID::NpadIdType::Handheld;
- case 9:
- return Core::HID::NpadIdType::Other;
- default:
- return Core::HID::NpadIdType::Invalid;
- }
-}
-
-constexpr Core::HID::NpadStyleSet GetStylesetByIndex(std::size_t index) {
- switch (index) {
- case 0:
- return Core::HID::NpadStyleSet::Fullkey;
- case 1:
- return Core::HID::NpadStyleSet::Handheld;
- case 2:
- return Core::HID::NpadStyleSet::JoyDual;
- case 3:
- return Core::HID::NpadStyleSet::JoyLeft;
- case 4:
- return Core::HID::NpadStyleSet::JoyRight;
- case 5:
- return Core::HID::NpadStyleSet::Palma;
- default:
- return Core::HID::NpadStyleSet::None;
- }
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index ffa7e144d..46f503d38 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -5,18 +5,18 @@
#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
-#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/service/hid/hidbus.h"
-#include "core/hle/service/hid/hidbus/ringcon.h"
-#include "core/hle/service/hid/hidbus/starlink.h"
-#include "core/hle/service/hid/hidbus/stubbed.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/service.h"
#include "core/memory.h"
+#include "hid_core/hid_types.h"
+#include "hid_core/hidbus/ringcon.h"
+#include "hid_core/hidbus/starlink.h"
+#include "hid_core/hidbus/stubbed.h"
namespace Service::HID {
// (15ms, 66Hz)
diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h
index 85a1df133..05f62f634 100644
--- a/src/core/hle/service/hid/hidbus.h
+++ b/src/core/hle/service/hid/hidbus.h
@@ -5,9 +5,9 @@
#include <functional>
-#include "core/hle/service/hid/hidbus/hidbus_base.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
+#include "hid_core/hidbus/hidbus_base.h"
namespace Core::Timing {
struct EventType;
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
deleted file mode 100644
index 8c44f93e8..000000000
--- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hid/hid_core.h"
-#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/service/hid/hidbus/hidbus_base.h"
-#include "core/hle/service/kernel_helpers.h"
-
-namespace Service::HID {
-
-HidbusBase::HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
- : system(system_), service_context(service_context_) {
- send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent");
-}
-
-HidbusBase::~HidbusBase() {
- service_context.CloseEvent(send_command_async_event);
-};
-
-void HidbusBase::ActivateDevice() {
- if (is_activated) {
- return;
- }
- is_activated = true;
- OnInit();
-}
-
-void HidbusBase::DeactivateDevice() {
- if (is_activated) {
- OnRelease();
- }
- is_activated = false;
-}
-
-bool HidbusBase::IsDeviceActivated() const {
- return is_activated;
-}
-
-void HidbusBase::Enable(bool enable) {
- device_enabled = enable;
-}
-
-bool HidbusBase::IsEnabled() const {
- return device_enabled;
-}
-
-bool HidbusBase::IsPollingMode() const {
- return polling_mode_enabled;
-}
-
-JoyPollingMode HidbusBase::GetPollingMode() const {
- return polling_mode;
-}
-
-void HidbusBase::SetPollingMode(JoyPollingMode mode) {
- polling_mode = mode;
- polling_mode_enabled = true;
-}
-
-void HidbusBase::DisablePollingMode() {
- polling_mode_enabled = false;
-}
-
-void HidbusBase::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
- transfer_memory = t_mem;
-}
-
-Kernel::KReadableEvent& HidbusBase::GetSendCommandAsycEvent() const {
- return send_command_async_event->GetReadableEvent();
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h
deleted file mode 100644
index ec41684e1..000000000
--- a/src/core/hle/service/hid/hidbus/hidbus_base.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <span>
-#include "common/typed_address.h"
-#include "core/hle/result.h"
-
-namespace Core {
-class System;
-}
-
-namespace Kernel {
-class KEvent;
-class KReadableEvent;
-} // namespace Kernel
-
-namespace Service::KernelHelpers {
-class ServiceContext;
-}
-
-namespace Service::HID {
-
-// This is nn::hidbus::JoyPollingMode
-enum class JoyPollingMode : u32 {
- SixAxisSensorDisable,
- SixAxisSensorEnable,
- ButtonOnly,
-};
-
-struct DataAccessorHeader {
- Result result{ResultUnknown};
- INSERT_PADDING_WORDS(0x1);
- std::array<u8, 0x18> unused{};
- u64 latest_entry{};
- u64 total_entries{};
-};
-static_assert(sizeof(DataAccessorHeader) == 0x30, "DataAccessorHeader is an invalid size");
-
-struct JoyDisableSixAxisPollingData {
- std::array<u8, 0x26> data;
- u8 out_size;
- INSERT_PADDING_BYTES(0x1);
- u64 sampling_number;
-};
-static_assert(sizeof(JoyDisableSixAxisPollingData) == 0x30,
- "JoyDisableSixAxisPollingData is an invalid size");
-
-struct JoyEnableSixAxisPollingData {
- std::array<u8, 0x8> data;
- u8 out_size;
- INSERT_PADDING_BYTES(0x7);
- u64 sampling_number;
-};
-static_assert(sizeof(JoyEnableSixAxisPollingData) == 0x18,
- "JoyEnableSixAxisPollingData is an invalid size");
-
-struct JoyButtonOnlyPollingData {
- std::array<u8, 0x2c> data;
- u8 out_size;
- INSERT_PADDING_BYTES(0x3);
- u64 sampling_number;
-};
-static_assert(sizeof(JoyButtonOnlyPollingData) == 0x38,
- "JoyButtonOnlyPollingData is an invalid size");
-
-struct JoyDisableSixAxisPollingEntry {
- u64 sampling_number;
- JoyDisableSixAxisPollingData polling_data;
-};
-static_assert(sizeof(JoyDisableSixAxisPollingEntry) == 0x38,
- "JoyDisableSixAxisPollingEntry is an invalid size");
-
-struct JoyEnableSixAxisPollingEntry {
- u64 sampling_number;
- JoyEnableSixAxisPollingData polling_data;
-};
-static_assert(sizeof(JoyEnableSixAxisPollingEntry) == 0x20,
- "JoyEnableSixAxisPollingEntry is an invalid size");
-
-struct JoyButtonOnlyPollingEntry {
- u64 sampling_number;
- JoyButtonOnlyPollingData polling_data;
-};
-static_assert(sizeof(JoyButtonOnlyPollingEntry) == 0x40,
- "JoyButtonOnlyPollingEntry is an invalid size");
-
-struct JoyDisableSixAxisDataAccessor {
- DataAccessorHeader header{};
- std::array<JoyDisableSixAxisPollingEntry, 0xb> entries{};
-};
-static_assert(sizeof(JoyDisableSixAxisDataAccessor) == 0x298,
- "JoyDisableSixAxisDataAccessor is an invalid size");
-
-struct JoyEnableSixAxisDataAccessor {
- DataAccessorHeader header{};
- std::array<JoyEnableSixAxisPollingEntry, 0xb> entries{};
-};
-static_assert(sizeof(JoyEnableSixAxisDataAccessor) == 0x190,
- "JoyEnableSixAxisDataAccessor is an invalid size");
-
-struct ButtonOnlyPollingDataAccessor {
- DataAccessorHeader header;
- std::array<JoyButtonOnlyPollingEntry, 0xb> entries;
-};
-static_assert(sizeof(ButtonOnlyPollingDataAccessor) == 0x2F0,
- "ButtonOnlyPollingDataAccessor is an invalid size");
-
-class HidbusBase {
-public:
- explicit HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
- virtual ~HidbusBase();
-
- void ActivateDevice();
-
- void DeactivateDevice();
-
- bool IsDeviceActivated() const;
-
- // Enables/disables the device
- void Enable(bool enable);
-
- // returns true if device is enabled
- bool IsEnabled() const;
-
- // returns true if polling mode is enabled
- bool IsPollingMode() const;
-
- // returns polling mode
- JoyPollingMode GetPollingMode() const;
-
- // Sets and enables JoyPollingMode
- void SetPollingMode(JoyPollingMode mode);
-
- // Disables JoyPollingMode
- void DisablePollingMode();
-
- // Called on EnableJoyPollingReceiveMode
- void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
-
- Kernel::KReadableEvent& GetSendCommandAsycEvent() const;
-
- virtual void OnInit() {}
-
- virtual void OnRelease() {}
-
- // Updates device transfer memory
- virtual void OnUpdate() {}
-
- // Returns the device ID of the joycon
- virtual u8 GetDeviceId() const {
- return {};
- }
-
- // Assigns a command from data
- virtual bool SetCommand(std::span<const u8> data) {
- return {};
- }
-
- // Returns a reply from a command
- virtual std::vector<u8> GetReply() const {
- return {};
- }
-
-protected:
- bool is_activated{};
- bool device_enabled{};
- bool polling_mode_enabled{};
- JoyPollingMode polling_mode = {};
- // TODO(German77): All data accessors need to be replaced with a ring lifo object
- JoyDisableSixAxisDataAccessor disable_sixaxis_data{};
- JoyEnableSixAxisDataAccessor enable_sixaxis_data{};
- ButtonOnlyPollingDataAccessor button_only_data{};
-
- Common::ProcessAddress transfer_memory{};
-
- Core::System& system;
- Kernel::KEvent* send_command_async_event;
- KernelHelpers::ServiceContext& service_context;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
deleted file mode 100644
index 378108012..000000000
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/service/hid/hidbus/ringcon.h"
-#include "core/memory.h"
-
-namespace Service::HID {
-
-RingController::RingController(Core::System& system_,
- KernelHelpers::ServiceContext& service_context_)
- : HidbusBase(system_, service_context_) {
- input = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
-}
-
-RingController::~RingController() = default;
-
-void RingController::OnInit() {
- input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
- Common::Input::PollingMode::Ring);
- return;
-}
-
-void RingController::OnRelease() {
- input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
- Common::Input::PollingMode::Active);
- return;
-};
-
-void RingController::OnUpdate() {
- if (!is_activated) {
- return;
- }
-
- if (!device_enabled) {
- return;
- }
-
- if (!polling_mode_enabled || transfer_memory == 0) {
- return;
- }
-
- // TODO: Increment multitasking counters from motion and sensor data
-
- switch (polling_mode) {
- case JoyPollingMode::SixAxisSensorEnable: {
- enable_sixaxis_data.header.total_entries = 10;
- enable_sixaxis_data.header.result = ResultSuccess;
- const auto& last_entry =
- enable_sixaxis_data.entries[enable_sixaxis_data.header.latest_entry];
-
- enable_sixaxis_data.header.latest_entry =
- (enable_sixaxis_data.header.latest_entry + 1) % 10;
- auto& curr_entry = enable_sixaxis_data.entries[enable_sixaxis_data.header.latest_entry];
-
- curr_entry.sampling_number = last_entry.sampling_number + 1;
- curr_entry.polling_data.sampling_number = curr_entry.sampling_number;
-
- const RingConData ringcon_value = GetSensorValue();
- curr_entry.polling_data.out_size = sizeof(ringcon_value);
- std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value));
-
- system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data,
- sizeof(enable_sixaxis_data));
- break;
- }
- default:
- LOG_ERROR(Service_HID, "Polling mode not supported {}", polling_mode);
- break;
- }
-}
-
-RingController::RingConData RingController::GetSensorValue() const {
- RingConData ringcon_sensor_value{
- .status = DataValid::Valid,
- .data = 0,
- };
-
- const f32 force_value = input->GetRingSensorForce().force * range;
- ringcon_sensor_value.data = static_cast<s16>(force_value) + idle_value;
-
- return ringcon_sensor_value;
-}
-
-u8 RingController::GetDeviceId() const {
- return device_id;
-}
-
-std::vector<u8> RingController::GetReply() const {
- const RingConCommands current_command = command;
-
- switch (current_command) {
- case RingConCommands::GetFirmwareVersion:
- return GetFirmwareVersionReply();
- case RingConCommands::ReadId:
- return GetReadIdReply();
- case RingConCommands::c20105:
- return GetC020105Reply();
- case RingConCommands::ReadUnkCal:
- return GetReadUnkCalReply();
- case RingConCommands::ReadFactoryCal:
- return GetReadFactoryCalReply();
- case RingConCommands::ReadUserCal:
- return GetReadUserCalReply();
- case RingConCommands::ReadRepCount:
- return GetReadRepCountReply();
- case RingConCommands::ReadTotalPushCount:
- return GetReadTotalPushCountReply();
- case RingConCommands::ResetRepCount:
- return GetResetRepCountReply();
- case RingConCommands::SaveCalData:
- return GetSaveDataReply();
- default:
- return GetErrorReply();
- }
-}
-
-bool RingController::SetCommand(std::span<const u8> data) {
- if (data.size() < 4) {
- LOG_ERROR(Service_HID, "Command size not supported {}", data.size());
- command = RingConCommands::Error;
- return false;
- }
-
- std::memcpy(&command, data.data(), sizeof(RingConCommands));
-
- switch (command) {
- case RingConCommands::GetFirmwareVersion:
- case RingConCommands::ReadId:
- case RingConCommands::c20105:
- case RingConCommands::ReadUnkCal:
- case RingConCommands::ReadFactoryCal:
- case RingConCommands::ReadUserCal:
- case RingConCommands::ReadRepCount:
- case RingConCommands::ReadTotalPushCount:
- ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
- send_command_async_event->Signal();
- return true;
- case RingConCommands::ResetRepCount:
- ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
- total_rep_count = 0;
- send_command_async_event->Signal();
- return true;
- case RingConCommands::SaveCalData: {
- ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes");
-
- SaveCalData save_info{};
- std::memcpy(&save_info, data.data(), sizeof(SaveCalData));
- user_calibration = save_info.calibration;
- send_command_async_event->Signal();
- return true;
- }
- default:
- LOG_ERROR(Service_HID, "Command not implemented {}", command);
- command = RingConCommands::Error;
- // Signal a reply to avoid softlocking the game
- send_command_async_event->Signal();
- return false;
- }
-}
-
-std::vector<u8> RingController::GetFirmwareVersionReply() const {
- const FirmwareVersionReply reply{
- .status = DataValid::Valid,
- .firmware = version,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetReadIdReply() const {
- // The values are hardcoded from a real joycon
- const ReadIdReply reply{
- .status = DataValid::Valid,
- .id_l_x0 = 8,
- .id_l_x0_2 = 41,
- .id_l_x4 = 22294,
- .id_h_x0 = 19777,
- .id_h_x0_2 = 13621,
- .id_h_x4 = 8245,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetC020105Reply() const {
- const Cmd020105Reply reply{
- .status = DataValid::Valid,
- .data = 1,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetReadUnkCalReply() const {
- const ReadUnkCalReply reply{
- .status = DataValid::Valid,
- .data = 0,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetReadFactoryCalReply() const {
- const ReadFactoryCalReply reply{
- .status = DataValid::Valid,
- .calibration = factory_calibration,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetReadUserCalReply() const {
- const ReadUserCalReply reply{
- .status = DataValid::Valid,
- .calibration = user_calibration,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetReadRepCountReply() const {
- const GetThreeByteReply reply{
- .status = DataValid::Valid,
- .data = {total_rep_count, 0, 0},
- .crc = GetCrcValue({total_rep_count, 0, 0, 0}),
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetReadTotalPushCountReply() const {
- const GetThreeByteReply reply{
- .status = DataValid::Valid,
- .data = {total_push_count, 0, 0},
- .crc = GetCrcValue({total_push_count, 0, 0, 0}),
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetResetRepCountReply() const {
- return GetReadRepCountReply();
-}
-
-std::vector<u8> RingController::GetSaveDataReply() const {
- const StatusReply reply{
- .status = DataValid::Valid,
- };
-
- return GetDataVector(reply);
-}
-
-std::vector<u8> RingController::GetErrorReply() const {
- const ErrorReply reply{
- .status = DataValid::BadCRC,
- };
-
- return GetDataVector(reply);
-}
-
-u8 RingController::GetCrcValue(const std::vector<u8>& data) const {
- u8 crc = 0;
- for (std::size_t index = 0; index < data.size(); index++) {
- for (u8 i = 0x80; i > 0; i >>= 1) {
- bool bit = (crc & 0x80) != 0;
- if ((data[index] & i) != 0) {
- bit = !bit;
- }
- crc <<= 1;
- if (bit) {
- crc ^= 0x8d;
- }
- }
- }
- return crc;
-}
-
-template <typename T>
-std::vector<u8> RingController::GetDataVector(const T& reply) const {
- static_assert(std::is_trivially_copyable_v<T>);
- std::vector<u8> data;
- data.resize(sizeof(reply));
- std::memcpy(data.data(), &reply, sizeof(reply));
- return data;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/ringcon.h b/src/core/hle/service/hid/hidbus/ringcon.h
deleted file mode 100644
index f42f3ea41..000000000
--- a/src/core/hle/service/hid/hidbus/ringcon.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <span>
-
-#include "common/common_types.h"
-#include "core/hle/service/hid/hidbus/hidbus_base.h"
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::HID {
-
-class RingController final : public HidbusBase {
-public:
- explicit RingController(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
- ~RingController() override;
-
- void OnInit() override;
-
- void OnRelease() override;
-
- // Updates ringcon transfer memory
- void OnUpdate() override;
-
- // Returns the device ID of the joycon
- u8 GetDeviceId() const override;
-
- // Assigns a command from data
- bool SetCommand(std::span<const u8> data) override;
-
- // Returns a reply from a command
- std::vector<u8> GetReply() const override;
-
-private:
- // These values are obtained from a real ring controller
- static constexpr s16 idle_value = 2280;
- static constexpr s16 idle_deadzone = 120;
- static constexpr s16 range = 2500;
-
- // Most missing command names are leftovers from other firmware versions
- enum class RingConCommands : u32 {
- GetFirmwareVersion = 0x00020000,
- ReadId = 0x00020100,
- JoyPolling = 0x00020101,
- Unknown1 = 0x00020104,
- c20105 = 0x00020105,
- Unknown2 = 0x00020204,
- Unknown3 = 0x00020304,
- Unknown4 = 0x00020404,
- ReadUnkCal = 0x00020504,
- ReadFactoryCal = 0x00020A04,
- Unknown5 = 0x00021104,
- Unknown6 = 0x00021204,
- Unknown7 = 0x00021304,
- ReadUserCal = 0x00021A04,
- ReadRepCount = 0x00023104,
- ReadTotalPushCount = 0x00023204,
- ResetRepCount = 0x04013104,
- Unknown8 = 0x04011104,
- Unknown9 = 0x04011204,
- Unknown10 = 0x04011304,
- SaveCalData = 0x10011A04,
- Error = 0xFFFFFFFF,
- };
-
- enum class DataValid : u32 {
- Valid,
- BadCRC,
- Cal,
- };
-
- struct FirmwareVersion {
- u8 sub;
- u8 main;
- };
- static_assert(sizeof(FirmwareVersion) == 0x2, "FirmwareVersion is an invalid size");
-
- struct FactoryCalibration {
- s32_le os_max;
- s32_le hk_max;
- s32_le zero_min;
- s32_le zero_max;
- };
- static_assert(sizeof(FactoryCalibration) == 0x10, "FactoryCalibration is an invalid size");
-
- struct CalibrationValue {
- s16 value;
- u16 crc;
- };
- static_assert(sizeof(CalibrationValue) == 0x4, "CalibrationValue is an invalid size");
-
- struct UserCalibration {
- CalibrationValue os_max;
- CalibrationValue hk_max;
- CalibrationValue zero;
- };
- static_assert(sizeof(UserCalibration) == 0xC, "UserCalibration is an invalid size");
-
- struct SaveCalData {
- RingConCommands command;
- UserCalibration calibration;
- INSERT_PADDING_BYTES_NOINIT(4);
- };
- static_assert(sizeof(SaveCalData) == 0x14, "SaveCalData is an invalid size");
- static_assert(std::is_trivially_copyable_v<SaveCalData>,
- "SaveCalData must be trivially copyable");
-
- struct FirmwareVersionReply {
- DataValid status;
- FirmwareVersion firmware;
- INSERT_PADDING_BYTES(0x2);
- };
- static_assert(sizeof(FirmwareVersionReply) == 0x8, "FirmwareVersionReply is an invalid size");
-
- struct Cmd020105Reply {
- DataValid status;
- u8 data;
- INSERT_PADDING_BYTES(0x3);
- };
- static_assert(sizeof(Cmd020105Reply) == 0x8, "Cmd020105Reply is an invalid size");
-
- struct StatusReply {
- DataValid status;
- };
- static_assert(sizeof(StatusReply) == 0x4, "StatusReply is an invalid size");
-
- struct GetThreeByteReply {
- DataValid status;
- std::array<u8, 3> data;
- u8 crc;
- };
- static_assert(sizeof(GetThreeByteReply) == 0x8, "GetThreeByteReply is an invalid size");
-
- struct ReadUnkCalReply {
- DataValid status;
- u16 data;
- INSERT_PADDING_BYTES(0x2);
- };
- static_assert(sizeof(ReadUnkCalReply) == 0x8, "ReadUnkCalReply is an invalid size");
-
- struct ReadFactoryCalReply {
- DataValid status;
- FactoryCalibration calibration;
- };
- static_assert(sizeof(ReadFactoryCalReply) == 0x14, "ReadFactoryCalReply is an invalid size");
-
- struct ReadUserCalReply {
- DataValid status;
- UserCalibration calibration;
- INSERT_PADDING_BYTES(0x4);
- };
- static_assert(sizeof(ReadUserCalReply) == 0x14, "ReadUserCalReply is an invalid size");
-
- struct ReadIdReply {
- DataValid status;
- u16 id_l_x0;
- u16 id_l_x0_2;
- u16 id_l_x4;
- u16 id_h_x0;
- u16 id_h_x0_2;
- u16 id_h_x4;
- };
- static_assert(sizeof(ReadIdReply) == 0x10, "ReadIdReply is an invalid size");
-
- struct ErrorReply {
- DataValid status;
- INSERT_PADDING_BYTES(0x3);
- };
- static_assert(sizeof(ErrorReply) == 0x8, "ErrorReply is an invalid size");
-
- struct RingConData {
- DataValid status;
- s16_le data;
- INSERT_PADDING_BYTES(0x2);
- };
- static_assert(sizeof(RingConData) == 0x8, "RingConData is an invalid size");
-
- // Returns RingConData struct with pressure sensor values
- RingConData GetSensorValue() const;
-
- // Returns 8 byte reply with firmware version
- std::vector<u8> GetFirmwareVersionReply() const;
-
- // Returns 16 byte reply with ID values
- std::vector<u8> GetReadIdReply() const;
-
- // (STUBBED) Returns 8 byte reply
- std::vector<u8> GetC020105Reply() const;
-
- // (STUBBED) Returns 8 byte empty reply
- std::vector<u8> GetReadUnkCalReply() const;
-
- // Returns 20 byte reply with factory calibration values
- std::vector<u8> GetReadFactoryCalReply() const;
-
- // Returns 20 byte reply with user calibration values
- std::vector<u8> GetReadUserCalReply() const;
-
- // Returns 8 byte reply
- std::vector<u8> GetReadRepCountReply() const;
-
- // Returns 8 byte reply
- std::vector<u8> GetReadTotalPushCountReply() const;
-
- // Returns 8 byte reply
- std::vector<u8> GetResetRepCountReply() const;
-
- // Returns 4 byte save data reply
- std::vector<u8> GetSaveDataReply() const;
-
- // Returns 8 byte error reply
- std::vector<u8> GetErrorReply() const;
-
- // Returns 8 bit redundancy check from provided data
- u8 GetCrcValue(const std::vector<u8>& data) const;
-
- // Converts structs to an u8 vector equivalent
- template <typename T>
- std::vector<u8> GetDataVector(const T& reply) const;
-
- RingConCommands command{RingConCommands::Error};
-
- // These counters are used in multitasking mode while the switch is sleeping
- // Total steps taken
- u8 total_rep_count = 0;
- // Total times the ring was pushed
- u8 total_push_count = 0;
-
- const u8 device_id = 0x20;
- const FirmwareVersion version = {
- .sub = 0x0,
- .main = 0x2c,
- };
- const FactoryCalibration factory_calibration = {
- .os_max = idle_value + range + idle_deadzone,
- .hk_max = idle_value - range - idle_deadzone,
- .zero_min = idle_value - idle_deadzone,
- .zero_max = idle_value + idle_deadzone,
- };
- UserCalibration user_calibration = {
- .os_max = {.value = range, .crc = 228},
- .hk_max = {.value = -range, .crc = 239},
- .zero = {.value = idle_value, .crc = 225},
- };
-
- Core::HID::EmulatedController* input;
-};
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/starlink.cpp b/src/core/hle/service/hid/hidbus/starlink.cpp
deleted file mode 100644
index 36573274e..000000000
--- a/src/core/hle/service/hid/hidbus/starlink.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/hidbus/starlink.h"
-
-namespace Service::HID {
-constexpr u8 DEVICE_ID = 0x28;
-
-Starlink::Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
- : HidbusBase(system_, service_context_) {}
-Starlink::~Starlink() = default;
-
-void Starlink::OnInit() {
- return;
-}
-
-void Starlink::OnRelease() {
- return;
-};
-
-void Starlink::OnUpdate() {
- if (!is_activated) {
- return;
- }
- if (!device_enabled) {
- return;
- }
- if (!polling_mode_enabled || transfer_memory == 0) {
- return;
- }
-
- LOG_ERROR(Service_HID, "Polling mode not supported {}", polling_mode);
-}
-
-u8 Starlink::GetDeviceId() const {
- return DEVICE_ID;
-}
-
-std::vector<u8> Starlink::GetReply() const {
- return {};
-}
-
-bool Starlink::SetCommand(std::span<const u8> data) {
- LOG_ERROR(Service_HID, "Command not implemented");
- return false;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/starlink.h b/src/core/hle/service/hid/hidbus/starlink.h
deleted file mode 100644
index a276aa88f..000000000
--- a/src/core/hle/service/hid/hidbus/starlink.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hle/service/hid/hidbus/hidbus_base.h"
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::HID {
-
-class Starlink final : public HidbusBase {
-public:
- explicit Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
- ~Starlink() override;
-
- void OnInit() override;
-
- void OnRelease() override;
-
- // Updates ringcon transfer memory
- void OnUpdate() override;
-
- // Returns the device ID of the joycon
- u8 GetDeviceId() const override;
-
- // Assigns a command from data
- bool SetCommand(std::span<const u8> data) override;
-
- // Returns a reply from a command
- std::vector<u8> GetReply() const override;
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/stubbed.cpp b/src/core/hle/service/hid/hidbus/stubbed.cpp
deleted file mode 100644
index 8160b7218..000000000
--- a/src/core/hle/service/hid/hidbus/stubbed.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/hidbus/stubbed.h"
-
-namespace Service::HID {
-constexpr u8 DEVICE_ID = 0xFF;
-
-HidbusStubbed::HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_)
- : HidbusBase(system_, service_context_) {}
-HidbusStubbed::~HidbusStubbed() = default;
-
-void HidbusStubbed::OnInit() {
- return;
-}
-
-void HidbusStubbed::OnRelease() {
- return;
-};
-
-void HidbusStubbed::OnUpdate() {
- if (!is_activated) {
- return;
- }
- if (!device_enabled) {
- return;
- }
- if (!polling_mode_enabled || transfer_memory == 0) {
- return;
- }
-
- LOG_ERROR(Service_HID, "Polling mode not supported {}", polling_mode);
-}
-
-u8 HidbusStubbed::GetDeviceId() const {
- return DEVICE_ID;
-}
-
-std::vector<u8> HidbusStubbed::GetReply() const {
- return {};
-}
-
-bool HidbusStubbed::SetCommand(std::span<const u8> data) {
- LOG_ERROR(Service_HID, "Command not implemented");
- return false;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus/stubbed.h b/src/core/hle/service/hid/hidbus/stubbed.h
deleted file mode 100644
index 2e58d42fc..000000000
--- a/src/core/hle/service/hid/hidbus/stubbed.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hle/service/hid/hidbus/hidbus_base.h"
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::HID {
-
-class HidbusStubbed final : public HidbusBase {
-public:
- explicit HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
- ~HidbusStubbed() override;
-
- void OnInit() override;
-
- void OnRelease() override;
-
- // Updates ringcon transfer memory
- void OnUpdate() override;
-
- // Returns the device ID of the joycon
- u8 GetDeviceId() const override;
-
- // Assigns a command from data
- bool SetCommand(std::span<const u8> data) override;
-
- // Returns a reply from a command
- std::vector<u8> GetReply() const override;
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 008debfd1..18e544f2f 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -6,22 +6,22 @@
#include "core/core.h"
#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/service/hid/errors.h"
-#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/hid/irs.h"
-#include "core/hle/service/hid/irsensor/clustering_processor.h"
-#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
-#include "core/hle/service/hid/irsensor/ir_led_processor.h"
-#include "core/hle/service/hid/irsensor/moment_processor.h"
-#include "core/hle/service/hid/irsensor/pointing_processor.h"
-#include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/memory.h"
+#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/irsensor/clustering_processor.h"
+#include "hid_core/irsensor/image_transfer_processor.h"
+#include "hid_core/irsensor/ir_led_processor.h"
+#include "hid_core/irsensor/moment_processor.h"
+#include "hid_core/irsensor/pointing_processor.h"
+#include "hid_core/irsensor/tera_plugin_processor.h"
namespace Service::IRS {
@@ -315,7 +315,7 @@ void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid &&
npad_id != Core::HID::NpadIdType::Handheld) {
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(Service::HID::InvalidNpadId);
+ rb.Push(Service::HID::ResultInvalidNpadId);
return;
}
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index c8e6dab17..06b7279ee 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -4,10 +4,10 @@
#pragma once
#include "core/core.h"
-#include "core/hid/hid_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
#include "core/hle/service/service.h"
+#include "hid_core/hid_types.h"
+#include "hid_core/irsensor/irs_types.h"
+#include "hid_core/irsensor/processor_base.h"
namespace Core::HID {
class EmulatedController;
diff --git a/src/core/hle/service/hid/irs_ring_lifo.h b/src/core/hle/service/hid/irs_ring_lifo.h
deleted file mode 100644
index 255d1d296..000000000
--- a/src/core/hle/service/hid/irs_ring_lifo.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include <array>
-
-#include "common/common_types.h"
-
-namespace Service::IRS {
-
-template <typename State, std::size_t max_buffer_size>
-struct Lifo {
- s64 sampling_number{};
- s64 buffer_count{};
- std::array<State, max_buffer_size> entries{};
-
- const State& ReadCurrentEntry() const {
- return entries[GetBufferTail()];
- }
-
- const State& ReadPreviousEntry() const {
- return entries[GetPreviousEntryIndex()];
- }
-
- s64 GetBufferTail() const {
- return sampling_number % max_buffer_size;
- }
-
- std::size_t GetPreviousEntryIndex() const {
- return static_cast<size_t>((GetBufferTail() + max_buffer_size - 1) % max_buffer_size);
- }
-
- std::size_t GetNextEntryIndex() const {
- return static_cast<size_t>((GetBufferTail() + 1) % max_buffer_size);
- }
-
- void WriteNextEntry(const State& new_state) {
- if (buffer_count < static_cast<s64>(max_buffer_size)) {
- buffer_count++;
- }
- sampling_number++;
- entries[GetBufferTail()] = new_state;
- }
-};
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.cpp b/src/core/hle/service/hid/irsensor/clustering_processor.cpp
deleted file mode 100644
index c559eb0d5..000000000
--- a/src/core/hle/service/hid/irsensor/clustering_processor.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include <queue>
-
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/irsensor/clustering_processor.h"
-
-namespace Service::IRS {
-ClusteringProcessor::ClusteringProcessor(Core::System& system_,
- Core::IrSensor::DeviceFormat& device_format,
- std::size_t npad_index)
- : device{device_format}, system{system_} {
- npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
-
- device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor;
- device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
- SetDefaultConfig();
-
- shared_memory = std::construct_at(
- reinterpret_cast<ClusteringSharedMemory*>(&device_format.state.processor_raw_data));
-
- Core::HID::ControllerUpdateCallback engine_callback{
- .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
- .is_npad_service = true,
- };
- callback_key = npad_device->SetCallback(engine_callback);
-}
-
-ClusteringProcessor::~ClusteringProcessor() {
- npad_device->DeleteCallback(callback_key);
-};
-
-void ClusteringProcessor::StartProcessor() {
- device.camera_status = Core::IrSensor::IrCameraStatus::Available;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready;
-}
-
-void ClusteringProcessor::SuspendProcessor() {}
-
-void ClusteringProcessor::StopProcessor() {}
-
-void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) {
- if (type != Core::HID::ControllerTriggerType::IrSensor) {
- return;
- }
-
- next_state = {};
- const auto& camera_data = npad_device->GetCamera();
- auto filtered_image = camera_data.data;
-
- RemoveLowIntensityData(filtered_image);
-
- const auto window_start_x = static_cast<std::size_t>(current_config.window_of_interest.x);
- const auto window_start_y = static_cast<std::size_t>(current_config.window_of_interest.y);
- const auto window_end_x =
- window_start_x + static_cast<std::size_t>(current_config.window_of_interest.width);
- const auto window_end_y =
- window_start_y + static_cast<std::size_t>(current_config.window_of_interest.height);
-
- for (std::size_t y = window_start_y; y < window_end_y; y++) {
- for (std::size_t x = window_start_x; x < window_end_x; x++) {
- u8 pixel = GetPixel(filtered_image, x, y);
- if (pixel == 0) {
- continue;
- }
- const auto cluster = GetClusterProperties(filtered_image, x, y);
- if (cluster.pixel_count > current_config.pixel_count_max) {
- continue;
- }
- if (cluster.pixel_count < current_config.pixel_count_min) {
- continue;
- }
- // Cluster object limit reached
- if (next_state.object_count >= next_state.data.size()) {
- continue;
- }
- next_state.data[next_state.object_count] = cluster;
- next_state.object_count++;
- }
- }
-
- next_state.sampling_number = camera_data.sample;
- next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count();
- next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
- shared_memory->clustering_lifo.WriteNextEntry(next_state);
-
- if (!IsProcessorActive()) {
- StartProcessor();
- }
-}
-
-void ClusteringProcessor::RemoveLowIntensityData(std::vector<u8>& data) {
- for (u8& pixel : data) {
- if (pixel < current_config.pixel_count_min) {
- pixel = 0;
- }
- }
-}
-
-ClusteringProcessor::ClusteringData ClusteringProcessor::GetClusterProperties(std::vector<u8>& data,
- std::size_t x,
- std::size_t y) {
- using DataPoint = Common::Point<std::size_t>;
- std::queue<DataPoint> search_points{};
- ClusteringData current_cluster = GetPixelProperties(data, x, y);
- SetPixel(data, x, y, 0);
- search_points.emplace<DataPoint>({x, y});
-
- while (!search_points.empty()) {
- const auto point = search_points.front();
- search_points.pop();
-
- // Avoid negative numbers
- if (point.x == 0 || point.y == 0) {
- continue;
- }
-
- std::array<DataPoint, 4> new_points{
- DataPoint{point.x - 1, point.y},
- {point.x, point.y - 1},
- {point.x + 1, point.y},
- {point.x, point.y + 1},
- };
-
- for (const auto new_point : new_points) {
- if (new_point.x >= width) {
- continue;
- }
- if (new_point.y >= height) {
- continue;
- }
- if (GetPixel(data, new_point.x, new_point.y) < current_config.object_intensity_min) {
- continue;
- }
- const ClusteringData cluster = GetPixelProperties(data, new_point.x, new_point.y);
- current_cluster = MergeCluster(current_cluster, cluster);
- SetPixel(data, new_point.x, new_point.y, 0);
- search_points.emplace<DataPoint>({new_point.x, new_point.y});
- }
- }
-
- return current_cluster;
-}
-
-ClusteringProcessor::ClusteringData ClusteringProcessor::GetPixelProperties(
- const std::vector<u8>& data, std::size_t x, std::size_t y) const {
- return {
- .average_intensity = GetPixel(data, x, y) / 255.0f,
- .centroid =
- {
- .x = static_cast<f32>(x),
- .y = static_cast<f32>(y),
-
- },
- .pixel_count = 1,
- .bound =
- {
- .x = static_cast<s16>(x),
- .y = static_cast<s16>(y),
- .width = 1,
- .height = 1,
- },
- };
-}
-
-ClusteringProcessor::ClusteringData ClusteringProcessor::MergeCluster(
- const ClusteringData a, const ClusteringData b) const {
- const f32 a_pixel_count = static_cast<f32>(a.pixel_count);
- const f32 b_pixel_count = static_cast<f32>(b.pixel_count);
- const f32 pixel_count = a_pixel_count + b_pixel_count;
- const f32 average_intensity =
- (a.average_intensity * a_pixel_count + b.average_intensity * b_pixel_count) / pixel_count;
- const Core::IrSensor::IrsCentroid centroid = {
- .x = (a.centroid.x * a_pixel_count + b.centroid.x * b_pixel_count) / pixel_count,
- .y = (a.centroid.y * a_pixel_count + b.centroid.y * b_pixel_count) / pixel_count,
- };
- s16 bound_start_x = a.bound.x < b.bound.x ? a.bound.x : b.bound.x;
- s16 bound_start_y = a.bound.y < b.bound.y ? a.bound.y : b.bound.y;
- s16 a_bound_end_x = a.bound.x + a.bound.width;
- s16 a_bound_end_y = a.bound.y + a.bound.height;
- s16 b_bound_end_x = b.bound.x + b.bound.width;
- s16 b_bound_end_y = b.bound.y + b.bound.height;
-
- const Core::IrSensor::IrsRect bound = {
- .x = bound_start_x,
- .y = bound_start_y,
- .width = a_bound_end_x > b_bound_end_x ? static_cast<s16>(a_bound_end_x - bound_start_x)
- : static_cast<s16>(b_bound_end_x - bound_start_x),
- .height = a_bound_end_y > b_bound_end_y ? static_cast<s16>(a_bound_end_y - bound_start_y)
- : static_cast<s16>(b_bound_end_y - bound_start_y),
- };
-
- return {
- .average_intensity = average_intensity,
- .centroid = centroid,
- .pixel_count = static_cast<u32>(pixel_count),
- .bound = bound,
- };
-}
-
-u8 ClusteringProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const {
- if ((y * width) + x >= data.size()) {
- return 0;
- }
- return data[(y * width) + x];
-}
-
-void ClusteringProcessor::SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value) {
- if ((y * width) + x >= data.size()) {
- return;
- }
- data[(y * width) + x] = value;
-}
-
-void ClusteringProcessor::SetDefaultConfig() {
- using namespace std::literals::chrono_literals;
- current_config.camera_config.exposure_time = std::chrono::microseconds(200ms).count();
- current_config.camera_config.gain = 2;
- current_config.camera_config.is_negative_used = false;
- current_config.camera_config.light_target = Core::IrSensor::CameraLightTarget::BrightLeds;
- current_config.window_of_interest = {
- .x = 0,
- .y = 0,
- .width = width,
- .height = height,
- };
- current_config.pixel_count_min = 3;
- current_config.pixel_count_max = static_cast<u32>(GetDataSize(format));
- current_config.is_external_light_filter_enabled = true;
- current_config.object_intensity_min = 150;
-
- npad_device->SetCameraFormat(format);
-}
-
-void ClusteringProcessor::SetConfig(Core::IrSensor::PackedClusteringProcessorConfig config) {
- current_config.camera_config.exposure_time = config.camera_config.exposure_time;
- current_config.camera_config.gain = config.camera_config.gain;
- current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
- current_config.camera_config.light_target =
- static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
- current_config.window_of_interest = config.window_of_interest;
- current_config.pixel_count_min = config.pixel_count_min;
- current_config.pixel_count_max = config.pixel_count_max;
- current_config.is_external_light_filter_enabled = config.is_external_light_filter_enabled;
- current_config.object_intensity_min = config.object_intensity_min;
-
- LOG_INFO(Service_IRS,
- "Processor config, exposure_time={}, gain={}, is_negative_used={}, "
- "light_target={}, window_of_interest=({}, {}, {}, {}), pixel_count_min={}, "
- "pixel_count_max={}, is_external_light_filter_enabled={}, object_intensity_min={}",
- current_config.camera_config.exposure_time, current_config.camera_config.gain,
- current_config.camera_config.is_negative_used,
- current_config.camera_config.light_target, current_config.window_of_interest.x,
- current_config.window_of_interest.y, current_config.window_of_interest.width,
- current_config.window_of_interest.height, current_config.pixel_count_min,
- current_config.pixel_count_max, current_config.is_external_light_filter_enabled,
- current_config.object_intensity_min);
-
- npad_device->SetCameraFormat(format);
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.h b/src/core/hle/service/hid/irsensor/clustering_processor.h
deleted file mode 100644
index 83f34734a..000000000
--- a/src/core/hle/service/hid/irsensor/clustering_processor.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irs_ring_lifo.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Core {
-class System;
-}
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::IRS {
-class ClusteringProcessor final : public ProcessorBase {
-public:
- explicit ClusteringProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
- std::size_t npad_index);
- ~ClusteringProcessor() override;
-
- // Called when the processor is initialized
- void StartProcessor() override;
-
- // Called when the processor is suspended
- void SuspendProcessor() override;
-
- // Called when the processor is stopped
- void StopProcessor() override;
-
- // Sets config parameters of the camera
- void SetConfig(Core::IrSensor::PackedClusteringProcessorConfig config);
-
-private:
- static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size320x240;
- static constexpr std::size_t width = 320;
- static constexpr std::size_t height = 240;
-
- // This is nn::irsensor::ClusteringProcessorConfig
- struct ClusteringProcessorConfig {
- Core::IrSensor::CameraConfig camera_config;
- Core::IrSensor::IrsRect window_of_interest;
- u32 pixel_count_min;
- u32 pixel_count_max;
- u32 object_intensity_min;
- bool is_external_light_filter_enabled;
- INSERT_PADDING_BYTES(3);
- };
- static_assert(sizeof(ClusteringProcessorConfig) == 0x30,
- "ClusteringProcessorConfig is an invalid size");
-
- // This is nn::irsensor::AdaptiveClusteringProcessorConfig
- struct AdaptiveClusteringProcessorConfig {
- Core::IrSensor::AdaptiveClusteringMode mode;
- Core::IrSensor::AdaptiveClusteringTargetDistance target_distance;
- };
- static_assert(sizeof(AdaptiveClusteringProcessorConfig) == 0x8,
- "AdaptiveClusteringProcessorConfig is an invalid size");
-
- // This is nn::irsensor::ClusteringData
- struct ClusteringData {
- f32 average_intensity;
- Core::IrSensor::IrsCentroid centroid;
- u32 pixel_count;
- Core::IrSensor::IrsRect bound;
- };
- static_assert(sizeof(ClusteringData) == 0x18, "ClusteringData is an invalid size");
-
- // This is nn::irsensor::ClusteringProcessorState
- struct ClusteringProcessorState {
- s64 sampling_number;
- u64 timestamp;
- u8 object_count;
- INSERT_PADDING_BYTES(3);
- Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
- std::array<ClusteringData, 0x10> data;
- };
- static_assert(sizeof(ClusteringProcessorState) == 0x198,
- "ClusteringProcessorState is an invalid size");
-
- struct ClusteringSharedMemory {
- Service::IRS::Lifo<ClusteringProcessorState, 6> clustering_lifo;
- static_assert(sizeof(clustering_lifo) == 0x9A0, "clustering_lifo is an invalid size");
- INSERT_PADDING_WORDS(0x11F);
- };
- static_assert(sizeof(ClusteringSharedMemory) == 0xE20,
- "ClusteringSharedMemory is an invalid size");
-
- void OnControllerUpdate(Core::HID::ControllerTriggerType type);
- void RemoveLowIntensityData(std::vector<u8>& data);
- ClusteringData GetClusterProperties(std::vector<u8>& data, std::size_t x, std::size_t y);
- ClusteringData GetPixelProperties(const std::vector<u8>& data, std::size_t x,
- std::size_t y) const;
- ClusteringData MergeCluster(const ClusteringData a, const ClusteringData b) const;
- u8 GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const;
- void SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value);
-
- // Sets config parameters of the camera
- void SetDefaultConfig();
-
- ClusteringSharedMemory* shared_memory = nullptr;
- ClusteringProcessorState next_state{};
-
- ClusteringProcessorConfig current_config{};
- Core::IrSensor::DeviceFormat& device;
- Core::HID::EmulatedController* npad_device;
- int callback_key{};
-
- Core::System& system;
-};
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
deleted file mode 100644
index 22067a591..000000000
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/core.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/irsensor/image_transfer_processor.h"
-#include "core/memory.h"
-
-namespace Service::IRS {
-ImageTransferProcessor::ImageTransferProcessor(Core::System& system_,
- Core::IrSensor::DeviceFormat& device_format,
- std::size_t npad_index)
- : device{device_format}, system{system_} {
- npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
-
- Core::HID::ControllerUpdateCallback engine_callback{
- .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
- .is_npad_service = true,
- };
- callback_key = npad_device->SetCallback(engine_callback);
-
- device.mode = Core::IrSensor::IrSensorMode::ImageTransferProcessor;
- device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
-}
-
-ImageTransferProcessor::~ImageTransferProcessor() {
- npad_device->DeleteCallback(callback_key);
-};
-
-void ImageTransferProcessor::StartProcessor() {
- is_active = true;
- device.camera_status = Core::IrSensor::IrCameraStatus::Available;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready;
- processor_state.sampling_number = 0;
- processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
-}
-
-void ImageTransferProcessor::SuspendProcessor() {}
-
-void ImageTransferProcessor::StopProcessor() {}
-
-void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) {
- if (type != Core::HID::ControllerTriggerType::IrSensor) {
- return;
- }
- if (transfer_memory == 0) {
- return;
- }
-
- const auto& camera_data = npad_device->GetCamera();
-
- // This indicates how much ambient light is present
- processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
- processor_state.sampling_number = camera_data.sample;
-
- if (camera_data.format != current_config.origin_format) {
- LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format,
- current_config.origin_format);
- system.ApplicationMemory().ZeroBlock(transfer_memory,
- GetDataSize(current_config.trimming_format));
- return;
- }
-
- if (current_config.origin_format > current_config.trimming_format) {
- LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}",
- current_config.origin_format, current_config.trimming_format);
- system.ApplicationMemory().ZeroBlock(transfer_memory,
- GetDataSize(current_config.trimming_format));
- return;
- }
-
- std::vector<u8> window_data{};
- const auto origin_width = GetDataWidth(current_config.origin_format);
- const auto origin_height = GetDataHeight(current_config.origin_format);
- const auto trimming_width = GetDataWidth(current_config.trimming_format);
- const auto trimming_height = GetDataHeight(current_config.trimming_format);
- window_data.resize(GetDataSize(current_config.trimming_format));
-
- if (trimming_width + current_config.trimming_start_x > origin_width ||
- trimming_height + current_config.trimming_start_y > origin_height) {
- LOG_WARNING(Service_IRS,
- "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})",
- current_config.trimming_start_x, current_config.trimming_start_y,
- trimming_width, trimming_height, origin_width, origin_height);
- system.ApplicationMemory().ZeroBlock(transfer_memory,
- GetDataSize(current_config.trimming_format));
- return;
- }
-
- for (std::size_t y = 0; y < trimming_height; y++) {
- for (std::size_t x = 0; x < trimming_width; x++) {
- const std::size_t window_index = (y * trimming_width) + x;
- const std::size_t origin_index =
- ((y + current_config.trimming_start_y) * origin_width) + x +
- current_config.trimming_start_x;
- window_data[window_index] = camera_data.data[origin_index];
- }
- }
-
- system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(),
- GetDataSize(current_config.trimming_format));
-
- if (!IsProcessorActive()) {
- StartProcessor();
- }
-}
-
-void ImageTransferProcessor::SetConfig(Core::IrSensor::PackedImageTransferProcessorConfig config) {
- current_config.camera_config.exposure_time = config.camera_config.exposure_time;
- current_config.camera_config.gain = config.camera_config.gain;
- current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
- current_config.camera_config.light_target =
- static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
- current_config.origin_format =
- static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.format);
- current_config.trimming_format =
- static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.format);
- current_config.trimming_start_x = 0;
- current_config.trimming_start_y = 0;
-
- npad_device->SetCameraFormat(current_config.origin_format);
-}
-
-void ImageTransferProcessor::SetConfig(
- Core::IrSensor::PackedImageTransferProcessorExConfig config) {
- current_config.camera_config.exposure_time = config.camera_config.exposure_time;
- current_config.camera_config.gain = config.camera_config.gain;
- current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
- current_config.camera_config.light_target =
- static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
- current_config.origin_format =
- static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.origin_format);
- current_config.trimming_format =
- static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.trimming_format);
- current_config.trimming_start_x = config.trimming_start_x;
- current_config.trimming_start_y = config.trimming_start_y;
-
- npad_device->SetCameraFormat(current_config.origin_format);
-}
-
-void ImageTransferProcessor::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
- transfer_memory = t_mem;
-}
-
-Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState(
- std::vector<u8>& data) const {
- const auto size = GetDataSize(current_config.trimming_format);
- data.resize(size);
- system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size);
- return processor_state;
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
deleted file mode 100644
index 7f42d8453..000000000
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/typed_address.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Core {
-class System;
-}
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::IRS {
-class ImageTransferProcessor final : public ProcessorBase {
-public:
- explicit ImageTransferProcessor(Core::System& system_,
- Core::IrSensor::DeviceFormat& device_format,
- std::size_t npad_index);
- ~ImageTransferProcessor() override;
-
- // Called when the processor is initialized
- void StartProcessor() override;
-
- // Called when the processor is suspended
- void SuspendProcessor() override;
-
- // Called when the processor is stopped
- void StopProcessor() override;
-
- // Sets config parameters of the camera
- void SetConfig(Core::IrSensor::PackedImageTransferProcessorConfig config);
- void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config);
-
- // Transfer memory where the image data will be stored
- void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
-
- Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const;
-
-private:
- // This is nn::irsensor::ImageTransferProcessorConfig
- struct ImageTransferProcessorConfig {
- Core::IrSensor::CameraConfig camera_config;
- Core::IrSensor::ImageTransferProcessorFormat format;
- };
- static_assert(sizeof(ImageTransferProcessorConfig) == 0x20,
- "ImageTransferProcessorConfig is an invalid size");
-
- // This is nn::irsensor::ImageTransferProcessorExConfig
- struct ImageTransferProcessorExConfig {
- Core::IrSensor::CameraConfig camera_config;
- Core::IrSensor::ImageTransferProcessorFormat origin_format;
- Core::IrSensor::ImageTransferProcessorFormat trimming_format;
- u16 trimming_start_x;
- u16 trimming_start_y;
- bool is_external_light_filter_enabled;
- INSERT_PADDING_BYTES(3);
- };
- static_assert(sizeof(ImageTransferProcessorExConfig) == 0x28,
- "ImageTransferProcessorExConfig is an invalid size");
-
- void OnControllerUpdate(Core::HID::ControllerTriggerType type);
-
- ImageTransferProcessorExConfig current_config{};
- Core::IrSensor::ImageTransferProcessorState processor_state{};
- Core::IrSensor::DeviceFormat& device;
- Core::HID::EmulatedController* npad_device;
- int callback_key{};
-
- Core::System& system;
- Common::ProcessAddress transfer_memory{};
-};
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/ir_led_processor.cpp b/src/core/hle/service/hid/irsensor/ir_led_processor.cpp
deleted file mode 100644
index 8e6dd99e4..000000000
--- a/src/core/hle/service/hid/irsensor/ir_led_processor.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/hle/service/hid/irsensor/ir_led_processor.h"
-
-namespace Service::IRS {
-IrLedProcessor::IrLedProcessor(Core::IrSensor::DeviceFormat& device_format)
- : device(device_format) {
- device.mode = Core::IrSensor::IrSensorMode::IrLedProcessor;
- device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
-}
-
-IrLedProcessor::~IrLedProcessor() = default;
-
-void IrLedProcessor::StartProcessor() {}
-
-void IrLedProcessor::SuspendProcessor() {}
-
-void IrLedProcessor::StopProcessor() {}
-
-void IrLedProcessor::SetConfig(Core::IrSensor::PackedIrLedProcessorConfig config) {
- current_config.light_target =
- static_cast<Core::IrSensor::CameraLightTarget>(config.light_target);
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/ir_led_processor.h b/src/core/hle/service/hid/irsensor/ir_led_processor.h
deleted file mode 100644
index c3d8693c9..000000000
--- a/src/core/hle/service/hid/irsensor/ir_led_processor.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Service::IRS {
-class IrLedProcessor final : public ProcessorBase {
-public:
- explicit IrLedProcessor(Core::IrSensor::DeviceFormat& device_format);
- ~IrLedProcessor() override;
-
- // Called when the processor is initialized
- void StartProcessor() override;
-
- // Called when the processor is suspended
- void SuspendProcessor() override;
-
- // Called when the processor is stopped
- void StopProcessor() override;
-
- // Sets config parameters of the camera
- void SetConfig(Core::IrSensor::PackedIrLedProcessorConfig config);
-
-private:
- // This is nn::irsensor::IrLedProcessorConfig
- struct IrLedProcessorConfig {
- Core::IrSensor::CameraLightTarget light_target;
- };
- static_assert(sizeof(IrLedProcessorConfig) == 0x4, "IrLedProcessorConfig is an invalid size");
-
- struct IrLedProcessorState {
- s64 sampling_number;
- u64 timestamp;
- std::array<u8, 0x8> data;
- };
- static_assert(sizeof(IrLedProcessorState) == 0x18, "IrLedProcessorState is an invalid size");
-
- IrLedProcessorConfig current_config{};
- Core::IrSensor::DeviceFormat& device;
-};
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.cpp b/src/core/hle/service/hid/irsensor/moment_processor.cpp
deleted file mode 100644
index cf045bda7..000000000
--- a/src/core/hle/service/hid/irsensor/moment_processor.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/irsensor/moment_processor.h"
-
-namespace Service::IRS {
-static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size40x30;
-static constexpr std::size_t ImageWidth = 40;
-static constexpr std::size_t ImageHeight = 30;
-
-MomentProcessor::MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
- std::size_t npad_index)
- : device(device_format), system{system_} {
- npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
-
- device.mode = Core::IrSensor::IrSensorMode::MomentProcessor;
- device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
-
- shared_memory = std::construct_at(
- reinterpret_cast<MomentSharedMemory*>(&device_format.state.processor_raw_data));
-
- Core::HID::ControllerUpdateCallback engine_callback{
- .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); },
- .is_npad_service = true,
- };
- callback_key = npad_device->SetCallback(engine_callback);
-}
-
-MomentProcessor::~MomentProcessor() {
- npad_device->DeleteCallback(callback_key);
-};
-
-void MomentProcessor::StartProcessor() {
- device.camera_status = Core::IrSensor::IrCameraStatus::Available;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready;
-}
-
-void MomentProcessor::SuspendProcessor() {}
-
-void MomentProcessor::StopProcessor() {}
-
-void MomentProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) {
- if (type != Core::HID::ControllerTriggerType::IrSensor) {
- return;
- }
-
- next_state = {};
- const auto& camera_data = npad_device->GetCamera();
-
- const auto window_width = static_cast<std::size_t>(current_config.window_of_interest.width);
- const auto window_height = static_cast<std::size_t>(current_config.window_of_interest.height);
- const auto window_start_x = static_cast<std::size_t>(current_config.window_of_interest.x);
- const auto window_start_y = static_cast<std::size_t>(current_config.window_of_interest.y);
-
- const std::size_t block_width = window_width / Columns;
- const std::size_t block_height = window_height / Rows;
-
- for (std::size_t row = 0; row < Rows; row++) {
- for (std::size_t column = 0; column < Columns; column++) {
- const size_t x_pos = (column * block_width) + window_start_x;
- const size_t y_pos = (row * block_height) + window_start_y;
- auto& statistic = next_state.statistic[column + (row * Columns)];
- statistic = GetStatistic(camera_data.data, x_pos, y_pos, block_width, block_height);
- }
- }
-
- next_state.sampling_number = camera_data.sample;
- next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count();
- next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
- shared_memory->moment_lifo.WriteNextEntry(next_state);
-
- if (!IsProcessorActive()) {
- StartProcessor();
- }
-}
-
-u8 MomentProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const {
- if ((y * ImageWidth) + x >= data.size()) {
- return 0;
- }
- return data[(y * ImageWidth) + x];
-}
-
-MomentProcessor::MomentStatistic MomentProcessor::GetStatistic(const std::vector<u8>& data,
- std::size_t start_x,
- std::size_t start_y,
- std::size_t width,
- std::size_t height) const {
- // The actual implementation is always 320x240
- static constexpr std::size_t RealWidth = 320;
- static constexpr std::size_t RealHeight = 240;
- static constexpr std::size_t Threshold = 30;
- MomentStatistic statistic{};
- std::size_t active_points{};
-
- // Sum all data points on the block that meet with the threshold
- for (std::size_t y = 0; y < width; y++) {
- for (std::size_t x = 0; x < height; x++) {
- const size_t x_pos = x + start_x;
- const size_t y_pos = y + start_y;
- const auto pixel =
- GetPixel(data, x_pos * ImageWidth / RealWidth, y_pos * ImageHeight / RealHeight);
-
- if (pixel < Threshold) {
- continue;
- }
-
- statistic.average_intensity += pixel;
-
- statistic.centroid.x += static_cast<float>(x_pos);
- statistic.centroid.y += static_cast<float>(y_pos);
-
- active_points++;
- }
- }
-
- // Return an empty field if no points were available
- if (active_points == 0) {
- return {};
- }
-
- // Finally calculate the actual centroid and average intensity
- statistic.centroid.x /= static_cast<float>(active_points);
- statistic.centroid.y /= static_cast<float>(active_points);
- statistic.average_intensity /= static_cast<f32>(width * height);
-
- return statistic;
-}
-
-void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig config) {
- current_config.camera_config.exposure_time = config.camera_config.exposure_time;
- current_config.camera_config.gain = config.camera_config.gain;
- current_config.camera_config.is_negative_used = config.camera_config.is_negative_used;
- current_config.camera_config.light_target =
- static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target);
- current_config.window_of_interest = config.window_of_interest;
- current_config.preprocess =
- static_cast<Core::IrSensor::MomentProcessorPreprocess>(config.preprocess);
- current_config.preprocess_intensity_threshold = config.preprocess_intensity_threshold;
-
- npad_device->SetCameraFormat(format);
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/moment_processor.h b/src/core/hle/service/hid/irsensor/moment_processor.h
deleted file mode 100644
index 398cfbdc1..000000000
--- a/src/core/hle/service/hid/irsensor/moment_processor.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irs_ring_lifo.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Core {
-class System;
-}
-
-namespace Core::HID {
-class EmulatedController;
-} // namespace Core::HID
-
-namespace Service::IRS {
-class MomentProcessor final : public ProcessorBase {
-public:
- explicit MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
- std::size_t npad_index);
- ~MomentProcessor() override;
-
- // Called when the processor is initialized
- void StartProcessor() override;
-
- // Called when the processor is suspended
- void SuspendProcessor() override;
-
- // Called when the processor is stopped
- void StopProcessor() override;
-
- // Sets config parameters of the camera
- void SetConfig(Core::IrSensor::PackedMomentProcessorConfig config);
-
-private:
- static constexpr std::size_t Columns = 8;
- static constexpr std::size_t Rows = 6;
-
- // This is nn::irsensor::MomentProcessorConfig
- struct MomentProcessorConfig {
- Core::IrSensor::CameraConfig camera_config;
- Core::IrSensor::IrsRect window_of_interest;
- Core::IrSensor::MomentProcessorPreprocess preprocess;
- u32 preprocess_intensity_threshold;
- };
- static_assert(sizeof(MomentProcessorConfig) == 0x28,
- "MomentProcessorConfig is an invalid size");
-
- // This is nn::irsensor::MomentStatistic
- struct MomentStatistic {
- f32 average_intensity;
- Core::IrSensor::IrsCentroid centroid;
- };
- static_assert(sizeof(MomentStatistic) == 0xC, "MomentStatistic is an invalid size");
-
- // This is nn::irsensor::MomentProcessorState
- struct MomentProcessorState {
- s64 sampling_number;
- u64 timestamp;
- Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
- INSERT_PADDING_BYTES(4);
- std::array<MomentStatistic, Columns * Rows> statistic;
- };
- static_assert(sizeof(MomentProcessorState) == 0x258, "MomentProcessorState is an invalid size");
-
- struct MomentSharedMemory {
- Service::IRS::Lifo<MomentProcessorState, 6> moment_lifo;
- };
- static_assert(sizeof(MomentSharedMemory) == 0xE20, "MomentSharedMemory is an invalid size");
-
- void OnControllerUpdate(Core::HID::ControllerTriggerType type);
- u8 GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const;
- MomentStatistic GetStatistic(const std::vector<u8>& data, std::size_t start_x,
- std::size_t start_y, std::size_t width, std::size_t height) const;
-
- MomentSharedMemory* shared_memory = nullptr;
- MomentProcessorState next_state{};
-
- MomentProcessorConfig current_config{};
- Core::IrSensor::DeviceFormat& device;
- Core::HID::EmulatedController* npad_device;
- int callback_key{};
-
- Core::System& system;
-};
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.cpp b/src/core/hle/service/hid/irsensor/pointing_processor.cpp
deleted file mode 100644
index 929f177fc..000000000
--- a/src/core/hle/service/hid/irsensor/pointing_processor.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/hle/service/hid/irsensor/pointing_processor.h"
-
-namespace Service::IRS {
-PointingProcessor::PointingProcessor(Core::IrSensor::DeviceFormat& device_format)
- : device(device_format) {
- device.mode = Core::IrSensor::IrSensorMode::PointingProcessorMarker;
- device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
-}
-
-PointingProcessor::~PointingProcessor() = default;
-
-void PointingProcessor::StartProcessor() {}
-
-void PointingProcessor::SuspendProcessor() {}
-
-void PointingProcessor::StopProcessor() {}
-
-void PointingProcessor::SetConfig(Core::IrSensor::PackedPointingProcessorConfig config) {
- current_config.window_of_interest = config.window_of_interest;
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.h b/src/core/hle/service/hid/irsensor/pointing_processor.h
deleted file mode 100644
index d63423aff..000000000
--- a/src/core/hle/service/hid/irsensor/pointing_processor.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Service::IRS {
-class PointingProcessor final : public ProcessorBase {
-public:
- explicit PointingProcessor(Core::IrSensor::DeviceFormat& device_format);
- ~PointingProcessor() override;
-
- // Called when the processor is initialized
- void StartProcessor() override;
-
- // Called when the processor is suspended
- void SuspendProcessor() override;
-
- // Called when the processor is stopped
- void StopProcessor() override;
-
- // Sets config parameters of the camera
- void SetConfig(Core::IrSensor::PackedPointingProcessorConfig config);
-
-private:
- // This is nn::irsensor::PointingProcessorConfig
- struct PointingProcessorConfig {
- Core::IrSensor::IrsRect window_of_interest;
- };
- static_assert(sizeof(PointingProcessorConfig) == 0x8,
- "PointingProcessorConfig is an invalid size");
-
- struct PointingProcessorMarkerData {
- u8 pointing_status;
- INSERT_PADDING_BYTES(3);
- u32 unknown;
- float unknown_float1;
- float position_x;
- float position_y;
- float unknown_float2;
- Core::IrSensor::IrsRect window_of_interest;
- };
- static_assert(sizeof(PointingProcessorMarkerData) == 0x20,
- "PointingProcessorMarkerData is an invalid size");
-
- struct PointingProcessorMarkerState {
- s64 sampling_number;
- u64 timestamp;
- std::array<PointingProcessorMarkerData, 0x3> data;
- };
- static_assert(sizeof(PointingProcessorMarkerState) == 0x70,
- "PointingProcessorMarkerState is an invalid size");
-
- PointingProcessorConfig current_config{};
- Core::IrSensor::DeviceFormat& device;
-};
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/processor_base.cpp b/src/core/hle/service/hid/irsensor/processor_base.cpp
deleted file mode 100644
index 4d43ca17a..000000000
--- a/src/core/hle/service/hid/irsensor/processor_base.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Service::IRS {
-
-ProcessorBase::ProcessorBase() {}
-ProcessorBase::~ProcessorBase() = default;
-
-bool ProcessorBase::IsProcessorActive() const {
- return is_active;
-}
-
-std::size_t ProcessorBase::GetDataSize(Core::IrSensor::ImageTransferProcessorFormat format) const {
- switch (format) {
- case Core::IrSensor::ImageTransferProcessorFormat::Size320x240:
- return 320 * 240;
- case Core::IrSensor::ImageTransferProcessorFormat::Size160x120:
- return 160 * 120;
- case Core::IrSensor::ImageTransferProcessorFormat::Size80x60:
- return 80 * 60;
- case Core::IrSensor::ImageTransferProcessorFormat::Size40x30:
- return 40 * 30;
- case Core::IrSensor::ImageTransferProcessorFormat::Size20x15:
- return 20 * 15;
- default:
- return 0;
- }
-}
-
-std::size_t ProcessorBase::GetDataWidth(Core::IrSensor::ImageTransferProcessorFormat format) const {
- switch (format) {
- case Core::IrSensor::ImageTransferProcessorFormat::Size320x240:
- return 320;
- case Core::IrSensor::ImageTransferProcessorFormat::Size160x120:
- return 160;
- case Core::IrSensor::ImageTransferProcessorFormat::Size80x60:
- return 80;
- case Core::IrSensor::ImageTransferProcessorFormat::Size40x30:
- return 40;
- case Core::IrSensor::ImageTransferProcessorFormat::Size20x15:
- return 20;
- default:
- return 0;
- }
-}
-
-std::size_t ProcessorBase::GetDataHeight(
- Core::IrSensor::ImageTransferProcessorFormat format) const {
- switch (format) {
- case Core::IrSensor::ImageTransferProcessorFormat::Size320x240:
- return 240;
- case Core::IrSensor::ImageTransferProcessorFormat::Size160x120:
- return 120;
- case Core::IrSensor::ImageTransferProcessorFormat::Size80x60:
- return 60;
- case Core::IrSensor::ImageTransferProcessorFormat::Size40x30:
- return 30;
- case Core::IrSensor::ImageTransferProcessorFormat::Size20x15:
- return 15;
- default:
- return 0;
- }
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/processor_base.h b/src/core/hle/service/hid/irsensor/processor_base.h
deleted file mode 100644
index bc0d2977b..000000000
--- a/src/core/hle/service/hid/irsensor/processor_base.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/common_types.h"
-#include "core/hid/irs_types.h"
-
-namespace Service::IRS {
-class ProcessorBase {
-public:
- explicit ProcessorBase();
- virtual ~ProcessorBase();
-
- virtual void StartProcessor() = 0;
- virtual void SuspendProcessor() = 0;
- virtual void StopProcessor() = 0;
-
- bool IsProcessorActive() const;
-
-protected:
- /// Returns the number of bytes the image uses
- std::size_t GetDataSize(Core::IrSensor::ImageTransferProcessorFormat format) const;
-
- /// Returns the width of the image
- std::size_t GetDataWidth(Core::IrSensor::ImageTransferProcessorFormat format) const;
-
- /// Returns the height of the image
- std::size_t GetDataHeight(Core::IrSensor::ImageTransferProcessorFormat format) const;
-
- bool is_active{false};
-};
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp b/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp
deleted file mode 100644
index e691c840a..000000000
--- a/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
-
-namespace Service::IRS {
-TeraPluginProcessor::TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format)
- : device(device_format) {
- device.mode = Core::IrSensor::IrSensorMode::TeraPluginProcessor;
- device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
- device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped;
-}
-
-TeraPluginProcessor::~TeraPluginProcessor() = default;
-
-void TeraPluginProcessor::StartProcessor() {}
-
-void TeraPluginProcessor::SuspendProcessor() {}
-
-void TeraPluginProcessor::StopProcessor() {}
-
-void TeraPluginProcessor::SetConfig(Core::IrSensor::PackedTeraPluginProcessorConfig config) {
- current_config.mode = config.mode;
- current_config.unknown_1 = config.unknown_1;
- current_config.unknown_2 = config.unknown_2;
- current_config.unknown_3 = config.unknown_3;
-}
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/irsensor/tera_plugin_processor.h b/src/core/hle/service/hid/irsensor/tera_plugin_processor.h
deleted file mode 100644
index bbea7ed0b..000000000
--- a/src/core/hle/service/hid/irsensor/tera_plugin_processor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "common/bit_field.h"
-#include "common/common_types.h"
-#include "core/hid/irs_types.h"
-#include "core/hle/service/hid/irsensor/processor_base.h"
-
-namespace Service::IRS {
-class TeraPluginProcessor final : public ProcessorBase {
-public:
- explicit TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format);
- ~TeraPluginProcessor() override;
-
- // Called when the processor is initialized
- void StartProcessor() override;
-
- // Called when the processor is suspended
- void SuspendProcessor() override;
-
- // Called when the processor is stopped
- void StopProcessor() override;
-
- // Sets config parameters of the camera
- void SetConfig(Core::IrSensor::PackedTeraPluginProcessorConfig config);
-
-private:
- // This is nn::irsensor::TeraPluginProcessorConfig
- struct TeraPluginProcessorConfig {
- u8 mode;
- u8 unknown_1;
- u8 unknown_2;
- u8 unknown_3;
- };
- static_assert(sizeof(TeraPluginProcessorConfig) == 0x4,
- "TeraPluginProcessorConfig is an invalid size");
-
- struct TeraPluginProcessorState {
- s64 sampling_number;
- u64 timestamp;
- Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level;
- std::array<u8, 0x12c> data;
- };
- static_assert(sizeof(TeraPluginProcessorState) == 0x140,
- "TeraPluginProcessorState is an invalid size");
-
- TeraPluginProcessorConfig current_config{};
- Core::IrSensor::DeviceFormat& device;
-};
-
-} // namespace Service::IRS
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
deleted file mode 100644
index 84b4be3ed..000000000
--- a/src/core/hle/service/hid/resource_manager.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "common/logging/log.h"
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/hid/hid_core.h"
-#include "core/hle/kernel/k_shared_memory.h"
-#include "core/hle/service/hid/resource_manager.h"
-#include "core/hle/service/ipc_helpers.h"
-
-#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/capture_button.h"
-#include "core/hle/service/hid/controllers/console_six_axis.h"
-#include "core/hle/service/hid/controllers/debug_mouse.h"
-#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/hle/service/hid/controllers/digitizer.h"
-#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/hle/service/hid/controllers/home_button.h"
-#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/hle/service/hid/controllers/mouse.h"
-#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/palma.h"
-#include "core/hle/service/hid/controllers/seven_six_axis.h"
-#include "core/hle/service/hid/controllers/six_axis.h"
-#include "core/hle/service/hid/controllers/sleep_button.h"
-#include "core/hle/service/hid/controllers/touchscreen.h"
-#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
-#include "core/hle/service/hid/controllers/unique_pad.h"
-
-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 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)
-
-ResourceManager::ResourceManager(Core::System& system_)
- : system{system_}, service_context{system_, "hid"} {
- applet_resource = std::make_shared<AppletResource>(system);
-}
-
-ResourceManager::~ResourceManager() = default;
-
-void ResourceManager::Initialize() {
- if (is_initialized) {
- return;
- }
-
- system.HIDCore().ReloadInputDevices();
-
- InitializeHidCommonSampler();
- InitializeTouchScreenSampler();
- InitializeConsoleSixAxisSampler();
- InitializeAHidSampler();
-
- is_initialized = true;
-}
-
-std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
- return applet_resource;
-}
-
-std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
- return capture_button;
-}
-
-std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const {
- return console_six_axis;
-}
-
-std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const {
- return debug_mouse;
-}
-
-std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const {
- return debug_pad;
-}
-
-std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const {
- return digitizer;
-}
-
-std::shared_ptr<Gesture> ResourceManager::GetGesture() const {
- return gesture;
-}
-
-std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const {
- return home_button;
-}
-
-std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const {
- return keyboard;
-}
-
-std::shared_ptr<Mouse> ResourceManager::GetMouse() const {
- return mouse;
-}
-
-std::shared_ptr<NPad> ResourceManager::GetNpad() const {
- return npad;
-}
-
-std::shared_ptr<Palma> ResourceManager::GetPalma() const {
- return palma;
-}
-
-std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const {
- return seven_six_axis;
-}
-
-std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const {
- return six_axis;
-}
-
-std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const {
- return sleep_button;
-}
-
-std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const {
- return touch_screen;
-}
-
-std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
- return unique_pad;
-}
-
-Result ResourceManager::CreateAppletResource(u64 aruid) {
- if (aruid == 0) {
- const auto result = RegisterCoreAppletResource();
- if (result.IsError()) {
- return result;
- }
- return GetNpad()->Activate();
- }
-
- const auto result = CreateAppletResourceImpl(aruid);
- if (result.IsError()) {
- return result;
- }
-
- // Homebrew doesn't try to activate some controllers, so we activate them by default
- npad->Activate();
- six_axis->Activate();
- touch_screen->Activate();
-
- return GetNpad()->Activate(aruid);
-}
-
-Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
- std::scoped_lock lock{shared_mutex};
- return applet_resource->CreateAppletResource(aruid);
-}
-
-void ResourceManager::InitializeHidCommonSampler() {
- debug_pad = std::make_shared<DebugPad>(system.HIDCore());
- mouse = std::make_shared<Mouse>(system.HIDCore());
- debug_mouse = std::make_shared<DebugMouse>(system.HIDCore());
- keyboard = std::make_shared<Keyboard>(system.HIDCore());
- unique_pad = std::make_shared<UniquePad>(system.HIDCore());
- npad = std::make_shared<NPad>(system.HIDCore(), service_context);
- gesture = std::make_shared<Gesture>(system.HIDCore());
- home_button = std::make_shared<HomeButton>(system.HIDCore());
- sleep_button = std::make_shared<SleepButton>(system.HIDCore());
- capture_button = std::make_shared<CaptureButton>(system.HIDCore());
- digitizer = std::make_shared<Digitizer>(system.HIDCore());
-
- palma = std::make_shared<Palma>(system.HIDCore(), service_context);
- six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
-
- debug_pad->SetAppletResource(applet_resource);
- digitizer->SetAppletResource(applet_resource);
- keyboard->SetAppletResource(applet_resource);
- npad->SetAppletResource(applet_resource);
- six_axis->SetAppletResource(applet_resource);
- mouse->SetAppletResource(applet_resource);
- debug_mouse->SetAppletResource(applet_resource);
- home_button->SetAppletResource(applet_resource);
- sleep_button->SetAppletResource(applet_resource);
- capture_button->SetAppletResource(applet_resource);
-}
-
-void ResourceManager::InitializeTouchScreenSampler() {
- gesture = std::make_shared<Gesture>(system.HIDCore());
- touch_screen = std::make_shared<TouchScreen>(system.HIDCore());
-
- touch_screen->SetAppletResource(applet_resource);
- gesture->SetAppletResource(applet_resource);
-}
-
-void ResourceManager::InitializeConsoleSixAxisSampler() {
- console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore());
- seven_six_axis = std::make_shared<SevenSixAxis>(system);
-
- console_six_axis->SetAppletResource(applet_resource);
-}
-
-void ResourceManager::InitializeAHidSampler() {
- // TODO
-}
-
-Result ResourceManager::RegisterCoreAppletResource() {
- std::scoped_lock lock{shared_mutex};
- return applet_resource->RegisterCoreAppletResource();
-}
-
-Result ResourceManager::UnregisterCoreAppletResource() {
- std::scoped_lock lock{shared_mutex};
- return applet_resource->UnregisterCoreAppletResource();
-}
-
-Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) {
- std::scoped_lock lock{shared_mutex};
- return applet_resource->RegisterAppletResourceUserId(aruid, bool_value);
-}
-
-void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) {
- std::scoped_lock lock{shared_mutex};
- applet_resource->UnregisterAppletResourceUserId(aruid);
-}
-
-Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
- std::scoped_lock lock{shared_mutex};
- return applet_resource->GetSharedMemoryHandle(out_handle, aruid);
-}
-
-void ResourceManager::FreeAppletResourceId(u64 aruid) {
- std::scoped_lock lock{shared_mutex};
- applet_resource->FreeAppletResourceId(aruid);
-}
-
-void ResourceManager::EnableInput(u64 aruid, bool is_enabled) {
- std::scoped_lock lock{shared_mutex};
- applet_resource->EnableInput(aruid, is_enabled);
-}
-
-void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
- std::scoped_lock lock{shared_mutex};
- applet_resource->EnableSixAxisSensor(aruid, is_enabled);
-}
-
-void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) {
- std::scoped_lock lock{shared_mutex};
- applet_resource->EnablePadInput(aruid, is_enabled);
-}
-
-void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
- std::scoped_lock lock{shared_mutex};
- applet_resource->EnableTouchScreen(aruid, is_enabled);
-}
-
-void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
- debug_pad->OnUpdate(core_timing);
- digitizer->OnUpdate(core_timing);
- unique_pad->OnUpdate(core_timing);
- gesture->OnUpdate(core_timing);
- touch_screen->OnUpdate(core_timing);
- palma->OnUpdate(core_timing);
- home_button->OnUpdate(core_timing);
- sleep_button->OnUpdate(core_timing);
- capture_button->OnUpdate(core_timing);
-}
-
-void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
- npad->OnUpdate(core_timing);
-}
-
-void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
- mouse->OnUpdate(core_timing);
- debug_mouse->OnUpdate(core_timing);
- keyboard->OnUpdate(core_timing);
-}
-
-void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) {
- auto& core_timing = system.CoreTiming();
- six_axis->OnUpdate(core_timing);
- seven_six_axis->OnUpdate(core_timing);
- console_six_axis->OnUpdate(core_timing);
-}
-
-IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
- u64 applet_resource_user_id)
- : ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id},
- resource_manager{resource} {
- static const FunctionInfo functions[] = {
- {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
- };
- RegisterHandlers(functions);
-
- // Register update callbacks
- npad_update_event = Core::Timing::CreateEvent(
- "HID::UpdatePadCallback",
- [this, resource](
- s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- resource->UpdateNpad(ns_late);
- return std::nullopt;
- });
- default_update_event = Core::Timing::CreateEvent(
- "HID::UpdateDefaultCallback",
- [this, resource](
- s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- resource->UpdateControllers(ns_late);
- return std::nullopt;
- });
- mouse_keyboard_update_event = Core::Timing::CreateEvent(
- "HID::UpdateMouseKeyboardCallback",
- [this, resource](
- s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- resource->UpdateMouseKeyboard(ns_late);
- return std::nullopt;
- });
- motion_update_event = Core::Timing::CreateEvent(
- "HID::UpdateMotionCallback",
- [this, resource](
- s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- const auto guard = LockService();
- resource->UpdateMotion(ns_late);
- return std::nullopt;
- });
-
- 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,
- motion_update_event);
-}
-
-IAppletResource::~IAppletResource() {
- system.CoreTiming().UnscheduleEvent(npad_update_event);
- system.CoreTiming().UnscheduleEvent(default_update_event);
- system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event);
- system.CoreTiming().UnscheduleEvent(motion_update_event);
- resource_manager->FreeAppletResourceId(aruid);
-}
-
-void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
- Kernel::KSharedMemory* handle;
- const auto result = resource_manager->GetSharedMemoryHandle(&handle, aruid);
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw);
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(result);
- rb.PushCopyObjects(handle);
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
deleted file mode 100644
index 70d9b6550..000000000
--- a/src/core/hle/service/hid/resource_manager.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#pragma once
-
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Core {
-class System;
-}
-
-namespace Core::Timing {
-struct EventType;
-}
-
-namespace Kernel {
-class KSharedMemory;
-}
-
-namespace Service::HID {
-class AppletResource;
-class CaptureButton;
-class Controller_Stubbed;
-class ConsoleSixAxis;
-class DebugMouse;
-class DebugPad;
-class Digitizer;
-class Gesture;
-class HomeButton;
-class Keyboard;
-class Mouse;
-class NPad;
-class Palma;
-class SevenSixAxis;
-class SixAxis;
-class SleepButton;
-class TouchScreen;
-class UniquePad;
-
-class ResourceManager {
-
-public:
- explicit ResourceManager(Core::System& system_);
- ~ResourceManager();
-
- void Initialize();
-
- std::shared_ptr<AppletResource> GetAppletResource() const;
- std::shared_ptr<CaptureButton> GetCaptureButton() const;
- std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
- std::shared_ptr<DebugMouse> GetDebugMouse() const;
- std::shared_ptr<DebugPad> GetDebugPad() const;
- std::shared_ptr<Digitizer> GetDigitizer() const;
- std::shared_ptr<Gesture> GetGesture() const;
- std::shared_ptr<HomeButton> GetHomeButton() const;
- std::shared_ptr<Keyboard> GetKeyboard() const;
- std::shared_ptr<Mouse> GetMouse() const;
- std::shared_ptr<NPad> GetNpad() const;
- std::shared_ptr<Palma> GetPalma() const;
- std::shared_ptr<SevenSixAxis> GetSevenSixAxis() const;
- std::shared_ptr<SixAxis> GetSixAxis() const;
- std::shared_ptr<SleepButton> GetSleepButton() const;
- std::shared_ptr<TouchScreen> GetTouchScreen() const;
- std::shared_ptr<UniquePad> GetUniquePad() const;
-
- Result CreateAppletResource(u64 aruid);
-
- Result RegisterCoreAppletResource();
- Result UnregisterCoreAppletResource();
- Result RegisterAppletResourceUserId(u64 aruid, bool bool_value);
- void UnregisterAppletResourceUserId(u64 aruid);
-
- Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
- void FreeAppletResourceId(u64 aruid);
-
- void EnableInput(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);
-
- void UpdateControllers(std::chrono::nanoseconds ns_late);
- void UpdateNpad(std::chrono::nanoseconds ns_late);
- void UpdateMouseKeyboard(std::chrono::nanoseconds ns_late);
- void UpdateMotion(std::chrono::nanoseconds ns_late);
-
-private:
- Result CreateAppletResourceImpl(u64 aruid);
- void InitializeHidCommonSampler();
- void InitializeTouchScreenSampler();
- void InitializeConsoleSixAxisSampler();
- void InitializeAHidSampler();
-
- bool is_initialized{false};
-
- mutable std::mutex shared_mutex;
- std::shared_ptr<AppletResource> applet_resource = nullptr;
-
- std::shared_ptr<CaptureButton> capture_button = nullptr;
- std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
- std::shared_ptr<DebugMouse> debug_mouse = nullptr;
- std::shared_ptr<DebugPad> debug_pad = nullptr;
- std::shared_ptr<Digitizer> digitizer = nullptr;
- std::shared_ptr<Gesture> gesture = nullptr;
- std::shared_ptr<HomeButton> home_button = nullptr;
- std::shared_ptr<Keyboard> keyboard = nullptr;
- std::shared_ptr<Mouse> mouse = nullptr;
- std::shared_ptr<NPad> npad = nullptr;
- std::shared_ptr<Palma> palma = nullptr;
- std::shared_ptr<SevenSixAxis> seven_six_axis = nullptr;
- std::shared_ptr<SixAxis> six_axis = nullptr;
- std::shared_ptr<SleepButton> sleep_button = nullptr;
- std::shared_ptr<TouchScreen> touch_screen = nullptr;
- std::shared_ptr<UniquePad> unique_pad = nullptr;
-
- // TODO: Create these resources
- // std::shared_ptr<AudioControl> audio_control = nullptr;
- // std::shared_ptr<ButtonConfig> button_config = nullptr;
- // std::shared_ptr<Config> config = nullptr;
- // std::shared_ptr<Connection> connection = nullptr;
- // std::shared_ptr<CustomConfig> custom_config = nullptr;
- // std::shared_ptr<Digitizer> digitizer = nullptr;
- // std::shared_ptr<Hdls> hdls = nullptr;
- // std::shared_ptr<PlayReport> play_report = nullptr;
- // std::shared_ptr<Rail> rail = nullptr;
-
- Core::System& system;
- KernelHelpers::ServiceContext service_context;
-};
-
-class IAppletResource final : public ServiceFramework<IAppletResource> {
-public:
- explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
- u64 applet_resource_user_id);
- ~IAppletResource() override;
-
-private:
- void GetSharedMemoryHandle(HLERequestContext& ctx);
-
- 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;
-
- u64 aruid;
- std::shared_ptr<ResourceManager> resource_manager;
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/ring_lifo.h b/src/core/hle/service/hid/ring_lifo.h
deleted file mode 100644
index 0816784e0..000000000
--- a/src/core/hle/service/hid/ring_lifo.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-
-#include "common/common_types.h"
-
-namespace Service::HID {
-
-template <typename State>
-struct AtomicStorage {
- s64 sampling_number;
- State state;
-};
-
-template <typename State, std::size_t max_buffer_size>
-struct Lifo {
- s64 timestamp{};
- s64 total_buffer_count = static_cast<s64>(max_buffer_size);
- s64 buffer_tail{};
- s64 buffer_count{};
- std::array<AtomicStorage<State>, max_buffer_size> entries{};
-
- const AtomicStorage<State>& ReadCurrentEntry() const {
- return entries[buffer_tail];
- }
-
- const AtomicStorage<State>& ReadPreviousEntry() const {
- return entries[GetPreviousEntryIndex()];
- }
-
- std::size_t GetPreviousEntryIndex() const {
- return static_cast<size_t>((buffer_tail + max_buffer_size - 1) % max_buffer_size);
- }
-
- std::size_t GetNextEntryIndex() const {
- return static_cast<size_t>((buffer_tail + 1) % max_buffer_size);
- }
-
- void WriteNextEntry(const State& new_state) {
- if (buffer_count < static_cast<s64>(max_buffer_size) - 1) {
- buffer_count++;
- }
- buffer_tail = GetNextEntryIndex();
- const auto& previous_entry = ReadPreviousEntry();
- entries[buffer_tail].sampling_number = previous_entry.sampling_number + 1;
- entries[buffer_tail].state = new_state;
- }
-};
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index f97e5b44c..b37fb6da3 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -22,9 +22,6 @@
#include "common/string_util.h"
#include "common/tiny_mt.h"
#include "core/core.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/mii/mii_manager.h"
@@ -33,6 +30,9 @@
#include "core/hle/service/nfc/mifare_result.h"
#include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/time_manager.h"
+#include "hid_core/frontend/emulated_controller.h"
+#include "hid_core/hid_core.h"
+#include "hid_core/hid_types.h"
namespace Service::NFC {
NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp
index ad534177d..44f651b87 100644
--- a/src/core/hle/service/nfc/common/device_manager.cpp
+++ b/src/core/hle/service/nfc/common/device_manager.cpp
@@ -5,15 +5,15 @@
#include "common/logging/log.h"
#include "core/core.h"
-#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
-#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/nfc/common/device.h"
#include "core/hle/service/nfc/common/device_manager.h"
#include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/time_manager.h"
+#include "hid_core/hid_types.h"
+#include "hid_core/hid_util.h"
namespace Service::NFC {
diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h
index c9f038e32..f02bdccf5 100644
--- a/src/core/hle/service/nfc/common/device_manager.h
+++ b/src/core/hle/service/nfc/common/device_manager.h
@@ -8,13 +8,13 @@
#include <optional>
#include <span>
-#include "core/hid/hid_types.h"
#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/nfc/mifare_types.h"
#include "core/hle/service/nfc/nfc_types.h"
#include "core/hle/service/nfp/nfp_types.h"
#include "core/hle/service/service.h"
#include "core/hle/service/time/clock_types.h"
+#include "hid_core/hid_types.h"
namespace Service::NFC {
class NfcDevice;
diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp
index 179c7ba2c..a71cf74b8 100644
--- a/src/core/hle/service/nfc/nfc_interface.cpp
+++ b/src/core/hle/service/nfc/nfc_interface.cpp
@@ -3,7 +3,6 @@
#include "common/logging/log.h"
#include "core/core.h"
-#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/nfc/common/device.h"
@@ -15,6 +14,7 @@
#include "core/hle/service/nfc/nfc_types.h"
#include "core/hle/service/nfp/nfp_result.h"
#include "core/hle/service/time/clock_types.h"
+#include "hid_core/hid_types.h"
namespace Service::NFC {
diff --git a/src/core/hle/service/nfp/nfp_interface.cpp b/src/core/hle/service/nfp/nfp_interface.cpp
index 34ef9d82d..5ba6d1742 100644
--- a/src/core/hle/service/nfp/nfp_interface.cpp
+++ b/src/core/hle/service/nfp/nfp_interface.cpp
@@ -3,7 +3,6 @@
#include "common/logging/log.h"
#include "core/core.h"
-#include "core/hid/hid_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/nfc/common/device.h"
@@ -12,6 +11,7 @@
#include "core/hle/service/nfp/nfp_interface.h"
#include "core/hle/service/nfp/nfp_result.h"
#include "core/hle/service/nfp/nfp_types.h"
+#include "hid_core/hid_types.h"
namespace Service::NFP {
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 7bc5b5ae5..96fa7fa3a 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -9,12 +9,12 @@
#include "core/core_timing.h"
#include "core/hle/kernel/k_page_table.h"
#include "core/hle/kernel/k_process.h"
-#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/hid_server.h"
-#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/sm/sm.h"
#include "core/memory.h"
#include "core/memory/cheat_engine.h"
+#include "hid_core/resource_manager.h"
+#include "hid_core/resources/npad/npad.h"
namespace Core::Memory {
namespace {