Browse Source
frontend/input_interpreter: Add InputInterpreter API
frontend/input_interpreter: Add InputInterpreter API
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. Co-authored-by: Chloe <25727384+ogniK5377@users.noreply.github.com>nce_cpp
3 changed files with 167 additions and 0 deletions
-
2src/core/CMakeLists.txt
-
45src/core/frontend/input_interpreter.cpp
-
120src/core/frontend/input_interpreter.h
@ -0,0 +1,45 @@ |
|||
// 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/frontend/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)} {} |
|||
|
|||
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; |
|||
} |
|||
|
|||
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; |
|||
} |
|||
@ -0,0 +1,120 @@ |
|||
// 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(); |
|||
|
|||
/** |
|||
* 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 HIDButton The buttons to check. |
|||
* |
|||
* @returns True when at least one of the buttons is pressed once. |
|||
*/ |
|||
template <HIDButton... T> |
|||
[[nodiscard]] bool IsAnyButtonPressedOnce() { |
|||
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 HIDButton The buttons to check. |
|||
* |
|||
* @returns True when at least one of the buttons is held down. |
|||
*/ |
|||
template <HIDButton... T> |
|||
[[nodiscard]] bool IsAnyButtonHeld() { |
|||
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{}; |
|||
}; |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue