Kajetan Johannes Hammerle 11 місяців тому
батько
коміт
6f323ed04f
2 змінених файлів з 174 додано та 168 видалено
  1. 20 21
      include/core/Window.h
  2. 154 147
      src/Window.c

+ 20 - 21
include/core/Window.h

@@ -50,26 +50,25 @@ float coreWindowFramesPerSecond(void);
 //     }
 // }
 
-// namespace Controls {
-//     typedef StringBuffer<32> ButtonName;
-//     typedef int ButtonId;
-//
-//     ButtonId add(const ButtonName& name);
-//     void bindKey(ButtonId id, int key);
-//     void bindGamepad(ButtonId id, int gamepadButton);
-//     void bindMouse(ButtonId id, int mouseButton);
-//
-//     Vector2 getLastMousePosition();
-//     Vector2 getMousePosition();
-//     Vector2 getLeftGamepadAxis();
-//     Vector2 getRightGamepadAxis();
-//     float getLeftGamepadTrigger();
-//     float getRightGamepadTrigger();
-//
-//     bool isDown(ButtonId id);
-//     int getDownTime(ButtonId id);
-//     bool wasReleased(ButtonId id);
-//     const ButtonName& getName(ButtonId id);
-// }
+typedef size_t CoreButton;
+
+void coreInitButton(void);
+void coreDestroyButton(void);
+CoreButton coreButtonAdd(const char* name);
+void coreButtonBindKey(CoreButton b, int key);
+void coreButtonBindGamepad(CoreButton b, int gamepadButton);
+void coreButtonBindMouse(CoreButton b, int mouseButton);
+
+CoreVector2 coreButtonLastMousePosition(void);
+CoreVector2 coreButtonMousePosition(void);
+CoreVector2 coreButtonLeftGamepadAxis(void);
+CoreVector2 coreButtonRightGamepadAxis(void);
+float coreButtonLeftGamepadTrigger(void);
+float coreButtonRightGamepadTrigger(void);
+
+bool coreButtonDown(CoreButton b);
+int coreButtonDownTime(CoreButton b);
+bool coreButtonReleased(CoreButton b);
+const char* coreButtonName(CoreButton b);
 
 #endif

+ 154 - 147
src/Window.c

@@ -1,6 +1,7 @@
 #include "core/Window.h"
 
 #include <GLFW/glfw3.h>
+#include <core/HashMap.h>
 #include <core/Logger.h>
 #include <core/Utility.h>
 #include <stdio.h>
@@ -33,81 +34,52 @@ typedef struct {
     i64 values[CLOCK_SIZE];
     size_t index;
 } Clock;
-
 static Clock fps = {0};
 static Clock tps = {0};
 
