Browse Source

use glfw gamepad mappings for input, multiple inputs per button

Kajetan Johannes Hammerle 3 years ago
parent
commit
33bc6183af
6 changed files with 99 additions and 87 deletions
  1. 2 2
      Game.cpp
  2. 1 1
      Main.cpp
  3. 21 15
      input/Button.cpp
  4. 7 5
      input/Button.h
  5. 58 59
      input/Controller.cpp
  6. 10 5
      input/Controller.h

+ 2 - 2
Game.cpp

@@ -73,11 +73,11 @@ void Game::render(float lag, Renderer& renderer) const {
     renderer.setStringSize(2);
     y = renderer.drawString(0.0f, y, s);
     for(int i = 0; i < controller.getButtonAmount(); i++) {
-        s.clear().append(controller.getName(i)).append(": ").append(controller.getDownTime(i)).append(" ").append(controller.getUpTime(i));
+        s.clear().append(controller.getName(i)).append(": ").append(controller.getDownTime(i)).append(" ").append(controller.wasReleased(i));
         y = renderer.drawString(0.0f, y, s);
     }
 }
 
 bool Game::isRunning() const {
-    return !controller.isDown(Controller::SELECT);
+    return true;//!controller.isDown(Controller::SELECT);
 }

+ 1 - 1
Main.cpp

