|
@@ -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;
|
|
|
}
|
|
|
-*/
|