|
@@ -1,12 +1,43 @@
|
|
|
#include "core/Window.h"
|
|
|
|
|
|
-/*static GLFWwindow* window = nullptr;
|
|
|
-static Clock fps;
|
|
|
-static Clock tps;
|
|
|
-static IntVector2 size{0, 0};
|
|
|
-static bool sizeChanged = false;
|
|
|
+#include <GLFW/glfw3.h>
|
|
|
+#include <core/Logger.h>
|
|
|
+#include <core/Utility.h>
|
|
|
+#include <stdio.h>
|
|
|
+
|
|
|
+static bool dummyWindowRunHandler(void*) {
|
|
|
+ return !coreWindowShouldClose();
|
|
|
+}
|
|
|
+
|
|
|
+static void dummyWindowTickHandler(void*) {
|
|
|
+}
|
|
|
+
|
|
|
+static void dummyWindowRenderHandler(void*, float) {
|
|
|
+}
|
|
|
|
|
|
-static List<uint32> input;
|
|
|
+static GLFWwindow* window = nullptr;
|
|
|
+static CoreIntVector2 size = {0, 0};
|
|
|
+static bool sizeChanged = false;
|
|
|
+static CoreWindowRunHandler runHandler = dummyWindowRunHandler;
|
|
|
+static CoreWindowTickHandler tickHandler = dummyWindowTickHandler;
|
|
|
+static CoreWindowRenderHandler renderHandler = dummyWindowRenderHandler;
|
|
|
+static void* runHandlerData = nullptr;
|
|
|
+static void* tickHandlerData = nullptr;
|
|
|
+static void* renderHandlerData = nullptr;
|
|
|
+static i64 nanosPerTick = 1;
|
|
|
+
|
|
|
+#define CLOCK_SIZE 16
|
|
|
+typedef struct {
|
|
|
+ i64 last;
|
|
|
+ i64 sum;
|
|
|
+ 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;
|
|
@@ -142,58 +173,39 @@ static void onMouse(GLFWwindow*, int button, int action, int mods) {
|
|
|
|
|
|
static void onMouseMove(GLFWwindow*, double x, double y) {
|
|
|
mousePosition = Vector<2, double>(x, y).toFloat();
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
-Error Window::open(const Options& o) {
|
|
|
+bool coreWindowOpen(const CoreWindowOptions* o) {
|
|
|
if(!glfwInit()) {
|
|
|
- Error e{"could not initialize GLFW"};
|
|
|
- addError(e);
|
|
|
- return e;
|
|
|
+ CORE_LOG_ERROR("could not initialize GLFW");
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
glfwDefaultWindowHints();
|
|
|
glfwWindowHint(GLFW_VISIBLE, false);
|
|
|
glfwWindowHint(GLFW_RESIZABLE, true);
|
|
|
- glfwWindowHint(GLFW_DECORATED, !o.fullscreen);
|
|
|
+ glfwWindowHint(GLFW_DECORATED, !o->fullscreen);
|
|
|
glfwWindowHint(GLFW_DOUBLEBUFFER, true);
|
|
|
|
|
|
- if(o.es) {
|
|
|
- glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
|
|
- } else {
|
|
|
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
- }
|
|
|
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, o.majorVersion);
|
|
|
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, o.minorVersion);
|
|
|
-
|
|
|
- GLFWmonitor* m = o.fullscreen ? glfwGetPrimaryMonitor() : nullptr;
|
|
|
- window = glfwCreateWindow(o.size[0], o.size[1], o.name, m, nullptr);
|
|
|
+ GLFWmonitor* m = o->fullscreen ? glfwGetPrimaryMonitor() : nullptr;
|
|
|
+ window =
|
|
|
+ glfwCreateWindow(o->size.data[0], o->size.data[1], o->name, m, nullptr);
|
|
|
if(window == nullptr) {
|
|
|
- Error e{"could not create window"};
|
|
|
- addError(e);
|
|
|
- close();
|
|
|
- return e;
|
|
|
+ CORE_LOG_ERROR("could not create window");
|
|
|
+ coreWindowClose();
|
|
|
+ return true;
|
|
|
}
|
|
|
- size = o.size;
|
|
|
- glfwSetKeyCallback(window, onKey);
|
|
|
- glfwSetCharCallback(window, onChar);
|
|
|
- glfwSetFramebufferSizeCallback(window, onResize);
|
|
|
- glfwSetMouseButtonCallback(window, onMouse);
|
|
|
- glfwSetCursorPosCallback(window, onMouseMove);
|
|
|
+ size = o->size;
|
|
|
+ // glfwSetKeyCallback(window, onKey);
|
|
|
+ // glfwSetCharCallback(window, onChar);
|
|
|
+ // glfwSetFramebufferSizeCallback(window, onResize);
|
|
|
+ // glfwSetMouseButtonCallback(window, onMouse);
|
|
|
+ // glfwSetCursorPosCallback(window, onMouseMove);
|
|
|
|
|
|
- glfwMakeContextCurrent(window);
|
|
|
- glfwSwapInterval(o.vsync);
|
|
|
-
|
|
|
- GLenum err = glewInit();
|
|
|
- if(err != GLEW_OK) {
|
|
|
- Error e{"could not initialize GLEW: "};
|
|
|
- e.message.append(glewGetErrorString(err));
|
|
|
- close();
|
|
|
- return e;
|
|
|
- }
|
|
|
- return {};
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
-void Window::close() {
|
|
|
+void coreWindowClose(void) {
|
|
|
if(window != nullptr) {
|
|
|
glfwDestroyWindow(window);
|
|
|
window = nullptr;
|
|
@@ -201,47 +213,111 @@ void Window::close() {
|
|
|
glfwTerminate();
|
|
|
}
|
|
|
|
|
|
-float Window::getTicksPerSecond() {
|
|
|
- return tps.getUpdatesPerSecond();
|
|
|
+void coreWindowShow(void) {
|
|
|
+ glfwShowWindow(window);
|
|
|
+}
|
|
|
+
|
|
|
+void coreWindowTrapCursor(void) {
|
|
|
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
|
+}
|
|
|
+
|
|
|
+void coreWindowFreeCursor(void) {
|
|
|
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
|
}
|
|
|
|
|
|
-float Window::getFramesPerSecond() {
|
|
|
- return fps.getUpdatesPerSecond();
|
|
|
+bool coreWindowIsCursorTrapped(void) {
|
|
|
+ return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
|
|
|
}
|
|
|
|
|
|
-const IntVector2& Window::getSize() {
|
|
|
- return size;
|
|
|
+const CoreIntVector2* coreWindowGetSize(void) {
|
|
|
+ return &size;
|
|
|
}
|
|
|
|
|
|
-bool Window::hasSizeChanged() {
|
|
|
+bool CoreWindowSizeChanged(void) {
|
|
|
return sizeChanged;
|
|
|
}
|
|
|
|
|
|
-void Window::trapCursor() {
|
|
|
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
|
+bool coreWindowShouldClose(void) {
|
|
|
+ return glfwWindowShouldClose(window);
|
|
|
}
|
|
|
|
|
|
-void Window::freeCursor() {
|
|
|
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
|
+void coreWindowRunHandler(CoreWindowRunHandler wr, void* data) {
|
|
|
+ runHandlerData = data;
|
|
|
+ runHandler = wr == nullptr ? dummyWindowRunHandler : wr;
|
|
|
}
|
|
|
|
|
|
-bool Window::isCursorTrapped() {
|
|
|
- return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
|
|
|
+void coreWindowTickHandler(CoreWindowTickHandler t, void* data) {
|
|
|
+ tickHandlerData = data;
|
|
|
+ tickHandler = t == nullptr ? dummyWindowTickHandler : t;
|
|
|
}
|
|
|
|
|
|
-void Window::show() {
|
|
|
- glfwShowWindow(window);
|
|
|
+void coreWindowRenderHandler(CoreWindowRenderHandler r, void* data) {
|
|
|
+ renderHandlerData = data;
|
|
|
+ renderHandler = r == nullptr ? dummyWindowRenderHandler : r;
|
|
|
}
|
|
|
|
|
|
-bool Window::shouldClose() {
|
|
|
- return glfwWindowShouldClose(window);
|
|
|
+void coreWindowNanosPerTick(i64 nanos) {
|
|
|
+ nanosPerTick = nanos <= 0 ? 1 : nanos;
|
|
|
}
|
|
|
|
|
|
-Error Window::startFrame(Clock::Nanos& n) {
|
|
|
- return fps.update(n);
|
|
|
+static i64 updateClock(Clock* c) {
|
|
|
+ i64 nanos = coreNanos();
|
|
|
+ if(nanos < 0) {
|
|
|
+ CORE_LOG_WARNING("Cannot get nanos, using default");
|
|
|
+ nanos = 10000000 + c->last;
|
|
|
+ }
|
|
|
+ i64 diff = nanos - c->last;
|
|
|
+ c->last = nanos;
|
|
|
+ c->sum -= c->values[c->index];
|
|
|
+ c->values[c->index] = diff;
|
|
|
+ c->sum += diff;
|
|
|
+ c->index = (c->index + 1) % CLOCK_SIZE;
|
|
|
+ return diff;
|
|
|
+}
|
|
|
+
|
|
|
+static void endFrame(void) {
|
|
|
+ sizeChanged = false;
|
|
|
+ glfwSwapBuffers(window);
|
|
|
+ glfwPollEvents();
|
|
|
+ // if(searchForGamepad()) {
|
|
|
+ // checkGamepad();
|
|
|
+ // }
|
|
|
+}
|
|
|
+
|
|
|
+static void tick() {
|
|
|
+ updateClock(&tps);
|
|
|
+ // for(Button& b : buttons) {
|
|
|
+ // b.tick();
|
|
|
+ // }
|
|
|
+ tickHandler(tickHandlerData);
|
|
|
+ // lastMousePosition = mousePosition;
|
|
|
}
|
|
|
|
|
|
-static bool searchForGamepad() {
|
|
|
+void coreWindowRun(void) {
|
|
|
+ glfwMakeContextCurrent(window);
|
|
|
+ tps.last = coreNanos();
|
|
|
+ fps.last = coreNanos();
|
|
|
+ i64 lag = 0;
|
|
|
+ while(runHandler(runHandlerData)) {
|
|
|
+ lag += updateClock(&fps);
|
|
|
+ while(lag >= nanosPerTick) {
|
|
|
+ lag -= nanosPerTick;
|
|
|
+ tick();
|
|
|
+ }
|
|
|
+ renderHandler(renderHandlerData, (float)lag / (float)nanosPerTick);
|
|
|
+ endFrame();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+float coreWindowTicksPerSecond(void) {
|
|
|
+ return (1000000000.0f * CLOCK_SIZE) / (float)tps.sum;
|
|
|
+}
|
|
|
+
|
|
|
+float coreWindowFramesPerSecond(void) {
|
|
|
+ return (1000000000.0f * CLOCK_SIZE) / (float)fps.sum;
|
|
|
+}
|
|
|
+
|
|
|
+/*static bool searchForGamepad() {
|
|
|
if(activeController != -1) {
|
|
|
return true;
|
|
|
}
|
|
@@ -278,31 +354,6 @@ static void checkGamepad() {
|
|
|
lastControllerState = state;
|
|
|
}
|
|
|
|
|
|
-void Window::endFrame() {
|
|
|
- glfwSwapBuffers(window);
|
|
|
- sizeChanged = false;
|
|
|
- glfwPollEvents();
|
|
|
- if(searchForGamepad()) {
|
|
|
- checkGamepad();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-Error Window::tick() {
|
|
|
- Clock::Nanos n = 0;
|
|
|
- Error e = tps.update(n);
|
|
|
- if(e.has()) {
|
|
|
- return e;
|
|
|
- }
|
|
|
- for(Button& b : buttons) {
|
|
|
- b.tick();
|
|
|
- }
|
|
|
- return Error();
|
|
|
-}
|
|
|
-
|
|
|
-void Window::postTick() {
|
|
|
- lastMousePosition = mousePosition;
|
|
|
-}
|
|
|
-
|
|
|
void Window::Input::setLimit(int l) {
|
|
|
inputLimit = l;
|
|
|
while(input.getLength() > inputLimit) {
|
|
@@ -444,4 +495,5 @@ bool Window::Controls::wasReleased(ButtonId id) {
|
|
|
|
|
|
const Window::Controls::ButtonName& Window::Controls::getName(ButtonId id) {
|
|
|
return getButton(id).name;
|
|
|
-}*/
|
|
|
+}
|
|
|
+*/
|