From f9653a4417665c208d96b4ee19394ace963adc66 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Wed, 25 Nov 2020 07:01:22 -0500
Subject: 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>
---
 src/core/frontend/input_interpreter.cpp | 45 +++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 src/core/frontend/input_interpreter.cpp

(limited to 'src/core/frontend/input_interpreter.cpp')

diff --git a/src/core/frontend/input_interpreter.cpp b/src/core/frontend/input_interpreter.cpp
new file mode 100644
index 0000000000..66ae506cd3
--- /dev/null
+++ b/src/core/frontend/input_interpreter.cpp
@@ -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;
+}
-- 
cgit v1.2.3-70-g09d2