Browse Source

button handler and registry for keyboard and gamepads

Kajetan Johannes Hammerle 3 years ago
parent
commit
b071869bd3
5 changed files with 189 additions and 1 deletions
  1. 31 0
      input/Button.cpp
  2. 24 0
      input/Button.h
  3. 83 0
      input/Buttons.cpp
  4. 48 0
      input/Buttons.h
  5. 3 1
      meson.build

+ 31 - 0
input/Button.cpp

@@ -0,0 +1,31 @@
+#include "input/Button.h"
+
+Button::Button(int key, const char* name) : key(key), downTime(0), released(false), name(name) {
+}
+
+void Button::tick(bool down) {
+    if(down) {
+        downTime++;
+    } else if(released) {
+        released = false;
+        downTime = 0;
+    } else if(!released && downTime > 0) {
+        released = true;
+    }
+}
+
+bool Button::isDown() const {
+    return downTime > 0;
+}
+
+int Button::getDownTime() const {
+    return downTime;
+}
+
+bool Button::wasReleased() const {
+    return released;
+}
+
+const char* Button::getName() const {
+    return name;
+}

+ 24 - 0
input/Button.h

@@ -0,0 +1,24 @@
+#ifndef BUTTON_H
+#define BUTTON_H
+
+class Button final {
+    friend class Buttons;
+    
+    int key;
+    int downTime;
+    bool released;
+    const char* name;
+    
+public:
+    Button(int key, const char* name);
+    
+    bool isDown() const;
+    int getDownTime() const;
+    bool wasReleased() const;
+    const char* getName() const;
+    
+private:
+    void tick(bool down);
+};
+
+#endif

+ 83 - 0
input/Buttons.cpp

@@ -0,0 +1,83 @@
+#include "input/Buttons.h"
+
+Buttons::Axis::Axis() : less(0.0f), greater(0.0f), lessIndex(-1), greaterIndex(-1) {
+}
+
+Buttons::Buttons(const Window& window) : window(window), dummy(0, "Dummy"), activeController(-1), gamepadToButton(-1) {
+}
+
+Button& Buttons::add(int key, const char* name) {
+    if(buttons.add(key, name)) {
+        return dummy;
+    }
+    return buttons[buttons.getLength() - 1];
+}
+
+void Buttons::mapGamepadButton(const Button& button, int mapping) {
+    gamepadToButton[mapping] = searchButton(button);
+}
+
+void Buttons::mapGamepadAxis(const Button& button, float value, int index) {
+    if(value > 0.0f) {
+        gamepadAxisToButton[index].greater = value;
+        gamepadAxisToButton[index].greaterIndex = searchButton(button);
+    } else {
+        gamepadAxisToButton[index].less = value;
+        gamepadAxisToButton[index].lessIndex = searchButton(button);
+    }
+}
+
+void Buttons::tick() {
+    DownArray down(false);
+    if(searchForGamepad()) {
+        checkGamepad(down);
+    }
+    for(int i = 0; i < buttons.getLength(); i++) {
+        buttons[i].tick(window.isKeyDown(buttons[i].key) || down[i]);
+    }
+}
+
+const ButtonList& Buttons::get() const {
+    return buttons;
+}
+
+bool Buttons::searchForGamepad() {
+    if(activeController != -1) {
+        return true;
+    }
+    for(int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {
+        if(glfwJoystickIsGamepad(i)) {
+            activeController = i;
+            return true;
+        }
+    }
+    return false;
+}
+
+void Buttons::checkGamepad(DownArray& down) {
+    GLFWgamepadstate state;
+    if(!glfwGetGamepadState(activeController, &state)) {
+        return;
+    }
+    for(int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) {
+        if(gamepadToButton[i] != -1 && state.buttons[i]) {
+            down[gamepadToButton[i]] = true;
+        }
+    }
+    for(int i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++) {
+        if(gamepadAxisToButton[i].greaterIndex != -1 && state.axes[i] > gamepadAxisToButton[i].greater) {
+            down[gamepadAxisToButton[i].greaterIndex] = true;
+        } else if(gamepadAxisToButton[i].lessIndex != -1 && state.axes[i] < gamepadAxisToButton[i].less) {
+            down[gamepadAxisToButton[i].lessIndex] = true;
+        }
+    }
+}
+
+int Buttons::searchButton(const Button& button) const {
+    for(int i = 0; i < buttons.getLength(); i++) {
+        if(&button == &(buttons[i])) {
+            return i;
+        }
+    }
+    return -1;
+}

+ 48 - 0
input/Buttons.h

@@ -0,0 +1,48 @@
+#ifndef BUTTONS_H
+#define BUTTONS_H
+
+#include "wrapper/Window.h"
+#include "input/Button.h"
+#include "utils/List.h"
+#include "utils/Array.h"
+
+typedef List<Button, 32> ButtonList;
+
+class Buttons final {
+    typedef Array<bool, 32 > DownArray;
+
+    const Window& window;
+    Button dummy;
+    int activeController;
+    ButtonList buttons;
+
+    struct Axis {
+        float less;
+        float greater;
+        int lessIndex;
+        int greaterIndex;
+
+        Axis();
+    };
+
+    Array<int, 1 + GLFW_GAMEPAD_BUTTON_LAST> gamepadToButton;
+    Array<Axis, 1 + GLFW_GAMEPAD_AXIS_LAST> gamepadAxisToButton;
+
+public:
+    Buttons(const Window& window);
+
+    Button& add(int key, const char* name);
+    void mapGamepadButton(const Button& button, int mapping);
+    void mapGamepadAxis(const Button& button, float value, int index);
+    
+    void tick();
+    
+    const ButtonList& get() const;
+
+private:
+    bool searchForGamepad();
+    void checkGamepad(DownArray& down);
+    int searchButton(const Button& button) const;
+};
+
+#endif

+ 3 - 1
meson.build

@@ -39,7 +39,9 @@ sources = ['Main.cpp',
     'wrapper/VertexBuffer.cpp',
     'wrapper/Attributes.cpp',
     'wrapper/Window.cpp',
-    'wrapper/WindowOptions.cpp']
+    'wrapper/WindowOptions.cpp',
+    'input/Button.cpp',
+    'input/Buttons.cpp']
 
 glewDep = dependency('glew')
 glfwDep = dependency('glfw3')