black background
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
# Compiler and flags
|
# Compiler and flags
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -std=c++17 -Wall -Wextra -O3
|
CXXFLAGS = -std=c++17 -Wall -Wextra -O3
|
||||||
LDFLAGS = -static -lncurses -ltinfo
|
LDFLAGS = -static
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
SRC_DIR = src
|
SRC_DIR = src
|
||||||
|
|||||||
@@ -15,9 +15,7 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int g_maxCells = 0;
|
int g_maxCells = 0;
|
||||||
|
|
||||||
// ANSI color codes
|
// ANSI color codes
|
||||||
namespace ANSI {
|
namespace ANSI {
|
||||||
const char *RESET = "\033[0m";
|
const char *RESET = "\033[0m";
|
||||||
@@ -26,7 +24,6 @@ const char *CLEAR_SCREEN = "\033[2J";
|
|||||||
const char *CURSOR_HOME = "\033[H";
|
const char *CURSOR_HOME = "\033[H";
|
||||||
const char *HIDE_CURSOR = "\033[?25l";
|
const char *HIDE_CURSOR = "\033[?25l";
|
||||||
const char *SHOW_CURSOR = "\033[?25h";
|
const char *SHOW_CURSOR = "\033[?25h";
|
||||||
|
|
||||||
// Colors (foreground)
|
// Colors (foreground)
|
||||||
const char *BLACK = "\033[30m";
|
const char *BLACK = "\033[30m";
|
||||||
const char *RED = "\033[31m";
|
const char *RED = "\033[31m";
|
||||||
@@ -36,7 +33,17 @@ const char *BLUE = "\033[34m";
|
|||||||
const char *MAGENTA = "\033[35m";
|
const char *MAGENTA = "\033[35m";
|
||||||
const char *CYAN = "\033[36m";
|
const char *CYAN = "\033[36m";
|
||||||
const char *WHITE = "\033[37m";
|
const char *WHITE = "\033[37m";
|
||||||
|
// Background colors
|
||||||
|
const char *BG_BLACK = "\033[40m";
|
||||||
|
const char *BG_RED = "\033[41m";
|
||||||
|
const char *BG_GREEN = "\033[42m";
|
||||||
|
const char *BG_YELLOW = "\033[43m";
|
||||||
|
const char *BG_BLUE = "\033[44m";
|
||||||
|
const char *BG_MAGENTA = "\033[45m";
|
||||||
|
const char *BG_CYAN = "\033[46m";
|
||||||
|
const char *BG_WHITE = "\033[47m";
|
||||||
|
// Combined reset with black background
|
||||||
|
const char *RESET_BLACK_BG = "\033[0;40m";
|
||||||
// Move cursor to position
|
// Move cursor to position
|
||||||
std::string moveTo(int row, int col) {
|
std::string moveTo(int row, int col) {
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
@@ -44,11 +51,9 @@ std::string moveTo(int row, int col) {
|
|||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
} // namespace ANSI
|
} // namespace ANSI
|
||||||
|
|
||||||
// Global terminal state
|
// Global terminal state
|
||||||
static struct termios original_termios;
|
static struct termios original_termios;
|
||||||
static bool termios_saved = false;
|
static bool termios_saved = false;
|
||||||
|
|
||||||
// Signal handler for cleanup
|
// Signal handler for cleanup
|
||||||
void cleanup_terminal(int sig) {
|
void cleanup_terminal(int sig) {
|
||||||
if (termios_saved) {
|
if (termios_saved) {
|
||||||
@@ -60,18 +65,15 @@ void cleanup_terminal(int sig) {
|
|||||||
exit(sig);
|
exit(sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Aquarium::Aquarium() {
|
Aquarium::Aquarium() {
|
||||||
// Save original terminal settings
|
// Save original terminal settings
|
||||||
if (tcgetattr(STDIN_FILENO, &original_termios) == 0) {
|
if (tcgetattr(STDIN_FILENO, &original_termios) == 0) {
|
||||||
termios_saved = true;
|
termios_saved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up signal handlers for cleanup
|
// Set up signal handlers for cleanup
|
||||||
signal(SIGINT, cleanup_terminal);
|
signal(SIGINT, cleanup_terminal);
|
||||||
signal(SIGTERM, cleanup_terminal);
|
signal(SIGTERM, cleanup_terminal);
|
||||||
signal(SIGQUIT, cleanup_terminal);
|
signal(SIGQUIT, cleanup_terminal);
|
||||||
|
|
||||||
// Set terminal to raw mode
|
// Set terminal to raw mode
|
||||||
struct termios raw = original_termios;
|
struct termios raw = original_termios;
|
||||||
raw.c_lflag &= ~(ECHO | ICANON | ISIG);
|
raw.c_lflag &= ~(ECHO | ICANON | ISIG);
|
||||||
@@ -79,37 +81,31 @@ Aquarium::Aquarium() {
|
|||||||
raw.c_oflag &= ~(OPOST);
|
raw.c_oflag &= ~(OPOST);
|
||||||
raw.c_cc[VMIN] = 0; // Non-blocking read
|
raw.c_cc[VMIN] = 0; // Non-blocking read
|
||||||
raw.c_cc[VTIME] = 1; // 100ms timeout
|
raw.c_cc[VTIME] = 1; // 100ms timeout
|
||||||
|
|
||||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
||||||
|
// Initialize display with black background
|
||||||
// Initialize display
|
printf("%s%s%s%s", ANSI::CLEAR_SCREEN, ANSI::CURSOR_HOME, ANSI::HIDE_CURSOR,
|
||||||
printf("%s%s%s", ANSI::CLEAR_SCREEN, ANSI::CURSOR_HOME, ANSI::HIDE_CURSOR);
|
ANSI::BG_BLACK);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Get terminal size
|
// Get terminal size
|
||||||
getTerminalSize();
|
getTerminalSize();
|
||||||
|
|
||||||
currentFrame.assign(height, std::vector<Cell>(width));
|
currentFrame.assign(height, std::vector<Cell>(width));
|
||||||
previousFrame.assign(height, std::vector<Cell>(width));
|
previousFrame.assign(height, std::vector<Cell>(width));
|
||||||
|
|
||||||
if (!colorLookupInitialized) {
|
if (!colorLookupInitialized) {
|
||||||
initColorLookup();
|
initColorLookup();
|
||||||
colorLookupInitialized = true;
|
colorLookupInitialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::getTerminalSize() {
|
void Aquarium::getTerminalSize() {
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
|
||||||
height = ws.ws_row;
|
height = ws.ws_row;
|
||||||
width = ws.ws_col;
|
width = ws.ws_col;
|
||||||
} else {
|
} else {
|
||||||
// Fallback to reasonable defaults
|
// Fallback
|
||||||
height = 24;
|
height = 24;
|
||||||
width = 80;
|
width = 80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::ensureEntitiesSorted() {
|
void Aquarium::ensureEntitiesSorted() {
|
||||||
if (entities_need_sorting) {
|
if (entities_need_sorting) {
|
||||||
std::sort(entities.begin(), entities.end(),
|
std::sort(entities.begin(), entities.end(),
|
||||||
@@ -123,23 +119,18 @@ void Aquarium::ensureEntitiesSorted() {
|
|||||||
entities_need_sorting = false;
|
entities_need_sorting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::redraw() {
|
void Aquarium::redraw() {
|
||||||
clearCurrentFrame();
|
clearCurrentFrame();
|
||||||
ensureBigEntityExists();
|
ensureBigEntityExists();
|
||||||
|
|
||||||
// Use static vectors to avoid per-frame allocations
|
// Use static vectors to avoid per-frame allocations
|
||||||
static std::vector<std::unique_ptr<Entity>> newEntities;
|
static std::vector<std::unique_ptr<Entity>> newEntities;
|
||||||
static std::vector<size_t> entitiesToRemove;
|
static std::vector<size_t> entitiesToRemove;
|
||||||
|
|
||||||
newEntities.clear();
|
newEntities.clear();
|
||||||
entitiesToRemove.clear();
|
entitiesToRemove.clear();
|
||||||
|
|
||||||
// Update all entities and collect changes
|
// Update all entities and collect changes
|
||||||
for (size_t i = 0; i < entities.size(); ++i) {
|
for (size_t i = 0; i < entities.size(); ++i) {
|
||||||
auto &entity = entities[i];
|
auto &entity = entities[i];
|
||||||
entity->update();
|
entity->update();
|
||||||
|
|
||||||
// Handle fish bubble spawning
|
// Handle fish bubble spawning
|
||||||
if (auto *fish = dynamic_cast<Fish *>(entity.get())) {
|
if (auto *fish = dynamic_cast<Fish *>(entity.get())) {
|
||||||
if (fish->shouldSpawnBubble()) {
|
if (fish->shouldSpawnBubble()) {
|
||||||
@@ -147,7 +138,6 @@ void Aquarium::redraw() {
|
|||||||
std::make_unique<Bubble>(fish->getX(), fish->getY()));
|
std::make_unique<Bubble>(fish->getX(), fish->getY()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity->shouldBeRemoved()) {
|
if (entity->shouldBeRemoved()) {
|
||||||
auto replacement = entity->createReplacement();
|
auto replacement = entity->createReplacement();
|
||||||
if (replacement) {
|
if (replacement) {
|
||||||
@@ -158,41 +148,33 @@ void Aquarium::redraw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove entities in reverse order to maintain indices
|
// Remove entities in reverse order to maintain indices
|
||||||
for (auto it = entitiesToRemove.rbegin(); it != entitiesToRemove.rend();
|
for (auto it = entitiesToRemove.rbegin(); it != entitiesToRemove.rend();
|
||||||
++it) {
|
++it) {
|
||||||
entities.erase(entities.begin() + *it);
|
entities.erase(entities.begin() + *it);
|
||||||
entities_need_sorting = true;
|
entities_need_sorting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new entities if we have them
|
// Add new entities if we have them
|
||||||
if (!newEntities.empty()) {
|
if (!newEntities.empty()) {
|
||||||
// Reserve space to minimize reallocations
|
// Reserve space to minimize reallocations
|
||||||
entities.reserve(entities.size() + newEntities.size());
|
entities.reserve(entities.size() + newEntities.size());
|
||||||
|
|
||||||
for (auto &newEntity : newEntities) {
|
for (auto &newEntity : newEntities) {
|
||||||
entities.emplace_back(std::move(newEntity));
|
entities.emplace_back(std::move(newEntity));
|
||||||
}
|
}
|
||||||
entities_need_sorting = true;
|
entities_need_sorting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureEntitiesSorted();
|
ensureEntitiesSorted();
|
||||||
|
|
||||||
// Draw all entities
|
// Draw all entities
|
||||||
for (const auto &entity : entities) {
|
for (const auto &entity : entities) {
|
||||||
entity->draw();
|
entity->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderToScreen();
|
renderToScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::resize() {
|
void Aquarium::resize() {
|
||||||
printf("%s%s", ANSI::CLEAR_SCREEN, ANSI::CURSOR_HOME);
|
// Clear screen and set black background
|
||||||
|
printf("%s%s%s", ANSI::CLEAR_SCREEN, ANSI::CURSOR_HOME, ANSI::BG_BLACK);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
getTerminalSize();
|
getTerminalSize();
|
||||||
|
|
||||||
if (g_maxCells && height * width > g_maxCells) {
|
if (g_maxCells && height * width > g_maxCells) {
|
||||||
cleanup_terminal(0);
|
cleanup_terminal(0);
|
||||||
std::cerr << "Error: Terminal too large. Maximum allowed area is "
|
std::cerr << "Error: Terminal too large. Maximum allowed area is "
|
||||||
@@ -200,13 +182,10 @@ void Aquarium::resize() {
|
|||||||
<< (height * width) << ".\n";
|
<< (height * width) << ".\n";
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentFrame.assign(height, std::vector<Cell>(width));
|
currentFrame.assign(height, std::vector<Cell>(width));
|
||||||
previousFrame.assign(height, std::vector<Cell>(width));
|
previousFrame.assign(height, std::vector<Cell>(width));
|
||||||
|
|
||||||
entities.clear();
|
entities.clear();
|
||||||
entities_need_sorting = true;
|
entities_need_sorting = true;
|
||||||
|
|
||||||
addWaterline();
|
addWaterline();
|
||||||
addCastle();
|
addCastle();
|
||||||
for (int i = 0; i < width / 15; i++)
|
for (int i = 0; i < width / 15; i++)
|
||||||
@@ -214,7 +193,6 @@ void Aquarium::resize() {
|
|||||||
for (int i = 0; i < width * (height - 9) / 350; i++)
|
for (int i = 0; i < width * (height - 9) / 350; i++)
|
||||||
addFish();
|
addFish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::addFish() { addEntityImpl<Fish>(); }
|
void Aquarium::addFish() { addEntityImpl<Fish>(); }
|
||||||
void Aquarium::addBubble(float x, float y) { addEntityImpl<Bubble>(x, y); }
|
void Aquarium::addBubble(float x, float y) { addEntityImpl<Bubble>(x, y); }
|
||||||
void Aquarium::addSeaweed() { addEntityImpl<Seaweed>(); }
|
void Aquarium::addSeaweed() { addEntityImpl<Seaweed>(); }
|
||||||
@@ -223,7 +201,6 @@ void Aquarium::addCastle() { addEntityImpl<Castle>(); }
|
|||||||
void Aquarium::addShip() { addEntityImpl<Ship>(); }
|
void Aquarium::addShip() { addEntityImpl<Ship>(); }
|
||||||
void Aquarium::addSeaMonster() { addEntityImpl<SeaMonster>(); }
|
void Aquarium::addSeaMonster() { addEntityImpl<SeaMonster>(); }
|
||||||
void Aquarium::addWhale() { addEntityImpl<Whale>(); }
|
void Aquarium::addWhale() { addEntityImpl<Whale>(); }
|
||||||
|
|
||||||
void Aquarium::ensureBigEntityExists() {
|
void Aquarium::ensureBigEntityExists() {
|
||||||
// Check if any big entities exist on screen
|
// Check if any big entities exist on screen
|
||||||
for (const auto &entity : entities) {
|
for (const auto &entity : entities) {
|
||||||
@@ -233,8 +210,7 @@ void Aquarium::ensureBigEntityExists() {
|
|||||||
return; // Big entity found, do nothing
|
return; // Big entity found, do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// No big entity found, spawn next in cycle
|
||||||
// No big entity found, spawn next in cycle (Ship, SeaMonster, Whale)
|
|
||||||
int entity_type = big_entity_index % 3;
|
int entity_type = big_entity_index % 3;
|
||||||
if (entity_type == 0) {
|
if (entity_type == 0) {
|
||||||
addEntityImpl<Ship>();
|
addEntityImpl<Ship>();
|
||||||
@@ -245,35 +221,28 @@ void Aquarium::ensureBigEntityExists() {
|
|||||||
}
|
}
|
||||||
++big_entity_index;
|
++big_entity_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::clearCurrentFrame() {
|
void Aquarium::clearCurrentFrame() {
|
||||||
for (auto &row : currentFrame) {
|
for (auto &row : currentFrame) {
|
||||||
std::fill(row.begin(), row.end(), Cell());
|
std::fill(row.begin(), row.end(), Cell());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::drawToFrame(int y, int x, const std::string &line,
|
void Aquarium::drawToFrame(int y, int x, const std::string &line,
|
||||||
const std::string &colorLine) {
|
const std::string &colorLine) {
|
||||||
const size_t len = std::min(line.size(), colorLine.size());
|
const size_t len = std::min(line.size(), colorLine.size());
|
||||||
|
|
||||||
for (size_t j = 0; j < len; ++j) {
|
for (size_t j = 0; j < len; ++j) {
|
||||||
int cx = x + static_cast<int>(j);
|
int cx = x + static_cast<int>(j);
|
||||||
if (cx < 0 || cx >= width)
|
if (cx < 0 || cx >= width)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char ch = line[j];
|
const char ch = line[j];
|
||||||
const char colorChar = colorLine[j];
|
const char colorChar = colorLine[j];
|
||||||
const bool isBold = (colorChar >= 'A' && colorChar <= 'Z');
|
const bool isBold = (colorChar >= 'A' && colorChar <= 'Z');
|
||||||
|
|
||||||
currentFrame[y][cx] = {
|
currentFrame[y][cx] = {
|
||||||
ch, static_cast<char>(isBold ? colorChar + 32 : colorChar), isBold};
|
ch, static_cast<char>(isBold ? colorChar + 32 : colorChar), isBold};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::initColorLookup() {
|
void Aquarium::initColorLookup() {
|
||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i)
|
||||||
colorLookup[i] = ANSI::BLACK; // Default black
|
colorLookup[i] = ANSI::BLACK; // Default black
|
||||||
|
|
||||||
colorLookup['r'] = ANSI::RED;
|
colorLookup['r'] = ANSI::RED;
|
||||||
colorLookup['g'] = ANSI::GREEN;
|
colorLookup['g'] = ANSI::GREEN;
|
||||||
colorLookup['y'] = ANSI::YELLOW;
|
colorLookup['y'] = ANSI::YELLOW;
|
||||||
@@ -283,48 +252,34 @@ void Aquarium::initColorLookup() {
|
|||||||
colorLookup['w'] = ANSI::WHITE;
|
colorLookup['w'] = ANSI::WHITE;
|
||||||
colorLookup['k'] = ANSI::BLACK;
|
colorLookup['k'] = ANSI::BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquarium::initColors() {
|
|
||||||
// This function is kept for compatibility but does nothing
|
|
||||||
// since we're using ANSI colors directly
|
|
||||||
}
|
|
||||||
|
|
||||||
void Aquarium::renderToScreen() {
|
void Aquarium::renderToScreen() {
|
||||||
static std::string output;
|
static std::string output;
|
||||||
output.clear();
|
output.clear();
|
||||||
output.reserve(height * width * 20); // Reserve space for efficiency
|
output.reserve(height * width * 20); // Reserve space for efficiency
|
||||||
|
|
||||||
for (int y = 0; y < height; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
const Cell &newCell = currentFrame[y][x];
|
const Cell &newCell = currentFrame[y][x];
|
||||||
Cell &oldCell = previousFrame[y][x];
|
Cell &oldCell = previousFrame[y][x];
|
||||||
|
|
||||||
if (newCell != oldCell) {
|
if (newCell != oldCell) {
|
||||||
oldCell = newCell;
|
oldCell = newCell;
|
||||||
|
|
||||||
// Move cursor to position
|
// Move cursor to position
|
||||||
output += ANSI::moveTo(y, x);
|
output += ANSI::moveTo(y, x);
|
||||||
|
// Set color and attributes with black background
|
||||||
// Set color and attributes
|
output += ANSI::RESET_BLACK_BG; // Reset with black background
|
||||||
output += ANSI::RESET; // Reset first
|
|
||||||
if (newCell.bold) {
|
if (newCell.bold) {
|
||||||
output += ANSI::BOLD;
|
output += ANSI::BOLD;
|
||||||
}
|
}
|
||||||
output += colorLookup[static_cast<unsigned char>(newCell.colorChar)];
|
output += colorLookup[static_cast<unsigned char>(newCell.colorChar)];
|
||||||
|
|
||||||
// Add the character
|
// Add the character
|
||||||
output += newCell.ch;
|
output += newCell.ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Output everything at once
|
||||||
// Output everything at once for better performance
|
|
||||||
if (!output.empty()) {
|
if (!output.empty()) {
|
||||||
printf("%s", output.c_str());
|
std::cout << output << std::flush;
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for input (non-blocking)
|
// Check for input (non-blocking)
|
||||||
int Aquarium::checkInput() {
|
int Aquarium::checkInput() {
|
||||||
char c;
|
char c;
|
||||||
@@ -333,8 +288,7 @@ int Aquarium::checkInput() {
|
|||||||
}
|
}
|
||||||
return -1; // No input available
|
return -1; // No input available
|
||||||
}
|
}
|
||||||
|
// Check if terminal was resized
|
||||||
// Check if terminal was resized (you'll need to call this periodically)
|
|
||||||
bool Aquarium::checkResize() {
|
bool Aquarium::checkResize() {
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
|
||||||
@@ -344,5 +298,4 @@ bool Aquarium::checkResize() {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Aquarium::~Aquarium() { cleanup_terminal(0); }
|
Aquarium::~Aquarium() { cleanup_terminal(0); }
|
||||||
|
|||||||
13
src/main.cpp
13
src/main.cpp
@@ -1,18 +1,11 @@
|
|||||||
// main.cpp
|
// main.cpp
|
||||||
#include "Aquarium.h"
|
#include "Aquarium.h"
|
||||||
#ifdef __OpenBSD__
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#include <chrono>
|
|
||||||
#include <iostream>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// Get the singleton instance
|
// Get the singleton instance
|
||||||
Aquarium &aquarium = Aquarium::getInstance();
|
Aquarium &aquarium = Aquarium::getInstance();
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
// Most restrictive pledge - no file access needed!
|
|
||||||
if (pledge("stdio tty", NULL) == -1) {
|
if (pledge("stdio tty", NULL) == -1) {
|
||||||
perror("pledge");
|
perror("pledge");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -24,22 +17,16 @@ int main() {
|
|||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (true) {
|
while (true) {
|
||||||
// Check for user input
|
|
||||||
int input = aquarium.checkInput();
|
int input = aquarium.checkInput();
|
||||||
if (input == 'q' || input == 'Q' || input == 27) { // ESC key
|
if (input == 'q' || input == 'Q' || input == 27) { // ESC key
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if terminal was resized
|
|
||||||
if (aquarium.checkResize()) {
|
if (aquarium.checkResize()) {
|
||||||
aquarium.resize();
|
aquarium.resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redraw the aquarium
|
|
||||||
aquarium.redraw();
|
aquarium.redraw();
|
||||||
|
|
||||||
// Control frame rate (~20 FPS)
|
|
||||||
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user