-/*static List<uint32> input;
-static int inputCursor = 0;
-static int inputLimit = 256;
-static bool inputActive = false;
+// static List<uint32> input;
+// static int inputCursor = 0;
+// static int inputLimit = 256;
+// static bool inputActive = false;
 
-struct Button final {
-    Window::Controls::ButtonName name;
+typedef struct {
+    char name[31];
+    bool released;
     int key;
     int downTime;
     int upEvents;
     int downEvents;
     int controllerUp;
     int controllerDown;
-    bool released;
-
-    Button(const Window::Controls::ButtonName& name_)
-        : name(name_), key(0), downTime(0), upEvents(0), downEvents(0),
-          controllerUp(0), controllerDown(0), released(false) {
-    }
-
-    void tick() {
-        bool down = (downEvents > 0) || (controllerDown > 0);
-        bool up = (upEvents == downEvents) && (controllerUp == controllerDown);
-
-        if(released) {
-            downTime = 0;
-        }
-        downTime += down;
-        released = down && up;
-
-        downEvents -= upEvents;
-        upEvents = 0;
-
-        controllerDown -= controllerUp;
-        controllerUp = 0;
-    }
-};
-static Button fallbackButton{"unknown"};
-static List<Button> buttons;
-static HashMap<int, Window::Controls::ButtonId> keyToButtonId;
-static HashMap<int, Window::Controls::ButtonId> gamepadToButtonId;
-static HashMap<int, Window::Controls::ButtonId> mouseToButtonId;
-static Vector2 lastMousePosition;
-static Vector2 mousePosition;
+} ButtonData;
+#define BUTTONS 100
+static ButtonData buttons[BUTTONS] = {0};
+static size_t buttonIndex = 0;
+static CoreHashMap keyToButtonId = {0};     // int -> CoreButton
+static CoreHashMap gamepadToButtonId = {0}; // int -> CoreButton
+static CoreHashMap mouseToButtonId = {0};   // int -> CoreButton
+static CoreVector2 lastMousePosition = {0};
+static CoreVector2 mousePosition = {0};
 static int activeController = -1;
-static GLFWgamepadstate lastControllerState;
+static GLFWgamepadstate lastControllerState = {0};
 
-Window::Options::Options(int majorVersion_, int minorVersion_,
-                         const IntVector2& size_, bool es_, const char* name_)
-    : majorVersion(majorVersion_), minorVersion(minorVersion_), size(size_),
-      fullscreen(false), es(es_), vsync(true), name(name_) {
-}
-
-static void onButton(HashMap<int, Window::Controls::ButtonId>& map, int key,
-                     int action) {
-    Window::Controls::ButtonId* b = map.search(key);
-    if(b == nullptr) {
+static void onButton(CoreHashMap* map, int key, int action) {
+    CoreButton* bp = coreHashMapSearch(map, int, key, CoreButton);
+    if(bp == nullptr) {
         return;
     }
-    Window::Controls::ButtonId id = *b;
-    if(id < 0 || id >= buttons.getLength()) {
+    CoreButton b = *bp;
+    if(b >= buttonIndex) {
         return;
     }
     if(action == GLFW_RELEASE) {
-        buttons[id].upEvents++;
+        buttons[b].upEvents++;
     } else if(action == GLFW_PRESS) {
-        buttons[id].downEvents++;
+        buttons[b].downEvents++;
     }
 }
 
-static void addError(Error& e) {
+/*static void addError(Error& e) {
     const char* description = nullptr;
     int errorCode = glfwGetError(&description);
     if(errorCode == GLFW_NO_ERROR) {
@@ -132,18 +104,18 @@ static void handleInputKey(int key, int action) {
             inputCursor += inputCursor < input.getLength();
             break;
     }
-}
+}*/
 
 static void onKey(GLFWwindow*, int key, int scancode, int action, int mods) {
     (void)scancode;
     (void)mods;
-    if(inputActive) {
-        handleInputKey(key, action);
-    }
-    onButton(keyToButtonId, key, action);
+    // if(inputActive) {
+    //     handleInputKey(key, action);
+    // }
+    onButton(&keyToButtonId, key, action);
 }
 
