|
@@ -5,7 +5,9 @@
|
|
|
#include <core/HashMap.h>
|
|
|
#include <core/Logger.h>
|
|
|
#include <core/Utility.h>
|
|
|
+#include <limits.h>
|
|
|
#include <stdio.h>
|
|
|
+#include <uchar.h>
|
|
|
|
|
|
static bool dummyWindowRunHandler(void*) {
|
|
|
return !shouldWindowClose();
|
|
@@ -38,10 +40,12 @@ typedef struct {
|
|
|
static Clock fps = {0};
|
|
|
static Clock tps = {0};
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+#define INPUT_SIZE 2048
|
|
|
+static char input[INPUT_SIZE] = {0};
|
|
|
+static size_t inputLength = 0;
|
|
|
+static size_t inputCursor = 0;
|
|
|
+static size_t inputLimit = INPUT_SIZE - 1;
|
|
|
+static bool inputActive = false;
|
|
|
|
|
|
typedef struct {
|
|
|
char name[31];
|
|
@@ -82,13 +86,8 @@ static void onButton(Button* map, int n, int key, int action) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- const char* description = nullptr;
|
|
|
- int errorCode = glfwGetError(&description);
|
|
|
- if(errorCode == GLFW_NO_ERROR) {
|
|
|
- return;
|
|
|
- }
|
|
|
- e.message.append(": ").append(description);
|
|
|
+static bool isCharSequence(size_t i) {
|
|
|
+ return (input[i] & 0xC0) == 0x80;
|
|
|
}
|
|
|
|
|
|
static void handleInputKey(int key, int action) {
|
|
@@ -97,43 +96,66 @@ static void handleInputKey(int key, int action) {
|
|
|
}
|
|
|
switch(key) {
|
|
|
case GLFW_KEY_BACKSPACE:
|
|
|
- if(input.getLength() > inputCursor - 1 && inputCursor > 0) {
|
|
|
- input.remove(inputCursor - 1);
|
|
|
+ if(inputLength >= inputCursor && inputCursor > 0) {
|
|
|
+ size_t w = 1;
|
|
|
+ while(inputCursor - w > 0 && isCharSequence(inputCursor - w)) {
|
|
|
+ w++;
|
|
|
+ }
|
|
|
+ for(size_t i = inputCursor - w; i < inputLength; i++) {
|
|
|
+ input[i] = input[i + w];
|
|
|
+ }
|
|
|
+ inputLength -= w;
|
|
|
+ inputCursor -= w;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case GLFW_KEY_LEFT: {
|
|
|
+ inputCursor -= inputCursor > 0;
|
|
|
+ while(inputCursor > 0 && isCharSequence(inputCursor)) {
|
|
|
inputCursor--;
|
|
|
}
|
|
|
break;
|
|
|
- case GLFW_KEY_LEFT: inputCursor -= inputCursor > 0; break;
|
|
|
- case GLFW_KEY_RIGHT:
|
|
|
- inputCursor += inputCursor < input.getLength();
|
|
|
+ }
|
|
|
+ case GLFW_KEY_RIGHT: {
|
|
|
+ inputCursor += inputCursor < inputLength;
|
|
|
+ while(inputCursor < inputLength && isCharSequence(inputCursor)) {
|
|
|
+ inputCursor++;
|
|
|
+ }
|
|
|
break;
|
|
|
+ }
|
|
|
}
|
|
|
-}*/
|
|
|
+}
|
|
|
|
|
|
static void onKey(GLFWwindow*, int key, int scancode, int action, int mods) {
|
|
|
(void)scancode;
|
|
|
(void)mods;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ if(inputActive) {
|
|
|
+ handleInputKey(key, action);
|
|
|
+ }
|
|
|
onButton(keyToButton, KEYS, key, action);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- if(input.getLength() >= inputLimit) {
|
|
|
+static void addUnicode(u32 c) {
|
|
|
+ char buffer[MB_LEN_MAX + 1] = {0};
|
|
|
+ mbstate_t state = {0};
|
|
|
+ size_t w = c32rtomb(buffer, c, &state);
|
|
|
+ if(w >= MB_LEN_MAX || inputLength + w >= inputLimit) {
|
|
|
return;
|
|
|
}
|
|
|
- input.add(codepoint);
|
|
|
- for(int i = input.getLength() - 1; i > inputCursor; i--) {
|
|
|
- ::swap(input[i], input[i - 1]);
|
|
|
+ if(inputLength > 0) {
|
|
|
+ for(size_t i = inputLength - 1; i >= inputCursor; i--) {
|
|
|
+ swap(input + (i + w), input + i);
|
|
|
+ }
|
|
|
}
|
|
|
- inputCursor++;
|
|
|
+ memcpy(input + inputCursor, buffer, w);
|
|
|
+ inputLength += w;
|
|
|
+ inputCursor += w;
|
|
|
}
|
|
|
|
|
|
-static void onChar(GLFWwindow*, uint32 codepoint) {
|
|
|
+static void onChar(GLFWwindow*, u32 codepoint) {
|
|
|
if(inputActive) {
|
|
|
addUnicode(codepoint);
|
|
|
}
|
|
|
-}*/
|
|
|
+}
|
|
|
|
|
|
static void onResize(GLFWwindow*, int width, int height) {
|
|
|
sizeChanged = true;
|
|
@@ -153,7 +175,7 @@ static void onMouseMove(GLFWwindow*, double x, double y) {
|
|
|
|
|
|
bool openWindow(const WindowOptions* o) {
|
|
|
if(!glfwInit()) {
|
|
|
- CORE_LOG_ERROR("could not initialize GLFW");
|
|
|
+ LOG_ERROR("could not initialize GLFW");
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -167,13 +189,13 @@ bool openWindow(const WindowOptions* o) {
|
|
|
window =
|
|
|
glfwCreateWindow(o->size.data[0], o->size.data[1], o->name, m, nullptr);
|
|
|
if(window == nullptr) {
|
|
|
- CORE_LOG_ERROR("could not create window");
|
|
|
+ LOG_ERROR("could not create window");
|
|
|
closeWindow();
|
|
|
return true;
|
|
|
}
|
|
|
size = o->size;
|
|
|
glfwSetKeyCallback(window, onKey);
|
|
|
-
|
|
|
+ glfwSetCharCallback(window, onChar);
|
|
|
glfwSetFramebufferSizeCallback(window, onResize);
|
|
|
glfwSetMouseButtonCallback(window, onMouse);
|
|
|
glfwSetCursorPosCallback(window, onMouseMove);
|
|
@@ -238,7 +260,7 @@ void setWindowNanosPerTick(i64 nanos) {
|
|
|
static i64 updateClock(Clock* c) {
|
|
|
i64 nanos = getNanos();
|
|
|
if(nanos < 0) {
|
|
|
- CORE_LOG_WARNING("Cannot get nanos, using default");
|
|
|
+ LOG_WARNING("Cannot get nanos, using default");
|
|
|
nanos = 10000000 + c->last;
|
|
|
}
|
|
|
i64 diff = nanos - c->last;
|
|
@@ -343,85 +365,55 @@ float getWindowFramesPerSecond(void) {
|
|
|
return (1000000000.0f * CLOCK_SIZE) / (float)fps.sum;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-void Window::Input::setLimit(int l) {
|
|
|
- inputLimit = l;
|
|
|
- while(input.getLength() > inputLimit) {
|
|
|
- input.removeBySwap(inputLimit);
|
|
|
+void setInputLimit(size_t limit) {
|
|
|
+ inputLimit = limit >= INPUT_SIZE ? INPUT_SIZE - 1 : limit;
|
|
|
+ if(inputLength > inputLimit) {
|
|
|
+ inputLength = inputLimit;
|
|
|
+ }
|
|
|
+ if(inputCursor > inputLimit) {
|
|
|
+ inputCursor = inputLimit;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Window::Input::reset() {
|
|
|
- input.clear();
|
|
|
+void resetInput() {
|
|
|
+ inputLength = 0;
|
|
|
inputCursor = 0;
|
|
|
}
|
|
|
|
|
|
-void Window::Input::enable() {
|
|
|
+void enableInput() {
|
|
|
inputActive = true;
|
|
|
}
|
|
|
|
|
|
-void Window::Input::disable() {
|
|
|
+void disableInput() {
|
|
|
inputActive = false;
|
|
|
}
|
|
|
|
|
|
-bool Window::Input::isEnabled() {
|
|
|
+bool isInputEnabled() {
|
|
|
return inputActive;
|
|
|
}
|
|
|
|
|
|
-static uint32 read(int& index, const char* s) {
|
|
|
- if(s[index] == '\0') {
|
|
|
- return '\0';
|
|
|
- }
|
|
|
- return static_cast<uint32>(s[index++]);
|
|
|
-}
|
|
|
-
|
|
|
-static uint32 readUnicode(int& index, const char* s) {
|
|
|
- uint32 c = read(index, s);
|
|
|
- if((c & 0xE0) == 0xC0) {
|
|
|
- c = ((c & 0x1F) << 6) | (read(index, s) & 0x3F);
|
|
|
- } else if((c & 0xF0) == 0xE0) {
|
|
|
- c = ((c & 0xF) << 12) | ((read(index, s) & 0x3F) << 6);
|
|
|
- c |= read(index, s) & 0x3F;
|
|
|
- } else if((c & 0xF8) == 0xF0) {
|
|
|
- c = ((c & 0x7) << 18) | ((read(index, s) & 0x3F) << 12);
|
|
|
- c |= (read(index, s) & 0x3F) << 6;
|
|
|
- c |= read(index, s) & 0x3F;
|
|
|
- }
|
|
|
- return c;
|
|
|
+void fillInput(const char* s) {
|
|
|
+ resetInput();
|
|
|
+ snprintf(input, inputLength, "%s", s);
|
|
|
}
|
|
|
|
|
|
-void Window::Input::fill(const char* s) {
|
|
|
- int index = 0;
|
|
|
- reset();
|
|
|
- while(true) {
|
|
|
- uint32 c = readUnicode(index, s);
|
|
|
- if(c == '\0') {
|
|
|
- break;
|
|
|
- }
|
|
|
- addUnicode(c);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int Window::Input::getCursor() {
|
|
|
+size_t getInputCursor() {
|
|
|
return inputCursor;
|
|
|
}
|
|
|
|
|
|
-void Window::Input::setCursor(int index) {
|
|
|
- if(index < 0) {
|
|
|
- inputCursor = 0;
|
|
|
- } else if(index > input.getLength()) {
|
|
|
- inputCursor = input.getLength();
|
|
|
+void setInputCursor(size_t index) {
|
|
|
+ if(index > inputLength) {
|
|
|
+ inputCursor = inputLength;
|
|
|
} else {
|
|
|
inputCursor = index;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const List<uint32>& Window::Input::getUnicode() {
|
|
|
+const char* getInputString(void) {
|
|
|
return input;
|
|
|
-}*/
|
|
|
+}
|
|
|
|
|
|
-Button coreAddButton(const char* name) {
|
|
|
+Button addButton(const char* name) {
|
|
|
if(buttonIndex >= BUTTONS) {
|
|
|
return 0;
|
|
|
}
|
|
@@ -430,47 +422,47 @@ Button coreAddButton(const char* name) {
|
|
|
return b;
|
|
|
}
|
|
|
|
|
|
-void coreBindKeyToButton(Button b, int key) {
|
|
|
+void bindKeyToButton(Button b, int key) {
|
|
|
if(key >= 0 && key < KEYS) {
|
|
|
keyToButton[key] = b;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void coreBindGamepadToButton(Button b, int gamepadButton) {
|
|
|
+void bindGamepadToButton(Button b, int gamepadButton) {
|
|
|
if(gamepadButton >= 0 && gamepadButton < GAMEPAD_BUTTONS) {
|
|
|
gamepadToButton[gamepadButton] = b;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void coreBindMouseToButton(Button b, int mouseButton) {
|
|
|
+void bindMouseToButton(Button b, int mouseButton) {
|
|
|
if(mouseButton >= 0 && mouseButton < MOUSE_BUTTONS) {
|
|
|
mouseToButton[mouseButton] = b;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-Vector2 coreGetLastMousePosition(void) {
|
|
|
+Vector2 getLastMousePosition(void) {
|
|
|
return lastMousePosition;
|
|
|
}
|
|
|
|
|
|
-Vector2 coreGetMousePosition(void) {
|
|
|
+Vector2 getMousePosition(void) {
|
|
|
return mousePosition;
|
|
|
}
|
|
|
|
|
|
-Vector2 coreGetLeftGamepadAxis(void) {
|
|
|
+Vector2 getLeftGamepadAxis(void) {
|
|
|
return (Vector2){{lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_X],
|
|
|
lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_Y]}};
|
|
|
}
|
|
|
|
|
|
-Vector2 coreGetRightGamepadAxis(void) {
|
|
|
+Vector2 getRightGamepadAxis(void) {
|
|
|
return (Vector2){{lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_X],
|
|
|
lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y]}};
|
|
|
}
|
|
|
|
|
|
-float coreGetLeftGamepadTrigger(void) {
|
|
|
+float getLeftGamepadTrigger(void) {
|
|
|
return lastControllerState.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER];
|
|
|
}
|
|
|
|
|
|
-float coreGetRightGamepadTrigger(void) {
|
|
|
+float getRightGamepadTrigger(void) {
|
|
|
return lastControllerState.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER];
|
|
|
}
|
|
|
|
|
@@ -478,18 +470,18 @@ static const ButtonData* getButton(Button id) {
|
|
|
return buttons + (id >= buttonIndex ? 0 : id);
|
|
|
}
|
|
|
|
|
|
-bool coreIsButtonDown(Button b) {
|
|
|
+bool isButtonDown(Button b) {
|
|
|
return getButton(b)->downTime > 0;
|
|
|
}
|
|
|
|
|
|
-int coreGetButtonDownTime(Button b) {
|
|
|
+int getButtonDownTime(Button b) {
|
|
|
return getButton(b)->downTime;
|
|
|
}
|
|
|
|
|
|
-bool coreWasButtonReleased(Button b) {
|
|
|
+bool wasButtonReleased(Button b) {
|
|
|
return getButton(b)->released;
|
|
|
}
|
|
|
|
|
|
-const char* coreGetButtonName(Button b) {
|
|
|
+const char* getButtonName(Button b) {
|
|
|
return getButton(b)->name;
|
|
|
}
|