mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Merge pull request #9191 from german77/touching_souls
core: hid: Implement true multitouch support
This commit is contained in:
		@@ -19,27 +19,26 @@ void EmulatedConsole::ReloadFromSettings() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EmulatedConsole::SetTouchParams() {
 | 
					void EmulatedConsole::SetTouchParams() {
 | 
				
			||||||
    // TODO(german77): Support any number of fingers
 | 
					 | 
				
			||||||
    std::size_t index = 0;
 | 
					    std::size_t index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Hardcode mouse, touchscreen and cemuhook parameters
 | 
					    // We can't use mouse as touch if native mouse is enabled
 | 
				
			||||||
    if (!Settings::values.mouse_enabled) {
 | 
					    if (!Settings::values.mouse_enabled) {
 | 
				
			||||||
        // We can't use mouse as touch if native mouse is enabled
 | 
					 | 
				
			||||||
        touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
 | 
					        touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    touch_params[index++] =
 | 
					    touch_params[index++] =
 | 
				
			||||||
        Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0,touch_id:0"};
 | 
					        Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"};
 | 
				
			||||||
    touch_params[index++] =
 | 
					    touch_params[index++] =
 | 
				
			||||||
        Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1,touch_id:1"};
 | 
					        Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072"};
 | 
				
			||||||
    touch_params[index++] =
 | 
					
 | 
				
			||||||
        Common::ParamPackage{"engine:touch,axis_x:4,axis_y:5,button:2,touch_id:2"};
 | 
					    for (int i = 0; i < static_cast<int>(MaxActiveTouchInputs); i++) {
 | 
				
			||||||
    touch_params[index++] =
 | 
					        Common::ParamPackage touchscreen_param{};
 | 
				
			||||||
        Common::ParamPackage{"engine:touch,axis_x:6,axis_y:7,button:3,touch_id:3"};
 | 
					        touchscreen_param.Set("engine", "touch");
 | 
				
			||||||
    touch_params[index++] =
 | 
					        touchscreen_param.Set("axis_x", i * 2);
 | 
				
			||||||
        Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536,touch_id:0"};
 | 
					        touchscreen_param.Set("axis_y", (i * 2) + 1);
 | 
				
			||||||
    touch_params[index++] =
 | 
					        touchscreen_param.Set("button", i);
 | 
				
			||||||
        Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072,touch_id:1"};
 | 
					        touch_params[index++] = touchscreen_param;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auto button_index =
 | 
					    const auto button_index =
 | 
				
			||||||
        static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
 | 
					        static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
 | 
				
			||||||
@@ -47,7 +46,7 @@ void EmulatedConsole::SetTouchParams() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Map the rest of the fingers from touch from button configuration
 | 
					    // Map the rest of the fingers from touch from button configuration
 | 
				
			||||||
    for (const auto& config_entry : touch_buttons) {
 | 
					    for (const auto& config_entry : touch_buttons) {
 | 
				
			||||||
        if (index >= touch_params.size()) {
 | 
					        if (index >= MaxTouchDevices) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Common::ParamPackage params{config_entry};
 | 
					        Common::ParamPackage params{config_entry};
 | 
				
			||||||
@@ -60,7 +59,6 @@ void EmulatedConsole::SetTouchParams() {
 | 
				
			|||||||
        touch_button_params.Set("button", params.Serialize());
 | 
					        touch_button_params.Set("button", params.Serialize());
 | 
				
			||||||
        touch_button_params.Set("x", x);
 | 
					        touch_button_params.Set("x", x);
 | 
				
			||||||
        touch_button_params.Set("y", y);
 | 
					        touch_button_params.Set("y", y);
 | 
				
			||||||
        touch_button_params.Set("touch_id", static_cast<int>(index));
 | 
					 | 
				
			||||||
        touch_params[index] = touch_button_params;
 | 
					        touch_params[index] = touch_button_params;
 | 
				
			||||||
        index++;
 | 
					        index++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -178,12 +176,38 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index) {
 | 
					void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index) {
 | 
				
			||||||
    if (index >= console.touch_values.size()) {
 | 
					    if (index >= MaxTouchDevices) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    std::unique_lock lock{mutex};
 | 
					    std::unique_lock lock{mutex};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.touch_values[index] = TransformToTouch(callback);
 | 
					    const auto touch_input = TransformToTouch(callback);
 | 
				
			||||||
 | 
					    auto touch_index = GetIndexFromFingerId(index);
 | 
				
			||||||
 | 
					    bool is_new_input = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!touch_index.has_value() && touch_input.pressed.value) {
 | 
				
			||||||
 | 
					        touch_index = GetNextFreeIndex();
 | 
				
			||||||
 | 
					        is_new_input = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // No free entries or invalid state. Ignore input
 | 
				
			||||||
 | 
					    if (!touch_index.has_value()) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto& touch_value = console.touch_values[touch_index.value()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (is_new_input) {
 | 
				
			||||||
 | 
					        touch_value.pressed.value = true;
 | 
				
			||||||
 | 
					        touch_value.id = static_cast<u32>(index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    touch_value.x = touch_input.x;
 | 
				
			||||||
 | 
					    touch_value.y = touch_input.y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!touch_input.pressed.value) {
 | 
				
			||||||
 | 
					        touch_value.pressed.value = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (is_configuring) {
 | 
					    if (is_configuring) {
 | 
				
			||||||
        lock.unlock();
 | 
					        lock.unlock();
 | 
				
			||||||
@@ -191,11 +215,15 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(german77): Remap touch id in sequential order
 | 
					    // Touch outside allowed range. Ignore input
 | 
				
			||||||
    console.touch_state[index] = {
 | 
					    if (touch_index.value() >= MaxActiveTouchInputs) {
 | 
				
			||||||
        .position = {console.touch_values[index].x.value, console.touch_values[index].y.value},
 | 
					        return;
 | 
				
			||||||
        .id = static_cast<u32>(console.touch_values[index].id),
 | 
					    }
 | 
				
			||||||
        .pressed = console.touch_values[index].pressed.value,
 | 
					
 | 
				
			||||||
 | 
					    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();
 | 
					    lock.unlock();
 | 
				
			||||||
@@ -222,6 +250,28 @@ TouchFingerState EmulatedConsole::GetTouch() const {
 | 
				
			|||||||
    return console.touch_state;
 | 
					    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) {
 | 
					void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
 | 
				
			||||||
    std::scoped_lock lock{callback_mutex};
 | 
					    std::scoped_lock lock{callback_mutex};
 | 
				
			||||||
    for (const auto& poller_pair : callback_list) {
 | 
					    for (const auto& poller_pair : callback_list) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
#include <mutex>
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					#include <optional>
 | 
				
			||||||
#include <unordered_map>
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "common/common_funcs.h"
 | 
					#include "common/common_funcs.h"
 | 
				
			||||||
@@ -20,6 +21,8 @@
 | 
				
			|||||||
#include "core/hid/motion_input.h"
 | 
					#include "core/hid/motion_input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Core::HID {
 | 
					namespace Core::HID {
 | 
				
			||||||
 | 
					static constexpr std::size_t MaxTouchDevices = 32;
 | 
				
			||||||
 | 
					static constexpr std::size_t MaxActiveTouchInputs = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ConsoleMotionInfo {
 | 
					struct ConsoleMotionInfo {
 | 
				
			||||||
    Common::Input::MotionStatus raw_status{};
 | 
					    Common::Input::MotionStatus raw_status{};
 | 
				
			||||||
@@ -27,13 +30,13 @@ struct ConsoleMotionInfo {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using ConsoleMotionDevices = std::unique_ptr<Common::Input::InputDevice>;
 | 
					using ConsoleMotionDevices = std::unique_ptr<Common::Input::InputDevice>;
 | 
				
			||||||
using TouchDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, 16>;
 | 
					using TouchDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, MaxTouchDevices>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using ConsoleMotionParams = Common::ParamPackage;
 | 
					using ConsoleMotionParams = Common::ParamPackage;
 | 
				
			||||||
using TouchParams = std::array<Common::ParamPackage, 16>;
 | 
					using TouchParams = std::array<Common::ParamPackage, MaxTouchDevices>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using ConsoleMotionValues = ConsoleMotionInfo;
 | 
					using ConsoleMotionValues = ConsoleMotionInfo;
 | 
				
			||||||
using TouchValues = std::array<Common::Input::TouchStatus, 16>;
 | 
					using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct TouchFinger {
 | 
					struct TouchFinger {
 | 
				
			||||||
    u64 last_touch{};
 | 
					    u64 last_touch{};
 | 
				
			||||||
@@ -55,7 +58,7 @@ struct ConsoleMotion {
 | 
				
			|||||||
    bool is_at_rest{};
 | 
					    bool is_at_rest{};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using TouchFingerState = std::array<TouchFinger, 16>;
 | 
					using TouchFingerState = std::array<TouchFinger, MaxActiveTouchInputs>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ConsoleStatus {
 | 
					struct ConsoleStatus {
 | 
				
			||||||
    // Data from input_common
 | 
					    // Data from input_common
 | 
				
			||||||
@@ -166,6 +169,10 @@ private:
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    void SetTouch(const Common::Input::CallbackStatus& callback, std::size_t index);
 | 
					    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
 | 
					     * Triggers a callback that something has changed on the console status
 | 
				
			||||||
     * @param type Input type of the event to trigger
 | 
					     * @param type Input type of the event to trigger
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -200,9 +200,6 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
 | 
				
			|||||||
    x = std::clamp(x, 0.0f, 1.0f);
 | 
					    x = std::clamp(x, 0.0f, 1.0f);
 | 
				
			||||||
    y = std::clamp(y, 0.0f, 1.0f);
 | 
					    y = std::clamp(y, 0.0f, 1.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Limit id to maximum number of fingers
 | 
					 | 
				
			||||||
    status.id = std::clamp(status.id, 0, 16);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (status.pressed.inverted) {
 | 
					    if (status.pressed.inverted) {
 | 
				
			||||||
        status.pressed.value = !status.pressed.value;
 | 
					        status.pressed.value = !status.pressed.value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,8 +36,9 @@ namespace Service::HID {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Updating period for each HID device.
 | 
					// Updating period for each HID device.
 | 
				
			||||||
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
 | 
					// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
 | 
				
			||||||
// Correct pad_update_ns is 4ms this is overclocked to lower input lag
 | 
					// Correct npad_update_ns is 4ms this is overclocked to lower input lag
 | 
				
			||||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
 | 
					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 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)
 | 
					constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000};         // (5ms, 200Hz)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,8 +76,16 @@ IAppletResource::IAppletResource(Core::System& system_,
 | 
				
			|||||||
    GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
 | 
					    GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Register update callbacks
 | 
					    // Register update callbacks
 | 
				
			||||||
    pad_update_event = Core::Timing::CreateEvent(
 | 
					    npad_update_event = Core::Timing::CreateEvent(
 | 
				
			||||||
        "HID::UpdatePadCallback",
 | 
					        "HID::UpdatePadCallback",
 | 
				
			||||||
 | 
					        [this](std::uintptr_t user_data, s64 time,
 | 
				
			||||||
 | 
					               std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
 | 
				
			||||||
 | 
					            const auto guard = LockService();
 | 
				
			||||||
 | 
					            UpdateNpad(user_data, ns_late);
 | 
				
			||||||
 | 
					            return std::nullopt;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    default_update_event = Core::Timing::CreateEvent(
 | 
				
			||||||
 | 
					        "HID::UpdateDefaultCallback",
 | 
				
			||||||
        [this](std::uintptr_t user_data, s64 time,
 | 
					        [this](std::uintptr_t user_data, s64 time,
 | 
				
			||||||
               std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
 | 
					               std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
 | 
				
			||||||
            const auto guard = LockService();
 | 
					            const auto guard = LockService();
 | 
				
			||||||
@@ -100,7 +109,9 @@ IAppletResource::IAppletResource(Core::System& system_,
 | 
				
			|||||||
            return std::nullopt;
 | 
					            return std::nullopt;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    system.CoreTiming().ScheduleLoopingEvent(pad_update_ns, pad_update_ns, pad_update_event);
 | 
					    system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
 | 
				
			||||||
 | 
					    system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
 | 
				
			||||||
 | 
					                                             default_update_event);
 | 
				
			||||||
    system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
 | 
					    system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
 | 
				
			||||||
                                             mouse_keyboard_update_event);
 | 
					                                             mouse_keyboard_update_event);
 | 
				
			||||||
    system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
 | 
					    system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
 | 
				
			||||||
@@ -118,7 +129,8 @@ void IAppletResource::DeactivateController(HidController controller) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IAppletResource::~IAppletResource() {
 | 
					IAppletResource::~IAppletResource() {
 | 
				
			||||||
    system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
 | 
					    system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
 | 
				
			||||||
 | 
					    system.CoreTiming().UnscheduleEvent(default_update_event, 0);
 | 
				
			||||||
    system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
 | 
					    system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
 | 
				
			||||||
    system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
 | 
					    system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -144,10 +156,20 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
 | 
				
			|||||||
        if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
 | 
					        if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        // Npad has it's own update event
 | 
				
			||||||
 | 
					        if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        controller->OnUpdate(core_timing);
 | 
					        controller->OnUpdate(core_timing);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
 | 
				
			||||||
 | 
					    auto& core_timing = system.CoreTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
 | 
					void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
 | 
				
			||||||
                                          std::chrono::nanoseconds ns_late) {
 | 
					                                          std::chrono::nanoseconds ns_late) {
 | 
				
			||||||
    auto& core_timing = system.CoreTiming();
 | 
					    auto& core_timing = system.CoreTiming();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,12 +71,14 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
 | 
					    void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
 | 
				
			||||||
    void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
					    void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
				
			||||||
 | 
					    void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
				
			||||||
    void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
					    void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
				
			||||||
    void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
					    void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    KernelHelpers::ServiceContext& service_context;
 | 
					    KernelHelpers::ServiceContext& service_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::shared_ptr<Core::Timing::EventType> pad_update_event;
 | 
					    std::shared_ptr<Core::Timing::EventType> npad_update_event;
 | 
				
			||||||
 | 
					    std::shared_ptr<Core::Timing::EventType> default_update_event;
 | 
				
			||||||
    std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
 | 
					    std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
 | 
				
			||||||
    std::shared_ptr<Core::Timing::EventType> motion_update_event;
 | 
					    std::shared_ptr<Core::Timing::EventType> motion_update_event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,8 +10,8 @@ namespace InputCommon {
 | 
				
			|||||||
class TouchFromButtonDevice final : public Common::Input::InputDevice {
 | 
					class TouchFromButtonDevice final : public Common::Input::InputDevice {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    using Button = std::unique_ptr<Common::Input::InputDevice>;
 | 
					    using Button = std::unique_ptr<Common::Input::InputDevice>;
 | 
				
			||||||
    TouchFromButtonDevice(Button button_, int touch_id_, float x_, float y_)
 | 
					    TouchFromButtonDevice(Button button_, float x_, float y_)
 | 
				
			||||||
        : button(std::move(button_)), touch_id(touch_id_), x(x_), y(y_) {
 | 
					        : button(std::move(button_)), x(x_), y(y_) {
 | 
				
			||||||
        last_button_value = false;
 | 
					        last_button_value = false;
 | 
				
			||||||
        button->SetCallback({
 | 
					        button->SetCallback({
 | 
				
			||||||
            .on_change =
 | 
					            .on_change =
 | 
				
			||||||
@@ -34,7 +34,6 @@ public:
 | 
				
			|||||||
            .pressed = button_status,
 | 
					            .pressed = button_status,
 | 
				
			||||||
            .x = {},
 | 
					            .x = {},
 | 
				
			||||||
            .y = {},
 | 
					            .y = {},
 | 
				
			||||||
            .id = touch_id,
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        status.x.properties = properties;
 | 
					        status.x.properties = properties;
 | 
				
			||||||
        status.y.properties = properties;
 | 
					        status.y.properties = properties;
 | 
				
			||||||
@@ -62,7 +61,6 @@ public:
 | 
				
			|||||||
private:
 | 
					private:
 | 
				
			||||||
    Button button;
 | 
					    Button button;
 | 
				
			||||||
    bool last_button_value;
 | 
					    bool last_button_value;
 | 
				
			||||||
    const int touch_id;
 | 
					 | 
				
			||||||
    const float x;
 | 
					    const float x;
 | 
				
			||||||
    const float y;
 | 
					    const float y;
 | 
				
			||||||
    const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false};
 | 
					    const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false};
 | 
				
			||||||
@@ -73,10 +71,9 @@ std::unique_ptr<Common::Input::InputDevice> TouchFromButton::Create(
 | 
				
			|||||||
    const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
 | 
					    const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
 | 
				
			||||||
    auto button = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
 | 
					    auto button = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
 | 
				
			||||||
        params.Get("button", null_engine));
 | 
					        params.Get("button", null_engine));
 | 
				
			||||||
    const auto touch_id = params.Get("touch_id", 0);
 | 
					 | 
				
			||||||
    const float x = params.Get("x", 0.0f) / 1280.0f;
 | 
					    const float x = params.Get("x", 0.0f) / 1280.0f;
 | 
				
			||||||
    const float y = params.Get("y", 0.0f) / 720.0f;
 | 
					    const float y = params.Get("y", 0.0f) / 720.0f;
 | 
				
			||||||
    return std::make_unique<TouchFromButtonDevice>(std::move(button), touch_id, x, y);
 | 
					    return std::make_unique<TouchFromButtonDevice>(std::move(button), x, y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace InputCommon
 | 
					} // namespace InputCommon
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -229,13 +229,12 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class InputFromTouch final : public Common::Input::InputDevice {
 | 
					class InputFromTouch final : public Common::Input::InputDevice {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    explicit InputFromTouch(PadIdentifier identifier_, int touch_id_, int button_, bool toggle_,
 | 
					    explicit InputFromTouch(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
 | 
				
			||||||
                            bool inverted_, int axis_x_, int axis_y_,
 | 
					                            int axis_x_, int axis_y_, Common::Input::AnalogProperties properties_x_,
 | 
				
			||||||
                            Common::Input::AnalogProperties properties_x_,
 | 
					 | 
				
			||||||
                            Common::Input::AnalogProperties properties_y_,
 | 
					                            Common::Input::AnalogProperties properties_y_,
 | 
				
			||||||
                            InputEngine* input_engine_)
 | 
					                            InputEngine* input_engine_)
 | 
				
			||||||
        : identifier(identifier_), touch_id(touch_id_), button(button_), toggle(toggle_),
 | 
					        : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
 | 
				
			||||||
          inverted(inverted_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
 | 
					          axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
 | 
				
			||||||
          properties_y(properties_y_), input_engine(input_engine_) {
 | 
					          properties_y(properties_y_), input_engine(input_engine_) {
 | 
				
			||||||
        UpdateCallback engine_callback{[this]() { OnChange(); }};
 | 
					        UpdateCallback engine_callback{[this]() { OnChange(); }};
 | 
				
			||||||
        const InputIdentifier button_input_identifier{
 | 
					        const InputIdentifier button_input_identifier{
 | 
				
			||||||
@@ -271,8 +270,7 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Common::Input::TouchStatus GetStatus() const {
 | 
					    Common::Input::TouchStatus GetStatus() const {
 | 
				
			||||||
        Common::Input::TouchStatus status;
 | 
					        Common::Input::TouchStatus status{};
 | 
				
			||||||
        status.id = touch_id;
 | 
					 | 
				
			||||||
        status.pressed = {
 | 
					        status.pressed = {
 | 
				
			||||||
            .value = input_engine->GetButton(identifier, button),
 | 
					            .value = input_engine->GetButton(identifier, button),
 | 
				
			||||||
            .inverted = inverted,
 | 
					            .inverted = inverted,
 | 
				
			||||||
@@ -307,7 +305,6 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    const PadIdentifier identifier;
 | 
					    const PadIdentifier identifier;
 | 
				
			||||||
    const int touch_id;
 | 
					 | 
				
			||||||
    const int button;
 | 
					    const int button;
 | 
				
			||||||
    const bool toggle;
 | 
					    const bool toggle;
 | 
				
			||||||
    const bool inverted;
 | 
					    const bool inverted;
 | 
				
			||||||
@@ -919,7 +916,6 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
 | 
					std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
 | 
				
			||||||
    const Common::ParamPackage& params) {
 | 
					    const Common::ParamPackage& params) {
 | 
				
			||||||
    const auto touch_id = params.Get("touch_id", 0);
 | 
					 | 
				
			||||||
    const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
 | 
					    const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
 | 
				
			||||||
    const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
 | 
					    const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
 | 
				
			||||||
    const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
 | 
					    const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
 | 
				
			||||||
@@ -954,8 +950,8 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
 | 
				
			|||||||
    input_engine->PreSetAxis(identifier, axis_x);
 | 
					    input_engine->PreSetAxis(identifier, axis_x);
 | 
				
			||||||
    input_engine->PreSetAxis(identifier, axis_y);
 | 
					    input_engine->PreSetAxis(identifier, axis_y);
 | 
				
			||||||
    input_engine->PreSetButton(identifier, button);
 | 
					    input_engine->PreSetButton(identifier, button);
 | 
				
			||||||
    return std::make_unique<InputFromTouch>(identifier, touch_id, button, toggle, inverted, axis_x,
 | 
					    return std::make_unique<InputFromTouch>(identifier, button, toggle, inverted, axis_x, axis_y,
 | 
				
			||||||
                                            axis_y, properties_x, properties_y, input_engine.get());
 | 
					                                            properties_x, properties_y, input_engine.get());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
 | 
					std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user