@@ -87,7 +87,7 @@ int main(int argAmount, char* const* args) {
         view.scale(2.0f / size.width, -2.0f / size.height);
         shader.setMatrix("view", view.getValues());
 
-        game.render((float) lag / nanosPerTick, renderer);
+        game.render(static_cast<float> (lag) / nanosPerTick, renderer);
         window.swapBuffers();
 
         glfwPollEvents();

+ 21 - 15
input/Button.cpp

@@ -1,21 +1,31 @@
 #include "input/Button.h"
 
-Button::Button() : downTime(0), upTime(1) {
+Button::Button() : keyDown(false), buttonDown(false), released(false), downTime(0) {
 }
 
-void Button::press() {
-    downTime = 1;
-    upTime = 0;
+void Button::pressKey() {
+    keyDown = true;
 }
 
-void Button::release() {
-    downTime = 0;
-    upTime = 1;
+void Button::releaseKey() {
+    keyDown = false;
+}
+
+void Button::pressButton() {
+    buttonDown = true;
 }
 
 void Button::tick() {
-    downTime += isDown();
-    upTime += isUp();
+    if(released) {
+        downTime = 0;
+    }
+    released = false;
+    if(keyDown || buttonDown) {
+        downTime++;
+    } else {
+        released = downTime > 0;
+    }
+    buttonDown = false;
 }
 
 bool Button::isDown() const {
@@ -26,10 +36,6 @@ int Button::getDownTime() const {
     return downTime;
 }
 
-bool Button::isUp() const {
-    return upTime > 0;
-}
-
-int Button::getUpTime() const {
-    return upTime;
+bool Button::wasReleased() const {
+    return released;
 }

+ 7 - 5
input/Button.h

@@ -2,18 +2,20 @@
 #define BUTTON_H
 
 class Button final {
+    bool keyDown;
+    bool buttonDown;
+    bool released;
     int downTime;
-    int upTime;
     
 public:
     Button();
-    void press();
-    void release();
+    void pressKey();
+    void releaseKey();
+    void pressButton();
     void tick();
     bool isDown() const;
     int getDownTime() const;
-    bool isUp() const;
-    int getUpTime() const;
+    bool wasReleased() const;
 };
 
 #endif

+ 58 - 59
input/Controller.cpp

@@ -2,10 +2,31 @@
 
 #include "input/Controller.h"
 
-Controller::Axis::Axis() : positive(0), negative(0) {
-}
-
-Controller::Controller() : keyToButton(0), gamepadToButton(0)/*activeController(GLFW_JOYSTICK_1)*/ {
+Controller::Axis::Axis() : positive(0), negative(0), split(0.5f) {
+}
+
+Controller::Controller() : keyToButton(0), gamepadToButton(0), activeController(-1) {
+    mapGamepad(GLFW_GAMEPAD_BUTTON_A, Controller::A);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_B, Controller::B);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_X, Controller::X);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_Y, Controller::Y);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, Controller::L);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, Controller::R);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_BACK, Controller::SELECT);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_START, Controller::START);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_GUIDE, Controller::UNKNOWN);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_LEFT_THUMB, Controller::SELECT);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, Controller::START);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_UP, Controller::UP);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, Controller::RIGHT);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_DOWN, Controller::DOWN);
+    mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_LEFT, Controller::LEFT);
+    mapAxis(GLFW_GAMEPAD_AXIS_LEFT_X, Controller::RIGHT, Controller::LEFT);
+    mapAxis(GLFW_GAMEPAD_AXIS_LEFT_Y, Controller::DOWN, Controller::UP);
+    mapAxis(GLFW_GAMEPAD_AXIS_RIGHT_X, Controller::RIGHT, Controller::LEFT);
+    mapAxis(GLFW_GAMEPAD_AXIS_RIGHT_Y, Controller::DOWN, Controller::UP);
+    mapAxis(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, Controller::L, Controller::UNKNOWN, -0.9f);
+    mapAxis(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, Controller::R, Controller::UNKNOWN, -0.9f);
 }
 
 bool Controller::mapKey(int key, int button) {
@@ -32,7 +53,7 @@ bool Controller::mapGamepad(int gamepad, int button) {
     return false;
 }
 
-bool Controller::mapAxis(int axis, int positiveButton, int negativeButton) {
+bool Controller::mapAxis(int axis, int positiveButton, int negativeButton, float split) {
     if(axis < 0 || axis >= axisToButton.getLength()) {
         return true;
     }
@@ -46,6 +67,7 @@ bool Controller::mapAxis(int axis, int positiveButton, int negativeButton) {
     }
     axisToButton[axis].positive = positiveButton;
     axisToButton[axis].negative = negativeButton;
+    axisToButton[axis].split = split;
     return false;
 }
 
@@ -53,78 +75,59 @@ void Controller::press(int key) {
     if(key < 0 || key >= keyToButton.getLength()) {
         return;
     }
-    buttons[keyToButton[key]].press();
+    buttons[keyToButton[key]].pressKey();
 }
 
 void Controller::release(int key) {
     if(key < 0 || key >= keyToButton.getLength()) {
         return;
     }
-    buttons[keyToButton[key]].release();
+    buttons[keyToButton[key]].releaseKey();
 }
 
 void Controller::tick() {
     for(Button& b : buttons) {
         b.tick();
     }
-    /*if(!glfwJoystickPresent(activeController) && findController()) {
-        std::cout << "cannot find any controller - resetting buttons\n";
-        reset();
-        return;
-    }
-    int buttonCount = 0;
-    const u8* buttonMap = glfwGetJoystickButtons(activeController, &buttonCount);
-    int axisCount = 0;
-    const float* axisMap = glfwGetJoystickAxes(activeController, &axisCount);
-    if(buttonCount < 10 || axisCount < 2) {
-        std::cout << "cannot find any supported controller - resetting buttons\n";
-        std::cout << "buttons found: " << buttonCount << "\n";
-        std::cout << "axes found: " << axisCount << "\n";
-        reset();
-        return;
+    if(searchForGamepad()) {
+        checkGamepad();
     }
-    increment(Button::A, buttonMap, 1);
-    increment(Button::B, buttonMap, 2);
-    increment(Button::X, buttonMap, 0);
-    increment(Button::Y, buttonMap, 3);
-    increment(Button::L, buttonMap, 4);
-    increment(Button::R, buttonMap, 5);
-    increment(Button::SELECT, buttonMap, 8);
-    increment(Button::START, buttonMap, 9);
-    increment(Button::LEFT, axisMap[0] < -0.5f);
-    increment(Button::RIGHT, axisMap[0] > 0.5f);
-    increment(Button::UP, axisMap[1] < -0.5f);
-    increment(Button::DOWN, axisMap[1] > 0.5f);*/
 }
 
-/*bool Controller::findController() {
-    for(uint i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {
-        if(glfwJoystickPresent(i)) {
+bool Controller::searchForGamepad() {
+    if(activeController != -1) {
+        return true;
+    }
+    for(int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {
+        if(glfwJoystickIsGamepad(i)) {
             activeController = i;
-            return false;
+            return true;
         }
     }
-    return true;
+    return false;
 }
 
-void Controller::reset() {
-    for(ButtonState& b : buttons) {
-        b.downTime = 0;
+void Controller::checkGamepad() {
+    GLFWgamepadstate state;
+    if(!glfwGetGamepadState(activeController, &state)) {
+        return;
+    }
+    for(int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) {
+        if(state.buttons[i]) {
+            buttons[gamepadToButton[i]].pressButton();
+        }
+    }
+    for(int i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++) {
+        if(state.axes[i] > axisToButton[i].split) {
+            buttons[axisToButton[i].positive].pressButton();
+        } else if(state.axes[i] < -axisToButton[i].split) {
+            buttons[axisToButton[i].negative].pressButton();
+        }
     }
 }
 
-void Controller::increment(uint button, const u8* mapping, uint index) {
-    increment(button, mapping[index] != GLFW_RELEASE);
-}
-
-void Controller::increment(uint button, bool notReleased) {
-    buttons[button].justReleased = (buttons[button].downTime > 0 && !notReleased && !buttons[button].justReleased);
-    bool b = notReleased || buttons[button].justReleased;
-    buttons[button].downTime = buttons[button].downTime * b + b;
-}*/
-
 int Controller::getButtonAmount() const {
-    return buttons.getLength();
+    return buttons.getLength() - 1;
 }
 
 const char* Controller::getName(int button) const {
@@ -142,12 +145,8 @@ int Controller::getDownTime(int button) const {
     return buttons[(button + 1) & getRangeMask(button + 1)].getDownTime();
 }
 
-bool Controller::isUp(int button) const {
-    return buttons[(button + 1) & getRangeMask(button + 1)].isUp();
-}
-
-int Controller::getUpTime(int button) const {
-    return buttons[(button + 1) & getRangeMask(button + 1)].getUpTime();
+bool Controller::wasReleased(int button) const {
+    return buttons[(button + 1) & getRangeMask(button + 1)].wasReleased();
 }
 
 int Controller::getRangeMask(int button) const {

+ 10 - 5
input/Controller.h

@@ -11,16 +11,20 @@ class Controller final {
     static constexpr int BUTTON_AMOUNT = 13;
     Array<Button, BUTTON_AMOUNT> buttons;
     Array<int, 1 + GLFW_KEY_LAST> keyToButton;
-    Array<int, 1 + GLFW_JOYSTICK_LAST> gamepadToButton;
+    Array<int, 1 + GLFW_GAMEPAD_BUTTON_LAST> gamepadToButton;
 
     struct Axis {
         int positive;
         int negative;
+        float split;
         Axis();
     };
     Array<Axis, 1 + GLFW_GAMEPAD_AXIS_LAST> axisToButton;
 
+    int activeController;
+
 public:
+    static constexpr int UNKNOWN = -1;
     static constexpr int A = 0;
     static constexpr int B = 1;
     static constexpr int X = 2;
@@ -36,8 +40,6 @@ public:
 
     Controller();
     bool mapKey(int key, int button);
-    bool mapGamepad(int gamepad, int button);
-    bool mapAxis(int axis, int positiveButton, int negativeButton);
 
     void press(int key);
     void release(int key);
@@ -47,11 +49,14 @@ public:
     const char* getName(int button) const;
     bool isDown(int button) const;
     int getDownTime(int button) const;
-    bool isUp(int button) const;
-    int getUpTime(int button) const;
+    bool wasReleased(int button) const;
 
 private:
     int getRangeMask(int button) const;
+    bool searchForGamepad();
+    void checkGamepad();
+    bool mapGamepad(int gamepad, int button);
+    bool mapAxis(int axis, int positiveButton, int negativeButton, float split = 0.5f);
 };
 
 #endif