-static void addUnicode(uint32 codepoint) {
+/*static void addUnicode(uint32 codepoint) {
     if(input.getLength() >= inputLimit) {
         return;
     }
@@ -158,22 +130,23 @@ static void onChar(GLFWwindow*, uint32 codepoint) {
     if(inputActive) {
         addUnicode(codepoint);
     }
-}
+}*/
 
 static void onResize(GLFWwindow*, int width, int height) {
     sizeChanged = true;
-    size[0] = width;
-    size[1] = height;
+    size.data[0] = width;
+    size.data[1] = height;
 }
 
 static void onMouse(GLFWwindow*, int button, int action, int mods) {
     (void)mods;
-    onButton(mouseToButtonId, button, action);
+    onButton(&mouseToButtonId, button, action);
 }
 
 static void onMouseMove(GLFWwindow*, double x, double y) {
-    mousePosition = Vector<2, double>(x, y).toFloat();
-}*/
+    mousePosition.data[0] = (float)x;
+    mousePosition.data[1] = (float)y;
+}
 
 bool coreWindowOpen(const CoreWindowOptions* o) {
     if(!glfwInit()) {
@@ -196,11 +169,11 @@ bool coreWindowOpen(const CoreWindowOptions* o) {
         return true;
     }
     size = o->size;
-    // glfwSetKeyCallback(window, onKey);
+    glfwSetKeyCallback(window, onKey);
     // glfwSetCharCallback(window, onChar);
-    // glfwSetFramebufferSizeCallback(window, onResize);
-    // glfwSetMouseButtonCallback(window, onMouse);
-    // glfwSetCursorPosCallback(window, onMouseMove);
+    glfwSetFramebufferSizeCallback(window, onResize);
+    glfwSetMouseButtonCallback(window, onMouse);
+    glfwSetCursorPosCallback(window, onMouseMove);
 
     return false;
 }
@@ -275,22 +248,78 @@ static i64 updateClock(Clock* c) {
     return diff;
 }
 
+static bool 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;
+}
+
+static void checkGamepad() {
+    GLFWgamepadstate state;
+    if(!glfwGetGamepadState(activeController, &state)) {
+        activeController = -1;
+        return;
+    }
+    for(int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) {
+        CoreButton* bp =
+            coreHashMapSearch(&gamepadToButtonId, int, i, CoreButton);
+        if(bp == nullptr) {
+            return;
+        }
+        CoreButton b = *bp;
+        if(b >= buttonIndex) {
+            return;
+        }
+        if(!lastControllerState.buttons[i] && state.buttons[i]) {
+            buttons[b].controllerDown++;
+        } else if(lastControllerState.buttons[i] && !state.buttons[i]) {
+            buttons[b].controllerUp++;
+        }
+    }
+    lastControllerState = state;
+}
+
 static void endFrame(void) {
     sizeChanged = false;
     glfwSwapBuffers(window);
     glfwPollEvents();
-    // if(searchForGamepad()) {
-    //     checkGamepad();
-    // }
+    if(searchForGamepad()) {
+        checkGamepad();
+    }
+}
+
+static void tickButton(ButtonData* b) {
+    bool down = (b->downEvents > 0) || (b->controllerDown > 0);
+    bool up = (b->upEvents == b->downEvents) &&
+              (b->controllerUp == b->controllerDown);
+    if(b->released) {
+        b->downTime = 0;
+    }
+    b->downTime += down;
+    b->released = down && up;
+
+    b->downEvents -= b->upEvents;
+    b->upEvents = 0;
+
+    b->controllerDown -= b->controllerUp;
+    b->controllerUp = 0;
 }
 
 static void tick() {
     updateClock(&tps);
-    // for(Button& b : buttons) {
-    //     b.tick();
-    // }
+    ButtonData* b = buttons;
+    for(size_t i = 0; i < buttonIndex; i++) {
+        tickButton(b++);
+    }
     tickHandler(tickHandlerData);
-    // lastMousePosition = mousePosition;
+    lastMousePosition = mousePosition;
 }
 
 void coreWindowRun(void) {
@@ -317,42 +346,7 @@ float coreWindowFramesPerSecond(void) {
     return (1000000000.0f * CLOCK_SIZE) / (float)fps.sum;
 }
 
-/*static bool 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;
-}
-
-static void checkGamepad() {
-    GLFWgamepadstate state;
-    if(!glfwGetGamepadState(activeController, &state)) {
-        activeController = -1;
-        return;
-    }
-    for(int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) {
-        Window::Controls::ButtonId* idp = gamepadToButtonId.search(i);
-        if(idp == nullptr) {
-            continue;
-        }
-        Window::Controls::ButtonId id = *idp;
-        if(id < 0 || id >= buttons.getLength()) {
-            continue;
-        }
-        if(!lastControllerState.buttons[i] && state.buttons[i]) {
-            buttons[id].controllerDown++;
-        } else if(lastControllerState.buttons[i] && !state.buttons[i]) {
-            buttons[id].controllerUp++;
-        }
-    }
-    lastControllerState = state;
-}
+/*
 
 void Window::Input::setLimit(int l) {
     inputLimit = l;
@@ -428,72 +422,85 @@ void Window::Input::setCursor(int index) {
 
 const List<uint32>& Window::Input::getUnicode() {
     return input;
+}*/
+
+void coreInitButton(void) {
+    coreButtonAdd("unknown");
+    coreInitHashMap(&keyToButtonId, sizeof(int), sizeof(CoreButton));
+    coreInitHashMap(&gamepadToButtonId, sizeof(int), sizeof(CoreButton));
+    coreInitHashMap(&mouseToButtonId, sizeof(int), sizeof(CoreButton));
 }
 
-Window::Controls::ButtonId Window::Controls::add(const ButtonName& name) {
-    ButtonId id = buttons.getLength();
-    buttons.add(name);
-    return id;
+void coreDestroyButton(void) {
+    buttonIndex = 0;
+    coreDestroyHashMap(&keyToButtonId);
+    coreDestroyHashMap(&gamepadToButtonId);
+    coreDestroyHashMap(&mouseToButtonId);
 }
 
-void Window::Controls::bindKey(ButtonId id, int key) {
-    keyToButtonId.add(key, id);
+CoreButton coreButtonAdd(const char* name) {
+    if(buttonIndex >= BUTTONS) {
+        return 0;
+    }
+    CoreButton b = buttonIndex++;
+    snprintf(buttons[b].name, sizeof(buttons[b].name), "%s", name);
+    return b;
 }
 
-void Window::Controls::bindGamepad(ButtonId id, int gamepadButton) {
-    gamepadToButtonId.add(gamepadButton, id);
+void coreButtonBindKey(CoreButton b, int key) {
+    coreHashMapPut(&keyToButtonId, int, key, CoreButton, b);
 }
 
-void Window::Controls::bindMouse(ButtonId id, int mouseButton) {
-    mouseToButtonId.add(mouseButton, id);
+void coreButtonBindGamepad(CoreButton b, int gamepadButton) {
+    coreHashMapPut(&gamepadToButtonId, int, gamepadButton, CoreButton, b);
 }
 
-Vector2 Window::Controls::getLastMousePosition() {
+void coreButtonBindMouse(CoreButton b, int mouseButton) {
+    coreHashMapPut(&mouseToButtonId, int, mouseButton, CoreButton, b);
+}
+
+CoreVector2 coreButtonLastMousePosition(void) {
     return lastMousePosition;
 }
 
-Vector2 Window::Controls::getMousePosition() {
+CoreVector2 coreButtonMousePosition(void) {
     return mousePosition;
 }
 
-Vector2 Window::Controls::getLeftGamepadAxis() {
-    return Vector2(lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_X],
-                   lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]);
+CoreVector2 coreButtonLeftGamepadAxis(void) {
+    return (CoreVector2){lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_X],
+                         lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]};
 }
 
-Vector2 Window::Controls::getRightGamepadAxis() {
-    return Vector2(lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_X],
-                   lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y]);
+CoreVector2 coreButtonRightGamepadAxis(void) {
+    return (CoreVector2){lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_X],
+                         lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y]};
 }
 
-float Window::Controls::getLeftGamepadTrigger() {
+float coreButtonLeftGamepadTrigger(void) {
     return lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER];
 }
 
-float Window::Controls::getRightGamepadTrigger() {
+float coreButtonRightGamepadTrigger(void) {
     return lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER];
 }
 
-static const Button& getButton(Window::Controls::ButtonId id) {
-    if(id < 0 || id >= buttons.getLength()) {
-        return fallbackButton;
-    }
-    return buttons[id];
+static const ButtonData* getButton(CoreButton id) {
+    return buttons + (id >= buttonIndex ? 0 : id);
 }
 
-bool Window::Controls::isDown(ButtonId id) {
-    return getButton(id).downTime > 0;
+bool coreButtonDown(CoreButton b) {
+    return getButton(b)->downTime > 0;
 }
 
-int Window::Controls::getDownTime(ButtonId id) {
-    return getButton(id).downTime;
+int coreButtonDownTime(CoreButton b) {
+    return getButton(b)->downTime;
 }
 
-bool Window::Controls::wasReleased(ButtonId id) {
-    return getButton(id).released;
+bool coreButtonReleased(CoreButton b) {
+    return getButton(b)->released;
 }
 
-const Window::Controls::ButtonName& Window::Controls::getName(ButtonId id) {
-    return getButton(id).name;
+const char* coreButtonName(CoreButton b) {
+    return getButton(b)->name;
 }
-*/