Browse Source

controller support

Kajetan Johannes Hammerle 3 years ago
parent
commit
e10ae5d7b3
6 changed files with 135 additions and 94 deletions
  1. 6 14
      Game.cpp
  2. 3 27
      Main.cpp
  3. 69 53
      input/Controller.cpp
  4. 27 0
      input/Controller.h
  5. 26 0
      utils/String.cpp
  6. 4 0
      utils/String.h

+ 6 - 14
Game.cpp

@@ -6,25 +6,17 @@
 Game::Game(const Controller& c, const Clock& fps, const Clock& tps) : controller(c), fps(fps), tps(tps) {
 }
 
-float w = 0;
-
 void Game::tick() {
-    w += 5;
 }
 
 void Game::render(float lag, Renderer& renderer) const {
-    renderer.translateTo(0.0f, 0.0f).scale(2.0f).translate(100.0f, 240.0f).rotate(w + 5 * lag).translate(-100.0f, -240.0f).update();
-    u64 time = GLFWWrapper::getTimeNanos();
-    for(uint i = 0; i < 60; i++) {
-        renderer.drawString(0, i * 10, "Das is&037t ein Test. Das is&077t ein Test. Das is&737t ein Test.");
-    }
-    time = GLFWWrapper::getTimeNanos() - time;
-    
-    renderer.translateTo(0.0f, 0.0f).scale(2.0f).update();
-    String s;
-    s.append((int) time).append("  ").append(fps.getUpdatesPerSecond());
-    renderer.drawString(100, 10, s);
     (void) lag;
+    renderer.translateTo(0.0f, 0.0f).scale(4.0f).update();
+    for(uint i = 0; i < controller.getButtonAmount(); i++) {
+        String s(controller.getName(i));
+        s.append(": ").append(controller.wasReleased(i)).append(" ").append(controller.getDownTime(i));
+        renderer.drawString(0, 10 * i, s);
+    }
 }
 
 bool Game::isRunning() const {

+ 3 - 27
Main.cpp

@@ -20,22 +20,13 @@ bool initGLEW() {
     return false;
 }
 
-void initCallbacks(Window& w, WindowSize& size, Controller& controller) {
+void initCallbacks(Window& w, WindowSize& size) {
     static WindowSize& cSize = size;
-    static Controller& cController = controller;
-    (void) cController;
     w.setFramebufferSizeCallback([](GLFWwindow*, int newWidth, int newHeight) {
         glViewport(0, 0, newWidth, newHeight);
         cSize.width = newWidth;
         cSize.height = newHeight;
     });
-    /*w.setKeyCallback([](GLFWwindow*, int key, int, int action, int) {
-        if(action == GLFW_PRESS) {
-            cControl.keys.press(key);
-        } else if(action == GLFW_RELEASE) {
-            cControl.keys.release(key);
-        }
-    });*/
 }
 
 int main() {
@@ -62,10 +53,10 @@ int main() {
     
     static Game game(controller, fps, tps);
     
-    initCallbacks(window, size, controller);
+    initCallbacks(window, size);
     window.show();
     
-    const u64 nanosPerTick = 50000000;
+    const u64 nanosPerTick = 10'000'000;
     u64 lag = 0;
     while(!window.shouldClose() && game.isRunning()) {
         GLWrapper::checkAndPrintError("GL-Error");
@@ -88,20 +79,5 @@ int main() {
         
         glfwPollEvents();
     }
-    
-    /*for(int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {
-        String s("Joystick ");
-        int present = glfwJoystickPresent(i);
-        s.append(i).append(": ").append(present);
-        if(present) {
-            s.append("  ");
-            int count = 0;
-            const u8* buttons = glfwGetJoystickButtons(i, &count);
-            for(int k = 0; k < count; k++) {
-                s.append(buttons[k] ? '1' : '0');
-            }
-        }
-        r.drawString(0, i * 10 + 10, s);
-    }*/
     return 0;
 }

+ 69 - 53
input/Controller.cpp

@@ -1,75 +1,91 @@
+#include <GL/glew.h>
+#include <GLFW/glfw3.h>
+#include <iostream>
+
 #include "input/Controller.h"
 
-void Controller::tick() {
+Controller::ButtonState::ButtonState() : downTime(0), justReleased(false) {
 }
 
-/*#include <GLFW/glfw3.h>
+Controller::Controller() : activeController(GLFW_JOYSTICK_1) {
+}
 
-#include "client/input/Keys.h"
+void Controller::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;
+    }
+    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);
+}
 
-Keys::Key::Key() : down(false), shouldRelease(false), downTime(0) {
+bool Controller::findController() {
+    for(uint i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {
+        if(glfwJoystickPresent(i)) {
+            activeController = i;
+            return false;
+        }
+    }
+    return true;
 }
 
-bool Keys::Key::isDown() const {
-    return down;
+void Controller::reset() {
+    for(ButtonState& b : buttons) {
+        b.downTime = 0;
+    }
 }
 
-bool Keys::Key::isReleased() const {
-    return shouldRelease;
+void Controller::increment(uint button, const u8* mapping, uint index) {
+    increment(button, mapping[index] != GLFW_RELEASE);
 }
 
-u32 Keys::Key::getDownTime() const {
-    return downTime;
+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;
 }
 
-std::ostream& operator<<(std::ostream& os, const Keys::Key& k) {
-    os << "Key(down: " << k.isDown() << ", release: " << k.isReleased() <<
-            ", time: " << k.getDownTime() << ")";
-    return os;
+uint Controller::getButtonAmount() const {
+    return buttons.getLength();
 }
 
-Keys::Keys() : left(keys[0]), right(keys[1]), up(keys[2]), down(keys[3]), jump(keys[4]), sneak(keys[5]),
-camLeft(keys[6]), camRight(keys[7]), camUp(keys[8]), camDown(keys[9]), test(keys[10]), test2(keys[11]), test3(keys[12]),
-test4(keys[13]), test5(keys[14]) {
-    keys[0].glfwKey = GLFW_KEY_A;
-    keys[1].glfwKey = GLFW_KEY_D;
-    keys[2].glfwKey = GLFW_KEY_W;
-    keys[3].glfwKey = GLFW_KEY_S;
-    keys[4].glfwKey = GLFW_KEY_SPACE;
-    keys[5].glfwKey = GLFW_KEY_LEFT_SHIFT;
-    keys[6].glfwKey = GLFW_KEY_LEFT;
-    keys[7].glfwKey = GLFW_KEY_RIGHT;
-    keys[8].glfwKey = GLFW_KEY_UP;
-    keys[9].glfwKey = GLFW_KEY_DOWN;
-    keys[10].glfwKey = GLFW_KEY_T;
-    keys[11].glfwKey = GLFW_KEY_Y;
-    keys[12].glfwKey = GLFW_KEY_U;
-    keys[13].glfwKey = GLFW_KEY_I;
-    keys[14].glfwKey = GLFW_KEY_R;
+const char* Controller::getName(uint button) const {
+    static constexpr const char* buttonNames[] = {
+        "A", "B", "X", "Y", "L", "R", "Select", "Start", "Left", "Right", "Up", "Down"
+    };
+    return buttonNames[button];
 }
 
-void Keys::release(int key) {
-    for(Key& k : keys) {
-        if(k.glfwKey == key) {
-            k.shouldRelease = true;
-        }
-    }
+uint Controller::getDownTime(uint button) const {
+    return buttons[button].downTime;
 }
 
-void Keys::press(int key) {
-    for(Key& k : keys) {
-        if(k.glfwKey == key) {
-            k.down = true;
-            k.shouldRelease = false;
-        }
-    }
+bool Controller::isDown(uint button) const {
+    return buttons[button].downTime > 0;
 }
 
-void Keys::tick() {
-    for(Key& k : keys) {
-        k.downTime += k.down;
-        k.down = k.down && !k.shouldRelease;
-        k.downTime *= !k.shouldRelease;
-        k.shouldRelease = false;
-    }
-}*/
+bool Controller::wasReleased(uint button) const {
+    return buttons[button].justReleased;
+}

+ 27 - 0
input/Controller.h

@@ -1,8 +1,35 @@
 #ifndef CONTROLLER_H
 #define CONTROLLER_H
 
+#include "utils/Array.h"
+
+enum Button {
+    A, B, X, Y, L, R, SELECT, START, LEFT, RIGHT, UP, DOWN
+};
+
 struct Controller final {
+    Controller();
     void tick();
+    uint getButtonAmount() const;
+    const char* getName(uint button) const;
+    uint getDownTime(uint button) const;
+    bool isDown(uint button) const;
+    bool wasReleased(uint button) const;
+
+private:
+    bool findController();
+    void reset();
+    void increment(uint button, const u8* mapping, uint index);
+    void increment(uint button, bool notReleased);
+
+    struct ButtonState final {
+        ButtonState();
+        uint downTime;
+        bool justReleased;
+    };
+    
+    Array<ButtonState, 12> buttons;
+    uint activeController;
 };
 
 #endif

+ 26 - 0
utils/String.cpp

@@ -50,6 +50,28 @@ String& String::append(const char* str) {
     return *this;
 }
 
+String& String::appendFormat(const char* format, void* value) {
+    uint left = MAX_LENGTH - length;
+    uint written = snprintf(data + length, left, format, value);
+    if(written < left) {
+        length += written;
+    } else {
+        length = MAX_LENGTH;
+    }
+    return *this;
+}
+
+String& String::append(uint i) {
+    uint left = MAX_LENGTH - length;
+    uint written = snprintf(data + length, left, "%u", i);
+    if(written < left) {
+        length += written;
+    } else {
+        length = MAX_LENGTH;
+    }
+    return *this;
+}
+
 String& String::append(int i) {
     uint left = MAX_LENGTH - length;
     uint written = snprintf(data + length, left, "%d", i);
@@ -70,4 +92,8 @@ String& String::append(float f) {
         length = MAX_LENGTH;
     }
     return *this;
+}
+
+String& String::append(bool b) {
+    return append(b ? "true" : "false");
 }

+ 4 - 0
utils/String.h

@@ -16,10 +16,14 @@ public:
     
     String& append(char c);
     String& append(const char* str);
+    String& append(uint i);
     String& append(int i);
     String& append(float f);
+    String& append(bool b);
 
 private:
+    String& appendFormat(const char* format, void* value);
+    
     static constexpr uint MAX_LENGTH = 255;
     char data[MAX_LENGTH];
     u8 length;