From 9ab9e476b95d3fc3fcf3657e707733f24635c92a Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Fri, 11 Oct 2024 17:58:04 +0200 Subject: [PATCH] Main refactor and proper window management --- Game.cpp | 39 +++++++-------------------------------- Game.hpp | 13 +++++++------ ProtoTank.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/Game.cpp b/Game.cpp index 5cc0498..2789d63 100644 --- a/Game.cpp +++ b/Game.cpp @@ -1,14 +1,11 @@ #include "Game.hpp" -#include "icon.h" #include #include -#include #include #include "Engine/Utils/Perfs.hpp" -#include "Engine/Utils/Timers.hpp" using std::make_shared; using std::make_unique; @@ -19,9 +16,7 @@ using std::make_unique; std::unique_ptr mPerfsTimer = nullptr; Game* Game::smInstance = nullptr; -Game::Game(bool dbgFlag) : mbDbgModeEnabled(dbgFlag) { - InitWindows(); - +Game::Game(std::shared_ptr mainWnd, bool dbgFlag) : mbDbgModeEnabled(dbgFlag), mMainWindow(mainWnd) { mCockpitUI = make_unique(); mWorldUI = make_unique(); @@ -32,32 +27,12 @@ Game::Game(bool dbgFlag) : mbDbgModeEnabled(dbgFlag) { } } -void Game::InitWindows() { - // Create default game window - sf::ContextSettings sWindowSettings; - sWindowSettings.depthBits = 0; - sWindowSettings.stencilBits = 0; - sWindowSettings.antialiasingLevel = 8; - sWindowSettings.sRgbCapable = true; - - mMainWindow = make_shared( - sf::VideoMode(1280, 720), "ProtoTank", - (sf::Style::Close | sf::Style::Titlebar), - sWindowSettings - ); - mMainWindow->setVerticalSyncEnabled(false); // Never use simultaneously with framerate limiter - mMainWindow->setFramerateLimit(60); - mMainWindow->setKeyRepeatEnabled(false); - mMainWindow->setMouseCursorVisible(true); - mMainWindow->setIcon(64, 64, _aicon_bin); -} - -GAME_STATUS Game::Tick(SysTimer& time) { +GAME_STATUS Game::Tick() { static std::vector msTicksMonitoring; static double mPrevdelta = 0; static double mLastCycleSleepDelta = 0; static unsigned int mFrameCnt = 0; - double mDelta = time.GetDeltaTimeUs(); + double mDelta = mSysTimer.GetDeltaTimeUs(); // Debug performance computations if (mDbgUI != nullptr && mPerfsTimer != nullptr) { @@ -66,7 +41,7 @@ GAME_STATUS Game::Tick(SysTimer& time) { // This average CPU/cycle_time method can monitor when CPU is in overload state (>0%) or in underload one (<0%) double cpuUsage = 200 * std::accumulate(msTicksMonitoring.begin(), msTicksMonitoring.end(), (double)(0)) / msTicksMonitoring.size() - 100; - mDbgUI->UpdateDebugData(cpuUsage, (((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) / 1000), ((-mPrevdelta + time.GetDeltaTimeUs()) / 1000), mFrameCnt, (PerfsGetVirtMem() / 1000), (PerfsGetPhysMem() / 1000)); + mDbgUI->UpdateDebugData(cpuUsage, (((1000000.f / TARGET_FPS) - mLastCycleSleepDelta) / 1000), ((-mPrevdelta + mSysTimer.GetDeltaTimeUs()) / 1000), mFrameCnt, (PerfsGetVirtMem() / 1000), (PerfsGetPhysMem() / 1000)); mFrameCnt = 0; msTicksMonitoring.clear(); @@ -87,16 +62,16 @@ GAME_STATUS Game::Tick(SysTimer& time) { //while(time.GetDeltaTime() < (1000/TARGET_FPS)) {} // Process to the final rendering - if (time.GetDeltaTime() >= (1000/TARGET_FPS)) { + if (mSysTimer.GetDeltaTime() >= (1000/TARGET_FPS)) { Render(); mFrameCnt++; - time.Reset(); + mSysTimer.Reset(); mDelta = -mDelta; } mPrevdelta = mDelta; // Sleep for remaining time to avoid useless CPU usage - mLastCycleSleepDelta = (1000000.f / TARGET_FPS) - (-mPrevdelta + time.GetDeltaTimeUs()); + mLastCycleSleepDelta = (1000000.f / TARGET_FPS) - (-mPrevdelta + mSysTimer.GetDeltaTimeUs()); if (mLastCycleSleepDelta > 0) sf::sleep(sf::microseconds(mLastCycleSleepDelta)); else diff --git a/Game.hpp b/Game.hpp index a4a93ff..dfcb0cd 100644 --- a/Game.hpp +++ b/Game.hpp @@ -15,9 +15,9 @@ typedef enum eGameStatus { class Game final { public: - static Game& getInstance(bool dbgFlag) { + static Game& getInstance(std::shared_ptr mainWnd, bool dbgFlag) { if (smInstance == nullptr) - smInstance = new Game(dbgFlag); + smInstance = new Game(mainWnd, dbgFlag); return *smInstance; } @@ -28,20 +28,21 @@ public: Game(Game const&) = delete; Game& operator= (Game const&) = delete; - GAME_STATUS Tick(SysTimer& time); + GAME_STATUS Tick(); private: - Game(bool dbgFlag) noexcept(false); + Game(std::shared_ptr mainWnd, bool dbgFlag) noexcept(false); static Game* smInstance; - void InitWindows(); void Update(); void Render(); bool mbDbgModeEnabled; std::unique_ptr mDbgUI = nullptr; - std::shared_ptr mMainWindow = nullptr; + SysTimer mSysTimer; + + std::shared_ptr mMainWindow; std::unique_ptr mCockpitUI = nullptr; std::unique_ptr mWorldUI = nullptr; diff --git a/ProtoTank.cpp b/ProtoTank.cpp index 02ca9f5..734e8b2 100644 --- a/ProtoTank.cpp +++ b/ProtoTank.cpp @@ -1,18 +1,33 @@ +#include +#include +#include + +#include "icon.h" #include "Engine/Misc/Logger.hpp" + #include "Game.hpp" +static std::shared_ptr InitWindow(); + int main(int argc, char** argv) { - SysTimer mSysTimer; Logger& log = Logger::getInstance(); + log.PrintInfo(LOGGER_MSG_FT("Create main window")); + std::shared_ptr mainWindow = nullptr; + try { + mainWindow = InitWindow(); + } catch (const std::exception& ex) { + log.PrintCritical(std::string(ex.what())); + return EXIT_FAILURE; + } + + log.PrintInfo(LOGGER_MSG_FT("Create game instance")); + Game& arcadeGame = Game::getInstance(mainWindow, true); GAME_STATUS status = GAME_INIT; - log.PrintInfo(LOGGER_MSG_FT("Init game instance")); - Game& arcadeGame = Game::getInstance(true); - for ( ;; ) { - status = arcadeGame.Tick(mSysTimer); + status = arcadeGame.Tick(); if (status == GAME_QUIT) break; @@ -21,3 +36,29 @@ int main(int argc, char** argv) { log.PrintInfo(LOGGER_MSG_FT("Bye bye!")); return EXIT_SUCCESS; } + +static std::shared_ptr InitWindow() { + // Create default game window + sf::ContextSettings sWindowSettings; + sWindowSettings.depthBits = 0; + sWindowSettings.stencilBits = 0; + sWindowSettings.antialiasingLevel = 8; + sWindowSettings.sRgbCapable = true; + + auto wnd = std::make_shared( + sf::VideoMode(1280, 720), "ProtoTank", + (sf::Style::Close | sf::Style::Titlebar), + sWindowSettings + ); + + if (wnd == nullptr) + throw std::runtime_error("Failed to create the window"); + + wnd->setVerticalSyncEnabled(false); // Never use simultaneously with framerate limiter + wnd->setFramerateLimit(60); // Never use simultaneously with VSync + wnd->setKeyRepeatEnabled(false); + wnd->setMouseCursorVisible(true); + wnd->setIcon(64, 64, _aicon_bin); + + return wnd; +} \ No newline at end of file