#include #include "input/Controller.h" Controller::Axis::Axis() : positive(0), negative(0), split(0.5f) { } Controller::Controller() : keyToButton(0), gamepadToButton(0), activeController(-1) { mapGamepad(GLFW_GAMEPAD_BUTTON_A, Controller::A); mapGamepad(GLFW_GAMEPAD_BUTTON_B, Controller::B); mapGamepad(GLFW_GAMEPAD_BUTTON_X, Controller::X); mapGamepad(GLFW_GAMEPAD_BUTTON_Y, Controller::Y); mapGamepad(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, Controller::L); mapGamepad(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, Controller::R); mapGamepad(GLFW_GAMEPAD_BUTTON_BACK, Controller::SELECT); mapGamepad(GLFW_GAMEPAD_BUTTON_START, Controller::START); mapGamepad(GLFW_GAMEPAD_BUTTON_GUIDE, Controller::UNKNOWN); mapGamepad(GLFW_GAMEPAD_BUTTON_LEFT_THUMB, Controller::SELECT); mapGamepad(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, Controller::START); mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_UP, Controller::UP); mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, Controller::RIGHT); mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_DOWN, Controller::DOWN); mapGamepad(GLFW_GAMEPAD_BUTTON_DPAD_LEFT, Controller::LEFT); mapAxis(GLFW_GAMEPAD_AXIS_LEFT_X, Controller::RIGHT, Controller::LEFT); mapAxis(GLFW_GAMEPAD_AXIS_LEFT_Y, Controller::DOWN, Controller::UP); mapAxis(GLFW_GAMEPAD_AXIS_RIGHT_X, Controller::RIGHT, Controller::LEFT); mapAxis(GLFW_GAMEPAD_AXIS_RIGHT_Y, Controller::DOWN, Controller::UP); mapAxis(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, Controller::L, Controller::UNKNOWN, -0.9f); mapAxis(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, Controller::R, Controller::UNKNOWN, -0.9f); } bool Controller::mapKey(int key, int button) { if(key < 0 || key >= keyToButton.getLength()) { return true; } button++; if(button < 0 || button >= buttons.getLength()) { return true; } keyToButton[key] = button; return false; } bool Controller::mapGamepad(int gamepad, int button) { if(gamepad < 0 || gamepad >= gamepadToButton.getLength()) { return true; } button++; if(button < 0 || button >= buttons.getLength()) { return true; } gamepadToButton[gamepad] = button; return false; } bool Controller::mapAxis(int axis, int positiveButton, int negativeButton, float split) { if(axis < 0 || axis >= axisToButton.getLength()) { return true; } positiveButton++; if(positiveButton < 0 || positiveButton >= buttons.getLength()) { return true; } negativeButton++; if(negativeButton < 0 || negativeButton >= buttons.getLength()) { return true; } axisToButton[axis].positive = positiveButton; axisToButton[axis].negative = negativeButton; axisToButton[axis].split = split; return false; } void Controller::press(int key) { if(key < 0 || key >= keyToButton.getLength()) { return; } buttons[keyToButton[key]].pressKey(); } void Controller::release(int key) { if(key < 0 || key >= keyToButton.getLength()) { return; } buttons[keyToButton[key]].releaseKey(); } void Controller::tick() { for(Button& b : buttons) { b.tick(); } if(searchForGamepad()) { checkGamepad(); } } bool Controller::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; } void Controller::checkGamepad() { GLFWgamepadstate state; if(!glfwGetGamepadState(activeController, &state)) { return; } for(int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) { if(state.buttons[i]) { buttons[gamepadToButton[i]].pressButton(); } } for(int i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++) { if(state.axes[i] > axisToButton[i].split) { buttons[axisToButton[i].positive].pressButton(); } else if(state.axes[i] < -axisToButton[i].split) { buttons[axisToButton[i].negative].pressButton(); } } } int Controller::getButtonAmount() const { return buttons.getLength() - 1; } const char* Controller::getName(int button) const { static constexpr const char* buttonNames[BUTTON_AMOUNT] = { "Unknown", "A", "B", "X", "Y", "L", "R", "Start", "Select", "Left", "Right", "Up", "Down" }; return buttonNames[(button + 1) & getRangeMask(button + 1)]; } bool Controller::isDown(int button) const { return buttons[(button + 1) & getRangeMask(button + 1)].isDown(); } int Controller::getDownTime(int button) const { return buttons[(button + 1) & getRangeMask(button + 1)].getDownTime(); } bool Controller::wasReleased(int button) const { return buttons[(button + 1) & getRangeMask(button + 1)].wasReleased(); } int Controller::getRangeMask(int button) const { return -(button >= 0 && button < buttons.getLength()); }