diff options
author | german77 <juangerman-13@hotmail.com> | 2021-09-20 22:02:01 +0200 |
---|---|---|
committer | Narr the Reg <juangerman-13@hotmail.com> | 2021-11-25 03:30:22 +0100 |
commit | bf71d18af99368d7658c9519086c40e73c6abfdd (patch) | |
tree | 1040c7d8554106215b6da4637f75aabc0154d9c7 /src/core/hid | |
parent | common: Rewrite and move core/frontend/input.h to common (diff) | |
download | yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.tar yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.tar.gz yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.tar.bz2 yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.tar.lz yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.tar.xz yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.tar.zst yuzu-bf71d18af99368d7658c9519086c40e73c6abfdd.zip |
Diffstat (limited to 'src/core/hid')
-rw-r--r-- | src/core/hid/input_interpreter.cpp | 62 | ||||
-rw-r--r-- | src/core/hid/input_interpreter.h | 144 |
2 files changed, 206 insertions, 0 deletions
diff --git a/src/core/hid/input_interpreter.cpp b/src/core/hid/input_interpreter.cpp new file mode 100644 index 000000000..c33d8a11a --- /dev/null +++ b/src/core/hid/input_interpreter.cpp @@ -0,0 +1,62 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/core.h" +#include "core/hid/input_interpreter.h" +#include "core/hle/service/hid/controllers/npad.h" +#include "core/hle/service/hid/hid.h" +#include "core/hle/service/sm/sm.h" + +InputInterpreter::InputInterpreter(Core::System& system) + : npad{system.ServiceManager() + .GetService<Service::HID::Hid>("hid") + ->GetAppletResource() + ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} { + ResetButtonStates(); +} + +InputInterpreter::~InputInterpreter() = default; + +void InputInterpreter::PollInput() { + const u32 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] = 0xFFFFFFFF; + + for (std::size_t i = 1; i < button_states.size(); ++i) { + button_states[i] = 0; + } +} + +bool InputInterpreter::IsButtonPressed(HIDButton button) const { + return (button_states[current_index] & (1U << static_cast<u8>(button))) != 0; +} + +bool InputInterpreter::IsButtonPressedOnce(HIDButton button) const { + const bool current_press = + (button_states[current_index] & (1U << static_cast<u8>(button))) != 0; + const bool previous_press = + (button_states[previous_index] & (1U << static_cast<u8>(button))) != 0; + + return current_press && !previous_press; +} + +bool InputInterpreter::IsButtonHeld(HIDButton button) const { + u32 held_buttons{button_states[0]}; + + for (std::size_t i = 1; i < button_states.size(); ++i) { + held_buttons &= button_states[i]; + } + + return (held_buttons & (1U << static_cast<u8>(button))) != 0; +} diff --git a/src/core/hid/input_interpreter.h b/src/core/hid/input_interpreter.h new file mode 100644 index 000000000..9495e3daf --- /dev/null +++ b/src/core/hid/input_interpreter.h @@ -0,0 +1,144 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> + +#include "common/common_types.h" + +namespace Core { +class System; +} + +namespace Service::HID { +class Controller_NPad; +} + +enum class HIDButton : u8 { + A, + B, + X, + Y, + LStick, + RStick, + L, + R, + ZL, + ZR, + Plus, + Minus, + + DLeft, + DUp, + DRight, + DDown, + + LStickLeft, + LStickUp, + LStickRight, + LStickDown, + + RStickLeft, + RStickUp, + RStickRight, + RStickDown, + + LeftSL, + LeftSR, + + RightSL, + RightSR, +}; + +/** + * 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(HIDButton 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 <HIDButton... 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(HIDButton 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 <HIDButton... 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(HIDButton 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 <HIDButton... T> + [[nodiscard]] bool IsAnyButtonHeld() const { + return (IsButtonHeld(T) || ...); + } + +private: + Service::HID::Controller_NPad& npad; + + /// Stores 9 consecutive button states polled from HID. + std::array<u32, 9> button_states{}; + + std::size_t previous_index{}; + std::size_t current_index{}; +}; |