Program Listing for File inputResource.h
↰ Return to documentation for file (PrismEngine/src/inputResource.h)
#pragma once
#include <cstdint>
#include <algorithm>
#include <SDL.h>
namespace prism {
namespace scene {
enum class KeyCode : int {
// Буквы
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
// Цифры
Num0, Num1, Num2, Num3, Num4, Num5, Num6, Num7, Num8, Num9,
// Цифровая клавиатура
KP_0, KP_1, KP_2, KP_3, KP_4, KP_5, KP_6, KP_7, KP_8, KP_9, KP_Decimal, KP_Divide, KP_Multiply, KP_Subtract, KP_Add, KP_Enter, KP_Equal,
// Функциональные клавиши
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
// Специальные клавиши
Escape, Space, Enter, Tab, Backspace, Delete, Insert, CapsLock, ScrollLock, NumLock, PrintScreen, Pause,
// Модификаторы
LeftShift, RightShift, LeftControl, RightControl, LeftAlt, RightAlt, LeftSuper, RightSuper, Menu,
// Навигация
Up, Down, Left, Right, Home, End, PageUp, PageDown,
// Символьные клавиши
Comma, Period, Semicolon, Apostrophe, Slash, Backslash, LeftBracket, RightBracket, Minus, Equal, Grave, World1, World2,
COUNT, // Общее количество поддерживаемых клавиш
Unknown // Неизвестная клавиша
};
inline KeyCode sdlScancodeToKeyCode(SDL_Scancode scancode)
{
switch (scancode) {
case SDL_SCANCODE_A: return KeyCode::A;
case SDL_SCANCODE_B: return KeyCode::B;
case SDL_SCANCODE_C: return KeyCode::C;
case SDL_SCANCODE_D: return KeyCode::D;
case SDL_SCANCODE_E: return KeyCode::E;
case SDL_SCANCODE_F: return KeyCode::F;
case SDL_SCANCODE_G: return KeyCode::G;
case SDL_SCANCODE_H: return KeyCode::H;
case SDL_SCANCODE_I: return KeyCode::I;
case SDL_SCANCODE_J: return KeyCode::J;
case SDL_SCANCODE_K: return KeyCode::K;
case SDL_SCANCODE_L: return KeyCode::L;
case SDL_SCANCODE_M: return KeyCode::M;
case SDL_SCANCODE_N: return KeyCode::N;
case SDL_SCANCODE_O: return KeyCode::O;
case SDL_SCANCODE_P: return KeyCode::P;
case SDL_SCANCODE_Q: return KeyCode::Q;
case SDL_SCANCODE_R: return KeyCode::R;
case SDL_SCANCODE_S: return KeyCode::S;
case SDL_SCANCODE_T: return KeyCode::T;
case SDL_SCANCODE_U: return KeyCode::U;
case SDL_SCANCODE_V: return KeyCode::V;
case SDL_SCANCODE_W: return KeyCode::W;
case SDL_SCANCODE_X: return KeyCode::X;
case SDL_SCANCODE_Y: return KeyCode::Y;
case SDL_SCANCODE_Z: return KeyCode::Z;
case SDL_SCANCODE_0: return KeyCode::Num0;
case SDL_SCANCODE_1: return KeyCode::Num1;
case SDL_SCANCODE_2: return KeyCode::Num2;
case SDL_SCANCODE_3: return KeyCode::Num3;
case SDL_SCANCODE_4: return KeyCode::Num4;
case SDL_SCANCODE_5: return KeyCode::Num5;
case SDL_SCANCODE_6: return KeyCode::Num6;
case SDL_SCANCODE_7: return KeyCode::Num7;
case SDL_SCANCODE_8: return KeyCode::Num8;
case SDL_SCANCODE_9: return KeyCode::Num9;
case SDL_SCANCODE_KP_0: return KeyCode::KP_0;
case SDL_SCANCODE_KP_1: return KeyCode::KP_1;
case SDL_SCANCODE_KP_2: return KeyCode::KP_2;
case SDL_SCANCODE_KP_3: return KeyCode::KP_3;
case SDL_SCANCODE_KP_4: return KeyCode::KP_4;
case SDL_SCANCODE_KP_5: return KeyCode::KP_5;
case SDL_SCANCODE_KP_6: return KeyCode::KP_6;
case SDL_SCANCODE_KP_7: return KeyCode::KP_7;
case SDL_SCANCODE_KP_8: return KeyCode::KP_8;
case SDL_SCANCODE_KP_9: return KeyCode::KP_9;
case SDL_SCANCODE_KP_DECIMAL: return KeyCode::KP_Decimal;
case SDL_SCANCODE_KP_DIVIDE: return KeyCode::KP_Divide;
case SDL_SCANCODE_KP_MULTIPLY: return KeyCode::KP_Multiply;
case SDL_SCANCODE_KP_MINUS: return KeyCode::KP_Subtract;
case SDL_SCANCODE_KP_PLUS: return KeyCode::KP_Add;
case SDL_SCANCODE_KP_ENTER: return KeyCode::KP_Enter;
case SDL_SCANCODE_KP_EQUALS: return KeyCode::KP_Equal;
case SDL_SCANCODE_F1: return KeyCode::F1;
case SDL_SCANCODE_F2: return KeyCode::F2;
case SDL_SCANCODE_F3: return KeyCode::F3;
case SDL_SCANCODE_F4: return KeyCode::F4;
case SDL_SCANCODE_F5: return KeyCode::F5;
case SDL_SCANCODE_F6: return KeyCode::F6;
case SDL_SCANCODE_F7: return KeyCode::F7;
case SDL_SCANCODE_F8: return KeyCode::F8;
case SDL_SCANCODE_F9: return KeyCode::F9;
case SDL_SCANCODE_F10: return KeyCode::F10;
case SDL_SCANCODE_F11: return KeyCode::F11;
case SDL_SCANCODE_F12: return KeyCode::F12;
case SDL_SCANCODE_F13: return KeyCode::F13;
case SDL_SCANCODE_F14: return KeyCode::F14;
case SDL_SCANCODE_F15: return KeyCode::F15;
case SDL_SCANCODE_F16: return KeyCode::F16;
case SDL_SCANCODE_F17: return KeyCode::F17;
case SDL_SCANCODE_F18: return KeyCode::F18;
case SDL_SCANCODE_F19: return KeyCode::F19;
case SDL_SCANCODE_F20: return KeyCode::F20;
case SDL_SCANCODE_F21: return KeyCode::F21;
case SDL_SCANCODE_F22: return KeyCode::F22;
case SDL_SCANCODE_F23: return KeyCode::F23;
case SDL_SCANCODE_F24: return KeyCode::F24;
case SDL_SCANCODE_ESCAPE: return KeyCode::Escape;
case SDL_SCANCODE_SPACE: return KeyCode::Space;
case SDL_SCANCODE_RETURN: return KeyCode::Enter;
case SDL_SCANCODE_TAB: return KeyCode::Tab;
case SDL_SCANCODE_BACKSPACE: return KeyCode::Backspace;
case SDL_SCANCODE_DELETE: return KeyCode::Delete;
case SDL_SCANCODE_INSERT: return KeyCode::Insert;
case SDL_SCANCODE_CAPSLOCK: return KeyCode::CapsLock;
case SDL_SCANCODE_SCROLLLOCK: return KeyCode::ScrollLock;
case SDL_SCANCODE_NUMLOCKCLEAR: return KeyCode::NumLock;
case SDL_SCANCODE_PRINTSCREEN: return KeyCode::PrintScreen;
case SDL_SCANCODE_PAUSE: return KeyCode::Pause;
case SDL_SCANCODE_LSHIFT: return KeyCode::LeftShift;
case SDL_SCANCODE_RSHIFT: return KeyCode::RightShift;
case SDL_SCANCODE_LCTRL: return KeyCode::LeftControl;
case SDL_SCANCODE_RCTRL: return KeyCode::RightControl;
case SDL_SCANCODE_LALT: return KeyCode::LeftAlt;
case SDL_SCANCODE_RALT: return KeyCode::RightAlt;
case SDL_SCANCODE_LGUI: return KeyCode::LeftSuper;
case SDL_SCANCODE_RGUI: return KeyCode::RightSuper;
case SDL_SCANCODE_APPLICATION: return KeyCode::Menu;
case SDL_SCANCODE_UP: return KeyCode::Up;
case SDL_SCANCODE_DOWN: return KeyCode::Down;
case SDL_SCANCODE_LEFT: return KeyCode::Left;
case SDL_SCANCODE_RIGHT: return KeyCode::Right;
case SDL_SCANCODE_HOME: return KeyCode::Home;
case SDL_SCANCODE_END: return KeyCode::End;
case SDL_SCANCODE_PAGEUP: return KeyCode::PageUp;
case SDL_SCANCODE_PAGEDOWN: return KeyCode::PageDown;
case SDL_SCANCODE_COMMA: return KeyCode::Comma;
case SDL_SCANCODE_PERIOD: return KeyCode::Period;
case SDL_SCANCODE_SEMICOLON: return KeyCode::Semicolon;
case SDL_SCANCODE_APOSTROPHE: return KeyCode::Apostrophe;
case SDL_SCANCODE_SLASH: return KeyCode::Slash;
case SDL_SCANCODE_BACKSLASH: return KeyCode::Backslash;
case SDL_SCANCODE_LEFTBRACKET: return KeyCode::LeftBracket;
case SDL_SCANCODE_RIGHTBRACKET: return KeyCode::RightBracket;
case SDL_SCANCODE_MINUS: return KeyCode::Minus;
case SDL_SCANCODE_EQUALS: return KeyCode::Equal;
case SDL_SCANCODE_GRAVE: return KeyCode::Grave;
case SDL_SCANCODE_INTERNATIONAL1: return KeyCode::World1;
case SDL_SCANCODE_INTERNATIONAL2: return KeyCode::World2;
default: return KeyCode::Unknown;
}
}
inline SDL_Scancode keyCodeToSdlScancode(KeyCode keycode)
{
switch (keycode) {
case KeyCode::A: return SDL_SCANCODE_A;
case KeyCode::B: return SDL_SCANCODE_B;
case KeyCode::C: return SDL_SCANCODE_C;
case KeyCode::D: return SDL_SCANCODE_D;
case KeyCode::E: return SDL_SCANCODE_E;
case KeyCode::F: return SDL_SCANCODE_F;
case KeyCode::G: return SDL_SCANCODE_G;
case KeyCode::H: return SDL_SCANCODE_H;
case KeyCode::I: return SDL_SCANCODE_I;
case KeyCode::J: return SDL_SCANCODE_J;
case KeyCode::K: return SDL_SCANCODE_K;
case KeyCode::L: return SDL_SCANCODE_L;
case KeyCode::M: return SDL_SCANCODE_M;
case KeyCode::N: return SDL_SCANCODE_N;
case KeyCode::O: return SDL_SCANCODE_O;
case KeyCode::P: return SDL_SCANCODE_P;
case KeyCode::Q: return SDL_SCANCODE_Q;
case KeyCode::R: return SDL_SCANCODE_R;
case KeyCode::S: return SDL_SCANCODE_S;
case KeyCode::T: return SDL_SCANCODE_T;
case KeyCode::U: return SDL_SCANCODE_U;
case KeyCode::V: return SDL_SCANCODE_V;
case KeyCode::W: return SDL_SCANCODE_W;
case KeyCode::X: return SDL_SCANCODE_X;
case KeyCode::Y: return SDL_SCANCODE_Y;
case KeyCode::Z: return SDL_SCANCODE_Z;
case KeyCode::Num0: return SDL_SCANCODE_0;
case KeyCode::Num1: return SDL_SCANCODE_1;
case KeyCode::Num2: return SDL_SCANCODE_2;
case KeyCode::Num3: return SDL_SCANCODE_3;
case KeyCode::Num4: return SDL_SCANCODE_4;
case KeyCode::Num5: return SDL_SCANCODE_5;
case KeyCode::Num6: return SDL_SCANCODE_6;
case KeyCode::Num7: return SDL_SCANCODE_7;
case KeyCode::Num8: return SDL_SCANCODE_8;
case KeyCode::Num9: return SDL_SCANCODE_9;
case KeyCode::KP_0: return SDL_SCANCODE_KP_0;
case KeyCode::KP_1: return SDL_SCANCODE_KP_1;
case KeyCode::KP_2: return SDL_SCANCODE_KP_2;
case KeyCode::KP_3: return SDL_SCANCODE_KP_3;
case KeyCode::KP_4: return SDL_SCANCODE_KP_4;
case KeyCode::KP_5: return SDL_SCANCODE_KP_5;
case KeyCode::KP_6: return SDL_SCANCODE_KP_6;
case KeyCode::KP_7: return SDL_SCANCODE_KP_7;
case KeyCode::KP_8: return SDL_SCANCODE_KP_8;
case KeyCode::KP_9: return SDL_SCANCODE_KP_9;
case KeyCode::KP_Decimal: return SDL_SCANCODE_KP_DECIMAL;
case KeyCode::KP_Divide: return SDL_SCANCODE_KP_DIVIDE;
case KeyCode::KP_Multiply: return SDL_SCANCODE_KP_MULTIPLY;
case KeyCode::KP_Subtract: return SDL_SCANCODE_KP_MINUS;
case KeyCode::KP_Add: return SDL_SCANCODE_KP_PLUS;
case KeyCode::KP_Enter: return SDL_SCANCODE_KP_ENTER;
case KeyCode::KP_Equal: return SDL_SCANCODE_KP_EQUALS;
case KeyCode::F1: return SDL_SCANCODE_F1;
case KeyCode::F2: return SDL_SCANCODE_F2;
case KeyCode::F3: return SDL_SCANCODE_F3;
case KeyCode::F4: return SDL_SCANCODE_F4;
case KeyCode::F5: return SDL_SCANCODE_F5;
case KeyCode::F6: return SDL_SCANCODE_F6;
case KeyCode::F7: return SDL_SCANCODE_F7;
case KeyCode::F8: return SDL_SCANCODE_F8;
case KeyCode::F9: return SDL_SCANCODE_F9;
case KeyCode::F10: return SDL_SCANCODE_F10;
case KeyCode::F11: return SDL_SCANCODE_F11;
case KeyCode::F12: return SDL_SCANCODE_F12;
case KeyCode::F13: return SDL_SCANCODE_F13;
case KeyCode::F14: return SDL_SCANCODE_F14;
case KeyCode::F15: return SDL_SCANCODE_F15;
case KeyCode::F16: return SDL_SCANCODE_F16;
case KeyCode::F17: return SDL_SCANCODE_F17;
case KeyCode::F18: return SDL_SCANCODE_F18;
case KeyCode::F19: return SDL_SCANCODE_F19;
case KeyCode::F20: return SDL_SCANCODE_F20;
case KeyCode::F21: return SDL_SCANCODE_F21;
case KeyCode::F22: return SDL_SCANCODE_F22;
case KeyCode::F23: return SDL_SCANCODE_F23;
case KeyCode::F24: return SDL_SCANCODE_F24;
case KeyCode::Escape: return SDL_SCANCODE_ESCAPE;
case KeyCode::Space: return SDL_SCANCODE_SPACE;
case KeyCode::Enter: return SDL_SCANCODE_RETURN;
case KeyCode::Tab: return SDL_SCANCODE_TAB;
case KeyCode::Backspace: return SDL_SCANCODE_BACKSPACE;
case KeyCode::Delete: return SDL_SCANCODE_DELETE;
case KeyCode::Insert: return SDL_SCANCODE_INSERT;
case KeyCode::CapsLock: return SDL_SCANCODE_CAPSLOCK;
case KeyCode::ScrollLock: return SDL_SCANCODE_SCROLLLOCK;
case KeyCode::NumLock: return SDL_SCANCODE_NUMLOCKCLEAR;
case KeyCode::PrintScreen: return SDL_SCANCODE_PRINTSCREEN;
case KeyCode::Pause: return SDL_SCANCODE_PAUSE;
case KeyCode::LeftShift: return SDL_SCANCODE_LSHIFT;
case KeyCode::RightShift: return SDL_SCANCODE_RSHIFT;
case KeyCode::LeftControl: return SDL_SCANCODE_LCTRL;
case KeyCode::RightControl: return SDL_SCANCODE_RCTRL;
case KeyCode::LeftAlt: return SDL_SCANCODE_LALT;
case KeyCode::RightAlt: return SDL_SCANCODE_RALT;
case KeyCode::LeftSuper: return SDL_SCANCODE_LGUI;
case KeyCode::RightSuper: return SDL_SCANCODE_RGUI;
case KeyCode::Menu: return SDL_SCANCODE_APPLICATION;
case KeyCode::Up: return SDL_SCANCODE_UP;
case KeyCode::Down: return SDL_SCANCODE_DOWN;
case KeyCode::Left: return SDL_SCANCODE_LEFT;
case KeyCode::Right: return SDL_SCANCODE_RIGHT;
case KeyCode::Home: return SDL_SCANCODE_HOME;
case KeyCode::End: return SDL_SCANCODE_END;
case KeyCode::PageUp: return SDL_SCANCODE_PAGEUP;
case KeyCode::PageDown: return SDL_SCANCODE_PAGEDOWN;
case KeyCode::Comma: return SDL_SCANCODE_COMMA;
case KeyCode::Period: return SDL_SCANCODE_PERIOD;
case KeyCode::Semicolon: return SDL_SCANCODE_SEMICOLON;
case KeyCode::Apostrophe: return SDL_SCANCODE_APOSTROPHE;
case KeyCode::Slash: return SDL_SCANCODE_SLASH;
case KeyCode::Backslash: return SDL_SCANCODE_BACKSLASH;
case KeyCode::LeftBracket: return SDL_SCANCODE_LEFTBRACKET;
case KeyCode::RightBracket: return SDL_SCANCODE_RIGHTBRACKET;
case KeyCode::Minus: return SDL_SCANCODE_MINUS;
case KeyCode::Equal: return SDL_SCANCODE_EQUALS;
case KeyCode::Grave: return SDL_SCANCODE_GRAVE;
case KeyCode::World1: return SDL_SCANCODE_INTERNATIONAL1;
case KeyCode::World2: return SDL_SCANCODE_INTERNATIONAL2;
case KeyCode::Unknown:
default:
return SDL_SCANCODE_UNKNOWN;
}
}
enum class MouseCode : int {
Left,
Right,
Middle,
Button4,
Button5,
COUNT
};
inline MouseCode sdlButtonToMouseCode(Uint8 button) {
switch (button) {
case SDL_BUTTON_LEFT: return MouseCode::Left;
case SDL_BUTTON_RIGHT: return MouseCode::Right;
case SDL_BUTTON_MIDDLE: return MouseCode::Middle;
case SDL_BUTTON_X1: return MouseCode::Button4;
case SDL_BUTTON_X2: return MouseCode::Button5;
default: return MouseCode::Left; // fallback
}
}
enum CodeState {
PASSIVE,
DOWN,
UP,
HELD,
};
struct InputResource {
CodeState keys[static_cast<int>(KeyCode::COUNT)];
CodeState mouseKeys[static_cast<int>(MouseCode::COUNT)];
double mouseX = 0.0;
double mouseY = 0.0;
double mouseXPrevious = 0.0;
double mouseYPrevious = 0.0;
double mouseScrollX = 0.0;
double mouseScrollY = 0.0;
void disableAllKey() {
std::fill_n(keys, static_cast<int>(KeyCode::COUNT), CodeState::PASSIVE);
std::fill_n(mouseKeys, static_cast<int>(MouseCode::COUNT), CodeState::PASSIVE);
}
CodeState getKeyState(KeyCode keycode) {
return keys[static_cast<int>(keycode)];
}
CodeState getMouseState(MouseCode mousecode) {
return mouseKeys[static_cast<int>(mousecode)];
}
void updateKeyStates() {
for (int i = 0; i < static_cast<int>(KeyCode::COUNT); i++) {
switch (keys[i]) {
case CodeState::DOWN:
keys[i] = CodeState::HELD;
break;
case CodeState::UP:
keys[i] = CodeState::PASSIVE;
break;
default:
break;
}
}
for (int i = 0; i < static_cast<int>(MouseCode::COUNT); i++) {
switch (mouseKeys[i]) {
case CodeState::DOWN:
mouseKeys[i] = CodeState::HELD;
break;
case CodeState::UP:
mouseKeys[i] = CodeState::PASSIVE;
break;
default:
break;
}
}
}
void resetStuckKeys() {
for (int i = 0; i < static_cast<int>(KeyCode::COUNT); i++) {
if (keys[i] == CodeState::HELD) {
const Uint8* currentKeyState = SDL_GetKeyboardState(NULL);
SDL_Scancode scancode = keyCodeToSdlScancode(static_cast<KeyCode>(i));
if (scancode == SDL_SCANCODE_UNKNOWN) {
continue;
}
if (!currentKeyState[scancode]) {
keys[i] = CodeState::PASSIVE;
}
}
}
}
void disableKey(KeyCode key) {
int index = static_cast<int>(key);
if (keys[index] == CodeState::DOWN || keys[index] == CodeState::HELD) {
keys[index] = CodeState::UP;
}
}
void enableKey(KeyCode key) {
int index = static_cast<int>(key);
if (keys[index] == CodeState::PASSIVE || keys[index] == CodeState::UP) {
keys[index] = CodeState::DOWN;
}
}
void disableMouseKey(MouseCode key) {
int index = static_cast<int>(key);
if (mouseKeys[index] == CodeState::DOWN || mouseKeys[index] == CodeState::HELD) {
mouseKeys[index] = CodeState::UP;
}
}
void enableMouseKey(MouseCode key) {
int index = static_cast<int>(key);
if (mouseKeys[index] == CodeState::PASSIVE || mouseKeys[index] == CodeState::UP) {
mouseKeys[index] = CodeState::DOWN;
}
}
double getMouseDeltaX() const { return mouseX - mouseXPrevious; }
double getMouseDeltaY() const { return mouseY - mouseYPrevious; }
};
}
}