Conway's game of life simulator made in SkeletonGL & C++ with a focus on performance
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

790 lines
27 KiB

// Author: XENOBYTE.XYZ
// License: MIT License
// Website: https://xenobyte.xyz/projects/?nav=skeletongl
#include "window.hpp"
int Window::createSGLWindow()
{
_upWindowManager = std::make_unique<SGL_Window>();
SGL_Log("Creating window...");
try
{
_upWindowManager->initializeWindow(0, 0, 640, 360, 640/4, 360/3, "CAS-SGL", false, std::string("skeletongl.ini"));
_upWindowManager->checkForErrors();
}
catch (SGL_Exception &e)
{
SGL_Log("Aborting window creation.");
SGL_Log(e.what());
assert(false);
return -1;
}
SGL_Log("Window ready.");
return 0;
}
Window::Window()
{
createSGLWindow();
SGL_Log("Starting SkeletonGL");
// Console testing
this->_console = std::make_unique<DebugConsole>();
_debugPanel = false;
_textMode = false;
_drawConsole = false;
_debugBG = std::make_unique<SGL_Sprite>();
_debugBG->position = glm::vec2(0, 0);
_debugBG->texture = _upWindowManager->assetManager->getTexture(SGL::SQUARE_TEXTURE);
_debugBG->size = glm::vec2(_upWindowManager->getWindowCreationSpecs().internalW, (_upWindowManager->getWindowCreationSpecs().internalH));
_debugBG->color = SGL_Color(0.0f, 0.0f, 0.0f, 0.70f);
_debugBG->blending = BLENDING_TYPE::DEFAULT_RENDERING;
_debugBG->shader = _upWindowManager->assetManager->getShader(SGL::DEFAULT_SPRITE_SHADER);
_debugBG->resetUVCoords();
}
Window::~Window()
{
SGL_Log("Exiting.");
}
void Window::mainLoop()
{
_upWindowManager->assetManager->loadTexture("assets/textures/avatar.png", true, "avatar");
// GAME STATE
_paused = false;
_mainLoopActive = true;
// Camera
_cameraZoom = 1.0f;
_paused = false;
_seed = {0};
_monoColor = SGL_Color(0.30f, 1.0f, 0.10f, 1.0f);
_monoColor = SGL_Color(0.99f, 0.99f, 0.99f, 1.0f);
_saveFile = "seed.txt";
// Cell pixel
pixel = std::make_shared<SGL_Sprite>();
pixel->texture = _upWindowManager->assetManager->getTexture(SGL::SQUARE_TEXTURE);
//pixel->shader = pWindowManager->assetManager->getShader("customSprite");
pixel->resetUVCoords();
pixel->color = _monoColor;
pixel->size.x = 1;
pixel->size.y = 1;
// BMP font
text = std::make_shared<SGL_Bitmap_Text>();
text->texture = _upWindowManager->assetManager->getTexture(SGL::DEFAULT_BMP_FONT_TEXTURE);
text->color = {1.0, 1.0, 1.0, 1.0};
text->position.x = 10;
text->position.y = 0;
text->scale = 8;
text->text = "cell-auto";
// Instanciate the sim nerd pointer
_CAS = std::make_shared<CellAutoSimulation>();
// Set the initial seed
// Bill Gosper's glider gun
_CAS->setCell(25, 45, "........................#............");
_CAS->setCell(25, 46, "......................#.#............");
_CAS->setCell(25, 47, "............##......##............##.");
_CAS->setCell(25, 48, "...........#...#....##............##.");
_CAS->setCell(25, 49, "##........#.....#...##...............");
_CAS->setCell(25, 50, "##........#...#.##....#.#............");
_CAS->setCell(25, 51, "..........#.....#.......#............");
_CAS->setCell(25, 52, "...........#...#.....................");
_CAS->setCell(25, 53, "............##.......................");
// Must be called before entering the game loop to properly initialize
// the post processor's FBO
this->_upWindowManager->setClearColor(SGL_Color(0.0f, 0.0f, 0.0f, 1.0f));
while (_mainLoopActive)
{
_fts.frameStart();
// Update the FPS string in the window title
std::string str = "CAS-SGL - FPS: " + std::to_string(_fts._FPS);
_upWindowManager->setWindowTitle(str);
this->input();
while ( _fts.consumeUpdateCycle() > 0)
this->update();
// Must be called as soon as the render frame starts to properly calculate delta time values and initiate the postprocessor FBO
//this->update();
this->_upWindowManager->startFrame();
this->render();
this->_upWindowManager->endFrame();
this->_upWindowManager->checkForErrors();
}
SGL_Log("Exiting main loop");
}
void Window::render()
{
_upWindowManager->setCameraMode(CAMERA_MODE::DEFAULT);
// Render simulation bounds
std::uint16_t x, y, w, h;
x = 2;
y = 10;
w = SIMULATION_WIDTH * pixel->size.x;
h = SIMULATION_HEIGHT * pixel->size.y;;
// Top boundary
_upWindowManager->renderer->renderLine(x, y, x+w, y, 1.0, SGL_Color(1.0f, 1.0f, 0.0f, 1.0f));
// Bottom boundary
_upWindowManager->renderer->renderLine(x, y+h, x+w, y+h, 1.0, SGL_Color(1.0f, 1.0f, 0.0f, 1.0f));
// Left boundary
_upWindowManager->renderer->renderLine(x, y, x, y+h, 1.0, SGL_Color(1.0f, 1.0f, 0.0f, 1.0f));
// Right boundary
_upWindowManager->renderer->renderLine(x+w, y, x+w, y+h, 1.0, SGL_Color(1.0f, 1.0f, 0.0f, 1.0f));
_spriteBatchData.clear();
for (std::uint16_t i = 0; i < _CAS->getTotalActiveCells(); ++i)
{
std::pair<std::uint16_t, std::uint16_t> activeCell = _CAS->getActiveCell(i);
glm::mat4 model{1.0f};
model = glm::translate(model, glm::vec3(activeCell.first + x, activeCell.second + y, 0.0f)); //move
_spriteBatchData.emplace_back(model);
}
_upWindowManager->renderer->renderSpriteBatch(*pixel, &_spriteBatchData);
// Render text
text->text = "CAS-SGL: Game of Life Simulator";
text->position.x = x;
text->position.y = y - 8;
text->scale = 4;
text->color = SGL_Color(0.80f, 0.20f, 0.20f, 1.0f);
_upWindowManager->renderer->renderBitmapText(*text);
if (_generating)
text->text = "-- generating -- ";
else
text->text = "-- running -- ";
if (_paused)
text->text = "-- paused -- ";
text->position.x = x;
text->position.y = y - 4;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
if (_generating)
{
text->text = "SEEDING...";
text->position.x = x + 20;
text->position.y = y + 38;
text->scale = 6;
text->color = SGL_Color(0.9, 0.2, 0.2, 1.0f);
_upWindowManager->renderer->renderBitmapText(*text);
}
// Sim data
text->text = "SIMULATION";
text->position.x = x+w;
text->position.y = y;
text->scale = 4;
text->color = SGL_Color(0.10, 0.8, 0.90, 1.0);
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "CELLS: " + std::to_string(_spriteBatchData.size());
text->position.x = x+w;
text->position.y = y+4;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "FPS: " + std::to_string(_fts._FPS);
text->position.x = x+w;
text->position.y = y+8;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
// Trim all but the first decimal
std::string timeElapsedStr = std::to_string(_fts._timeElapsed / 1000);
timeElapsedStr.erase(timeElapsedStr.find('.') + 2, timeElapsedStr.back());
text->text = "Time: " + timeElapsedStr;
text->position.x = x+w;
text->position.y = y+12;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "HZ: " + std::to_string(_CAS->getIterations());
text->position.x = x+w;
text->position.y = y+16;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
std::string seedStr = std::to_string(_seed.size());
text->text = seedStr;
text->position.x = x + w;
text->position.y = y-8;
text->scale = 4;
text->color = _monoColor;
// Instructions
y += 30;
text->text = "CONTROLS";
text->position.x = x + w;
text->position.y = y -4;
text->scale = 4;
text->color = SGL_Color(0.10, 0.8, 0.90, 1.0);
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "spc - pause";
text->position.x = x + w;
text->position.y = y;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
text->text = " s - save";
text->position.x = x + w;
text->position.y = y + 4;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
text->text = " l - load";
text->position.x = x + w;
text->position.y = y + 8;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "1:9 - reset";
text->position.x = x + w;
text->position.y = y + 12;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
// XENOBYTE logo
y = SIMULATION_HEIGHT - 20;
text->text = "VISIT";
text->position.x = x + w;
text->position.y = y;
text->scale = 4;
text->color = SGL_Color(0.90, 0.2, 0.2, 1.0);
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "XENOBYTE.XYZ";
text->position.x = x + w;
text->position.y = y + 4;
text->scale = 4;
text->color = _monoColor;
_upWindowManager->renderer->renderBitmapText(*text);
text->text = "4 MORE";
text->position.x = x + w;
text->position.y = y + 8;
text->scale = 4;
text->color = SGL_Color(0.90, 0.2, 0.2, 1.0);
_upWindowManager->renderer->renderBitmapText(*text);
// Render system messages
if ( _msgTime > 0.0)
{
text->text = _displayMsg;
text->position.x = x;
text->position.y = SIMULATION_HEIGHT + 11;
text->scale = 4;
text->color = SGL_Color(0.90, 0.9, 0.90, _msgTime);
_upWindowManager->renderer->renderBitmapText(*text);
}
if (_debugPanel)
{
_upWindowManager->setCameraMode(CAMERA_MODE::OVERLAY);
drawDebugPanel(4, 4, 0.06f, SGL_Color{1.0f, 1.0f, 1.0f, 1.0f});
_upWindowManager->setCameraMode(CAMERA_MODE::DEFAULT);
}
if (_drawConsole)
{
_upWindowManager->setCameraMode(CAMERA_MODE::OVERLAY);
drawConsole(4, 4, 0.06f, SGL_Color{1.0f, 1.0f, 1.0f, 1.0f});
_upWindowManager->setCameraMode(CAMERA_MODE::DEFAULT);
}
}
void Window::update()
{
processCommands();
if (!_paused)
_CAS->update();
if (_msgTime > 0.0)
_msgTime -= _fts._deltaTimeMS;
_upWindowManager->setCameraMode(CAMERA_MODE::DEFAULT);
_upWindowManager->setCameraPosition(glm::vec2(_upWindowManager->getWindowCreationSpecs().internalW / 2, _upWindowManager->getWindowCreationSpecs().internalH / 2));
_upWindowManager->setCameraScale(_cameraZoom);
//update the internal offset matrix for rendering
_upWindowManager->updateCamera();
}
void Window::input()
{
SGL_InputFrame input = _upWindowManager->getFrameInput();
if (input.esc.pressed && !_deltaInput.esc.pressed)
_mainLoopActive = false;
if (input.ctrl.pressed && !_deltaInput.ctrl.pressed)
{
_textMode = true;
_drawConsole = true;
_debugPanel = false;
}
if (input.shift.pressed && !_deltaInput.shift.pressed)
{
_textMode = false;
_drawConsole = false;
}
// ---
_generating = false;
// If text mode is enabled reroute all keyboard input here
if (this->_textMode)
this->_console->input(input, this->_deltaInput);
else
{
if (input.v.pressed && !_deltaInput.v.pressed)
_upWindowManager->toggleVSYNC(true);
if (input.c.pressed && !_deltaInput.c.pressed)
_upWindowManager->toggleVSYNC(false);
if (input.f.pressed && !_deltaInput.f.pressed)
this->_upWindowManager->toggleFullScreen(true);
if (input.g.pressed && !_deltaInput.g.pressed)
this->_upWindowManager->toggleFullScreen(false);
if (input.z.pressed && !_deltaInput.z.pressed)
_cameraZoom -= 0.02;
if (input.x.pressed && !_deltaInput.x.pressed)
_cameraZoom += 0.02;
if (input.c.pressed && !_deltaInput.c.pressed)
_cameraZoom = 1.0;
if (input.b.pressed && !_deltaInput.b.pressed)
_debugPanel = !_debugPanel;
// CAS
if (input.num1.pressed && !_deltaInput.num1.pressed)
{
_msgTime = 4.0;
_displayMsg = "Bill Gosper glider gun";
_CAS->resetSimulation();
// Bill Gosper's glider gun
_CAS->setCell(25, 45, "........................#............");
_CAS->setCell(25, 46, "......................#.#............");
_CAS->setCell(25, 47, "............##......##............##.");
_CAS->setCell(25, 48, "...........#...#....##............##.");
_CAS->setCell(25, 49, "##........#.....#...##...............");
_CAS->setCell(25, 50, "##........#...#.##....#.#............");
_CAS->setCell(25, 51, "..........#.....#.......#............");
_CAS->setCell(25, 52, "...........#...#.....................");
_CAS->setCell(25, 53, "............##.......................");
_seed = {0};
_simulationTime = 0.0;
_generating = true;
// randomizeSeed(1);
}
if (input.num2.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 2";
randomizeSeed(2);
}
if (input.num3.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 3";
randomizeSeed(3);
}
if (input.num4.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 4";
randomizeSeed(4);
}
if (input.num5.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 5";
randomizeSeed(5);
}
if (input.num6.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 6";
randomizeSeed(6);
}
if (input.num7.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 7";
randomizeSeed(7);
}
if (input.num8.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 8";
randomizeSeed(8);
}
if (input.num9.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 9";
randomizeSeed(9);
}
// Reset the simulation with randomized values
if (input.r.pressed)
{
_msgTime = 4.0;
_displayMsg = "Randomizing seed with 1 in 9";
randomizeSeed(9);
}
if (input.space.pressed && !_deltaInput.space.pressed)
_paused = !_paused;
// Save the generated seed to a file & make short pause
if (input.s.pressed && !_deltaInput.s.pressed)
{
if (!_seed.empty())
{
if (saveSeed(_saveFile))
{
std::this_thread::sleep_for(std::chrono::milliseconds(300));
_msgTime = 4.0;
_displayMsg = "Seed saved to ./seed.txt";
SGL_Log("Seed saved to ./seed.txt");
}
else
{
throw std::runtime_error("Error saving to ./seed.txt");
SGL_Log("Error saving to ./seed.txt");
}
}
}
// Load the contents of the save file
if (input.l.pressed && !_deltaInput.l.pressed)
{
if (loadSeed(_saveFile))
{
std::this_thread::sleep_for(std::chrono::milliseconds(300));
_msgTime = 4.0;
_displayMsg = "Seed loaded from ./seed.txt";
SGL_Log("Seed loaded from ./seed.txt");
}
else
{
SGL_Log("Error loading ./seed.txt");
throw std::runtime_error("Error loading ./seed.txt");
}
}
}
if (input.mouse.leftBtn.pressed)
{
SGL_Log("mouse left pressed");
_mouseLBHeld = true;
}
if (input.mouse.leftBtn.released)
{
_mouseLBHeld = false;
SGL_Log("mouse left released");
}
if (input.mouse.rightBtn.pressed)
{
SGL_Log("mouse right pressed");
_mouseRBHeld = true;
}
if (input.mouse.rightBtn.released)
{
_mouseRBHeld = false;
SGL_Log("mouse right released");
}
if (input.mouse.middleBtn.pressed)
{
SGL_Log("mouse wheel pressed");
_mouseMidHeld = true;
}
if (input.mouse.middleBtn.released)
{
_mouseMidHeld = false;
SGL_Log("mouse wheel released");
}
if (input.mouse.scrollUp.pressed)
{
SGL_Log("mouse wheel scroll up");
_mouseScrollUp = true;
_mouseScrollDown = false;
}
if (input.mouse.scrollUp.released)
{
_mouseScrollUp = false;
SGL_Log("mouse wheel scroll up");
}
if (input.mouse.scrollDown.pressed)
{
SGL_Log("mouse wheel scroll down");
_mouseScrollDown = true;
_mouseScrollUp = false;
}
if (input.mouse.scrollDown.released)
{
_mouseScrollDown = false;
SGL_Log("mouse wheel scroll down");
}
_deltaInput = input;
}
// Renders the embedded console
void Window::drawConsole(float x, float y, float fontSize, SGL_Color color)
{
float offset = (fontSize * 100) / 2;
// Background image
this->_upWindowManager->renderer->renderSprite((*_debugBG));
for (int i = 35; i >= 1; --i)
{
_upWindowManager->renderer->renderText(SGL_LOG_HISTORY[SGL_LOG_HISTORY.size() - i], x, y + (offset * (35.0f - i)), fontSize, color);
}
// _upWindowManager->renderer->renderText("/"+this->_textInputCache, left, y + (offset * (40.0f)), fontSize, color);
if (_textMode)
_upWindowManager->renderer->renderText("-> "+this->_console->inputStr(), x, y + (offset * (35.0f)), fontSize, SGL_Color(0.8f, 0.8f, 0.8f, 1.0f));
else
_upWindowManager->renderer->renderText("-> "+this->_console->inputStr(), x, y + (offset * (35.0f)), fontSize, color);
}
// Renders an overaly panel with debugging data
void Window::drawDebugPanel(float x, float y, float fontSize, SGL_Color color)
{
float offset = (fontSize * 100) / 2;
SGL_Color titleColor = {1.0f, 0.30f, 0.30f, 1.0f};
SGL_Color subTitleColor = {0.30f, 1.0f, 0.30f, 1.0f};
int center = (_upWindowManager->getWindowCreationSpecs().internalW / 2) - (x * 10);
int left = x;
int right = (_upWindowManager->getWindowCreationSpecs().internalW) - (x * 20);
int spacing = offset * 8;
WindowCreationSpecs windowSpecs = _upWindowManager->getWindowCreationSpecs();
std::stringstream textureMem;
std::string timeElapsedStr = std::to_string(_fts._timeElapsed / 1000);
std::string mouseWheel = "LAST SCROLL: ---";
if (_mouseScrollUp)
mouseWheel = "LAST SCROLL: SCROLL-UP";
if (_mouseScrollDown)
mouseWheel = "LAST SCROLL: SCROLL-DOWN";
timeElapsedStr.erase(timeElapsedStr.find('.') + 2, timeElapsedStr.back());
// Background image
this->_upWindowManager->renderer->renderSprite((*_debugBG));
textureMem << "GPU Texture Memory (MB): " << (static_cast<float>(_upWindowManager->assetManager->getTextureMemoryGPU()) / 1024) / 1024;
// Title
_upWindowManager->renderer->renderText("SkeletonGL Debug Panel", left, y, fontSize, titleColor);
// Left
_upWindowManager->renderer->renderText("--- WINDOW ---", left, y + (offset * 1.0f), fontSize, subTitleColor);
_upWindowManager->renderer->renderText("Host OS: " + _upWindowManager->hostData->hostOS, left, y + (offset * 2.0f), fontSize, color);
_upWindowManager->renderer->renderText("Display resolution: " + std::to_string(_upWindowManager->getWindowCreationSpecs().currentW) + " x " +
std::to_string(_upWindowManager->getWindowCreationSpecs().currentH),
left, y + (offset * 3.0f), fontSize, color);
_upWindowManager->renderer->renderText("Internal resolution: " + std::to_string(_upWindowManager->getWindowCreationSpecs().internalW) + " x " +
std::to_string(_upWindowManager->getWindowCreationSpecs().internalH),
left, y + (offset * 4.0f), fontSize, color);
_upWindowManager->renderer->renderText((_upWindowManager->hasKeyboardFocus() ? "Focused: YES" : "Focused: NO"), left, y + (offset * 5.0f), fontSize, color);
_upWindowManager->renderer->renderText((windowSpecs.fullScreen ? "Fullscreen: YES" : "Fullscreen: NO"), left, y + (offset * 6.0f), fontSize, color);
_upWindowManager->renderer->renderText((windowSpecs.activeVSYNC ? "VSYNC: YES" : "VSYNC: NO"), left, y + (offset * 7.0f), fontSize, color);
_upWindowManager->renderer->renderText((_textMode ? "Console: ON" : "Console: OFF"), left, y + (offset * 8.0f), fontSize, color);
_upWindowManager->renderer->renderText("Console History: " + std::to_string(_console->historySize()), left, y + (offset * 9.0f), fontSize, color);
_upWindowManager->renderer->renderText("--- ENGINE STATUS ---", left, y + (offset * 10.0f), fontSize, subTitleColor);
_upWindowManager->renderer->renderText("FPS: " + std::to_string(_fts._FPS), left, y + (offset * 11.0f), fontSize, color);
_upWindowManager->renderer->renderText("Physics delta time: " + std::to_string(_fts._deltaTimeMS), left, y + (offset * 12.0f), fontSize, color);
_upWindowManager->renderer->renderText("Render delta time: " + std::to_string(_upWindowManager->getRenderDeltaTime()), left, y + (offset * 13.0f), fontSize, color);
_upWindowManager->renderer->renderText("Time elapsed: " + timeElapsedStr, left, y + (offset * 14.0f), fontSize, color);
_upWindowManager->renderer->renderText("Target FPS: " + std::to_string(_fts._fixedTimeStepMS) + "ms / " + std::to_string(_fts._targetFPS) + "fps", left, y + (offset * 15.0f), fontSize, color);
_upWindowManager->renderer->renderText(textureMem.str(), left, y + (offset * 16.0f), fontSize, color);
_upWindowManager->renderer->renderText("--- CAMERA ---", left, y + (offset * 17.0f), fontSize, subTitleColor);
_upWindowManager->renderer->renderText("X: " + std::to_string(_upWindowManager->getCameraPosX()), left, y + (offset * 18.0f), fontSize, color);
_upWindowManager->renderer->renderText("Y: " + std::to_string(_upWindowManager->getCameraPosY()), left + spacing, y + (offset * 18.0f), fontSize, color);
_upWindowManager->renderer->renderText("W: " + std::to_string(_upWindowManager->getCameraPosW()), left, y + (offset * 19.0f), fontSize, color);
_upWindowManager->renderer->renderText("H: " + std::to_string(_upWindowManager->getCameraPosH()), left + spacing, y + (offset * 19.0f), fontSize, color);
_upWindowManager->renderer->renderText("Zoom: " + std::to_string(_cameraZoom), left, y + (offset * 20.0f), fontSize, color);
_upWindowManager->renderer->renderText("--- MOUSE ---", left, y + (offset * 21.0f), fontSize, subTitleColor);
_upWindowManager->renderer->renderText("X: " + std::to_string(_deltaInput.mouse.cursorX),
left, y + (offset * 22.0f), fontSize, color);
_upWindowManager->renderer->renderText("Y: " + std::to_string(_deltaInput.mouse.cursorY),
left + spacing, y + (offset * 22.0f), fontSize, color);
_upWindowManager->renderer->renderText("NX: " + std::to_string(_deltaInput.mouse.cursorXNormalized),
left, y + (offset * 23.0f), fontSize, color);
_upWindowManager->renderer->renderText("NY: " + std::to_string(_deltaInput.mouse.cursorYNormalized),
left + spacing, y + (offset * 23.0f), fontSize, color);
_upWindowManager->renderer->renderText((this->_mouseLBHeld ? "L: PRESSED" : "L: RELEASED"), left, y + (offset * 24.0f), fontSize, color);
_upWindowManager->renderer->renderText((this->_mouseRBHeld ? "R: PRESSED" : "R: RELEASED"), left, y + (offset * 25.0f), fontSize, color);
_upWindowManager->renderer->renderText((this->_mouseMidHeld ? "M: PRESSED" : "M: RELEASED"), left, y + (offset * 26.0f), fontSize, color);
_upWindowManager->renderer->renderText(mouseWheel, left, y + (offset * 27.0f), fontSize, color);
}
void Window::processCommands()
{
std::string cmd = std::move(this->_console->lastCommand());
if (cmd == "/exit")
this->_mainLoopActive = false;
}
void Window::randomizeSeed(std::uint8_t freq)
{
if (freq > 9)
freq = 9;
if (freq <= 0)
freq = 2;
_seed = {0};
for (std::uint16_t i = 0; i < (SIMULATION_WIDTH * SIMULATION_HEIGHT); ++i)
{
if ((rand() % freq) == 1)
_seed[i] = 1;
else
_seed[i] = 0;
}
reset();
}
void Window::reset()
{
_CAS->resetSimulation();
for (std::uint16_t i = 0; i < (SIMULATION_WIDTH * SIMULATION_HEIGHT); ++i)
{
if (_seed[i] == 1)
_CAS->setCell(i,0," # ");
}
_simulationTime = 0.0;
_generating = true;
}
bool Window::loadSeed(const std::string &fn)
{
std::ifstream file(fn);
if (file.is_open())
{
SGL_Log("Loading save file");
// Load file header (first 17 bytes)
// std::string str;
// for(std::uint16_t i = 0; i < 17; ++i)
// str += file.get();
// SGL_Log(fn + " contents: ");
// SGL_Log(str);
// Read the relevant data into a char buffer
char *buffer = new char[SIMULATION_WIDTH*SIMULATION_HEIGHT];
memset(buffer, 0, SIMULATION_WIDTH*SIMULATION_HEIGHT);
file.seekg(17);
file.read(buffer, SIMULATION_WIDTH*SIMULATION_HEIGHT);
// Populate the seed array
for (std::uint16_t i = 0; i < SIMULATION_WIDTH*SIMULATION_HEIGHT; ++i)
{
if (buffer[i] == '1')
_seed[i] = 1;
else
_seed[i] = 0;
}
delete [] buffer;
file.close();
reset();
return true;
}
return false;
}
bool Window::saveSeed(const std::string &fn)
{
std::ofstream file(fn);
if (file.is_open() && !_seed.empty())
{
SGL_Log("saving file");
//printSeed();
file << "-- SEED START --\n";
//file.write((char*)&_seed, SIMULATION_WIDTH*SIMULATION_HEIGHT);
// std::string test = "";
// for (std::uint16_t i = 0; i < SIMULATION_WIDTH*SIMULATION_HEIGHT; ++i)
// {
// file << static_cast<int>(_seed[i]);
// }
for (const std::uint8_t &i : _seed)
{
//test += i;
// file << static_cast<char>(i);
if (i == 1)
file << 1;
else
file << 0;
}
//file.write(test.c_str());
//file << test.c_str();
file << "\n-- SEED END --";
file << "\n";
SGL_Log("done, string saved: ");
//SGL_Log(test);
file.close();
return true;
}
return false;
}