/****************************************************************************** * File - core.cpp * Author - Joey Pollack * Date - 2021/08/30 (y/m/d) * Mod Date - 2021/08/30 (y/m/d) * Description - The Core Engine Class. Manages the engine components. ******************************************************************************/ #include "core.h" #include "version.h" // Sub Systems #include #include namespace lunarium { Core* Core::mpInstance = nullptr; Core::Core() : mbIsInit(false), mpArgs(nullptr), mpWindow(nullptr), mpGraphics(nullptr) { } Core& Core::GetInstance() { if (!mpInstance) { mpInstance = new Core; } return *mpInstance; } void Core::Shutdown() { if (!mpInstance) return; Logger::Log(LogCategory::CORE, LogLevel::INFO, "Lunarium is shutting down!"); // Shutdown subsystems delete mpInstance->mpGraphics; mpInstance->mpGraphics = nullptr; delete mpInstance->mpWindow; mpInstance->mpWindow = nullptr; delete mpInstance->mpArgs; mpInstance->mpArgs = nullptr; mpInstance->mbIsInit = false; delete mpInstance; mpInstance = nullptr; } void Core::Initialize(int argc, char** argv) { // Setup the log system mMasterLogFile.open("Lunarium_Master.log", std::ios_base::app); mMasterLogFile << "\n\n"; mErrorLogFile.open("Lunarium_Errors.log", std::ios_base::app); mErrorLogFile << "\n\n"; if (mMasterLogFile.is_open()) Logger::GetInstance()->AddListener(new FileListener(mMasterLogFile)); if (mErrorLogFile.is_open()) Logger::GetInstance()->AddListener(new FileListener(mErrorLogFile, LogLevel::ERROR | LogLevel::FATAL_ERROR)); Logger::Log(LogCategory::CORE, LogLevel::INFO, "Running Lunarium version %s", Version::GetVersion().ToString().c_str()); // Attempt to load the engine state file. This file should be placed in the same directory as the lunarium program. if (Failed(State::CreateFromFile("lunarium_state.xml", mState))) { Logger::Log(LogCategory::CORE, LogLevel::WARNING, "Unable to load state file: lunarium_state.xml. Loading default state."); mState = State::CreateDefault(); } else { Logger::Log(LogCategory::CORE, LogLevel::INFO, "Loaded state file: lunarium_state.xml"); } // Parse command line args -- None right now std::vector sd; mpArgs = new Args(argc, argv, '-', sd); OpRes result; // Init Graphics/Window system mpWindow = new Window; result = mpWindow->Initialize(mState); if (Failed(result)) { Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR, "Could not initialize the Window system: %s", result.Description); return; } if (Renderer::OPENGL == mState.Display.RenderFramework) { mpGraphics = new OglGraphics; } else if (Renderer::VULKAN == mState.Display.RenderFramework) { Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR, "Can not create Vulkan graphics system because it is not yet implemented. Must use OpenGL instead."); return; } else { Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR, "Could not create graphics system: Unknown render framework specified."); return; } // TODO: This should probably be based on a state setting instead #ifdef _DEBUG result = mpGraphics->Initialize(mpWindow); #else result = mpGraphics->Initialize(mpWindow, false); #endif if (Failed(result)) { Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR, "Could not initialized the graphics system: %s", result.Description); return; } // DEBUG mpGraphics->SetClearColor(Color(0.0f, 0.0f, 0.0f, 1.0f)); mbIsInit = true; } bool Core::IsInit() const { return mbIsInit; } const State& Core::GetState() const { return mState; } void Core::RunGameLoop() { mFrameCounter.Reset(); // TODO: Init frame counter while (!mpWindow->ShouldWindowClose()) { mFrameCounter.NewFrame(); // Display FPS in window title for now std::string title = "Lunarium - FPS: "; title += std::to_string(mFrameCounter.GetFrameData().CurrentFPS); glfwSetWindowTitle(mpWindow->GetWindow(), title.c_str()); // Poll input Window::PollEvents(); // HACK: Temporary solution to close the program if (glfwGetKey(mpWindow->GetWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS) { mpWindow->SetShouldCloseFlag(true); } // Update game state // Render mpGraphics->BeginDraw(); mpGraphics->EndDraw(); } } }