#include "input.hpp"
Input* Input::inst = NULL;
const size_t Input::maxevents = 10;
Input::Input(Window* w): window(w) {
assert(!inst);
inst = this;
//glfwSetInputMode(window, GLFW_STICKY_KEYS, 1);
glfwSetKeyCallback(window->window, &keyFun);
glfwSetMouseButtonCallback(window->window, &clickFun);
glfwSetScrollCallback(window->window, &scrollFun);
}
void Input::shouldClose() {
window->shouldClose(true);
}
void Input::keyFun(GLFWwindow* window, int key, int, int action, int) {
assert(window == inst->window->window);
if (action != GLFW_PRESS && action != GLFW_REPEAT) return;
switch (key) {
case GLFW_KEY_ESCAPE:
inst->window->shouldClose(true);
break;
case GLFW_KEY_PAGE_UP:
inst->pans++;
break;
case GLFW_KEY_PAGE_DOWN:
inst->pans--;
break;
case GLFW_KEY_RIGHT:
case GLFW_KEY_D:
if (inst->poskeys.size() < inst->maxevents) inst->poskeys.push((poskey_t){1, 0});
break;
case GLFW_KEY_LEFT:
case GLFW_KEY_A:
if (inst->poskeys.size() < inst->maxevents) inst->poskeys.push((poskey_t){-1, 0});
break;
case GLFW_KEY_UP:
case GLFW_KEY_W:
if (inst->poskeys.size() < inst->maxevents) inst->poskeys.push((poskey_t){0, 1});
break;
case GLFW_KEY_DOWN:
case GLFW_KEY_S:
if (inst->poskeys.size() < inst->maxevents) inst->poskeys.push((poskey_t){0, -1});
break;
}
}
void Input::clickFun(GLFWwindow* window, int button, int action, int) {
assert(window == inst->window->window);
if (action != GLFW_RELEASE || button != GLFW_MOUSE_BUTTON_LEFT) {
return;
}
if (inst->clicks.size() >= inst->maxevents) {
return;
}
double xpos, ypos;
float zpos;
glfwGetCursorPos(window, &xpos, &ypos);
if (xpos < 0.0 || xpos >= inst->window->w || ypos < 0.0 || ypos >= inst->window->h) {
return;
}
ypos = ((double)inst->window->h) - ypos;
glReadPixels(floor(xpos), floor(ypos), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zpos);
if (zpos < 0.0 || zpos >= 1.0) {
return;
}
inst->clicks.push((click_t){xpos, ypos, zpos});
}
void Input::scrollFun(GLFWwindow* window, double, double yoffset) {
assert(window == inst->window->window);
inst->pans += yoffset;
}
bool Input::getPanKey(int& p) {
p = pans;
pans = 0;
return (p != 0);
}
bool Input::getPosKey(int& x, int& y) {
if (poskeys.empty()) return false;
x = poskeys.front().x;
y = poskeys.front().y;
poskeys.pop();
return true;
}
bool Input::getClick(double& x, double& y, float& z) {
if (clicks.empty()) return false;
x = clicks.front().x;
y = clicks.front().y;
z = clicks.front().z;
clicks.pop();
return true;
}