From 9bde54a7c3922c2e325748b8e5591a00bf439980 Mon Sep 17 00:00:00 2001 From: roy Date: Thu, 25 Jun 2026 19:29:23 +0300 Subject: Initial commit --- .gitignore | 2 + terminal-game-utils.hpp | 178 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 .gitignore create mode 100644 terminal-game-utils.hpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14004c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +debug.cpp +debug diff --git a/terminal-game-utils.hpp b/terminal-game-utils.hpp new file mode 100644 index 0000000..0e41074 --- /dev/null +++ b/terminal-game-utils.hpp @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace TGU { + +inline struct termios orig_termios; + +inline std::string newline = "\n\r"; + +enum class GameKey { + INVALID, + LEFTARROW, + DOWNARROW, + UPARROW, + RIGHTARROW, + ESCAPE, + 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, + SPACE, +}; + +inline std::map KeyMap = {{"a", GameKey::A}, + {"b", GameKey::B}, + {"c", GameKey::C}, + {"d", GameKey::D}, + {"e", GameKey::E}, + {"f", GameKey::F}, + {"g", GameKey::G}, + {"h", GameKey::H}, + {"i", GameKey::I}, + {"j", GameKey::J}, + {"k", GameKey::K}, + {"l", GameKey::L}, + {"m", GameKey::M}, + {"n", GameKey::N}, + {"o", GameKey::O}, + {"p", GameKey::P}, + {"q", GameKey::Q}, + {"r", GameKey::R}, + {"s", GameKey::S}, + {"t", GameKey::T}, + {"u", GameKey::U}, + {"v", GameKey::V}, + {"w", GameKey::W}, + {"x", GameKey::X}, + {"y", GameKey::Y}, + {"z", GameKey::Z}, + {"A", GameKey::A}, + {"B", GameKey::B}, + {"C", GameKey::C}, + {"D", GameKey::D}, + {"E", GameKey::E}, + {"F", GameKey::F}, + {"G", GameKey::G}, + {"H", GameKey::H}, + {"I", GameKey::I}, + {"J", GameKey::J}, + {"K", GameKey::K}, + {"L", GameKey::L}, + {"M", GameKey::M}, + {"N", GameKey::N}, + {"O", GameKey::O}, + {"P", GameKey::P}, + {"Q", GameKey::Q}, + {"R", GameKey::R}, + {"S", GameKey::S}, + {"T", GameKey::T}, + {"U", GameKey::U}, + {"V", GameKey::V}, + {"W", GameKey::W}, + {"X", GameKey::X}, + {"Y", GameKey::Y}, + {"Z", GameKey::Z}, + {"\x1b", GameKey::ESCAPE}, + {"\x1b[D", GameKey::LEFTARROW}, + {"\x1b[B", GameKey::DOWNARROW}, + {"\x1b[A", GameKey::UPARROW}, + {"\x1b[C", GameKey::RIGHTARROW}, + {" ", GameKey::SPACE}}; + +inline void DisableRawMode() { tcsetattr(0, TCSAFLUSH, &orig_termios); } + +inline void EnableRawMode() { + + tcgetattr(0, &orig_termios); + + atexit(DisableRawMode); + struct termios raw = orig_termios; + raw.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON); + raw.c_oflag &= ~(OPOST); + raw.c_cflag |= (CS8); + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN); + raw.c_cc[VMIN] = 1; + raw.c_cc[VTIME] = 0; + + tcsetattr(0, TCSAFLUSH, &raw); +} + +inline bool InputAvailable(int timeout_ms) { + pollfd pfd{}; + pfd.fd = STDIN_FILENO; + pfd.events = POLLIN; + + return poll(&pfd, 1, timeout_ms) > 0; +} + +inline GameKey GetKeyPress() { + std::string keypress_string; + char c; + + read(STDIN_FILENO, &c, 1); + keypress_string += c; + + if (c == 27) + while (InputAvailable(10)) { + read(STDIN_FILENO, &c, 1); + keypress_string += c; + } + + if (KeyMap.count(keypress_string)) + return KeyMap[keypress_string]; + + return KeyMap[keypress_string]; +} + +// Terminal color printers: + +inline void TextGreen() { std::cout << "\033[32m"; } + +inline void TextRed() { std::cout << "\033[31m"; } + +inline void TextBlue() { std::cout << "\033[34m"; } + +inline void TextReset() { std::cout << "\033[0m"; } + +inline void TextRGB(int r, int g, int b) { + std::cout << std::format("\033[38;2;{};{};{}m", r, g, b); +}; + +// Game buffer printers: + +inline void EnterGameBuffer() { std::cout << "\033[?1049h"; } + +inline void LeaveGameBuffer() { std::cout << "\033[?1049l"; } + +inline void MoveCursor(int row, int col) { + std::cout << "\033[" << row << ";" << col << "H" << std::flush; +} +}; // namespace TGU -- cgit v1.3.1