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