diff --git a/CMakeLists.txt b/CMakeLists.txt index b19a66e..7fb7b03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,12 @@ configure_file(LunariumConfig.h.in LunariumConfig.h) # Source Files set(LUNARIUM_SRC "src/test_main.cpp" +"src/core/core.cpp" +"src/core/state.cpp" "src/utils/Logger.cpp" "src/utils/HighResTimer.cpp" +"src/utils/helpers.cpp" +"src/utils/OpRes.cpp" ) # add the executable @@ -69,6 +73,7 @@ add_subdirectory(external/pugixml) target_include_directories(${PROJECT_NAME} PUBLIC "${PROJECT_BINARY_DIR}" + PUBLIC src PUBLIC external/glfw/include PUBLIC external/glm PUBLIC external/lua/lua5.4.3/include diff --git a/src/core/core.cpp b/src/core/core.cpp new file mode 100644 index 0000000..682ae06 --- /dev/null +++ b/src/core/core.cpp @@ -0,0 +1,45 @@ +/****************************************************************************** +* 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" + +namespace lunarium +{ + core* core::mpInstance = nullptr; + core::core() + : mbIsInit(false) + { + + } + + core& core::GetInstance() + { + if (!mpInstance) + { + mpInstance = new core; + } + + return *mpInstance; + } + + void core::Shutdown() + { + if (!mpInstance) + return; + + // Shutdown subsystems + + delete mpInstance; + mpInstance = nullptr; + } + + bool core::IsInit() const + { + return mbIsInit; + } +} \ No newline at end of file diff --git a/src/core/core.h b/src/core/core.h new file mode 100644 index 0000000..d202bad --- /dev/null +++ b/src/core/core.h @@ -0,0 +1,36 @@ +/****************************************************************************** +* File - core.h +* 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. +******************************************************************************/ + +#ifndef CORE_H_ +#define CORE_H_ + +namespace lunarium +{ + class core + { + public: + static core& GetInstance(); + static void Shutdown(); + + void Initialize(const char* args); + + bool IsInit() const; + + private: // DATA + static core* mpInstance; + bool mbIsInit; + + private: // HIDDEN METHODS + + core(); + core(const core&) = delete; + core& operator=(const core&) = delete; + }; +} + +#endif // CORE_H_ \ No newline at end of file diff --git a/src/core/state.cpp b/src/core/state.cpp new file mode 100644 index 0000000..2045f21 --- /dev/null +++ b/src/core/state.cpp @@ -0,0 +1,148 @@ +/****************************************************************************** +* File - state.cpp +* Author - Joey Pollack +* Date - 2021/08/30 (y/m/d) +* Mod Date - 2021/08/30 (y/m/d) +* Description - Stores all of the settings for the engine. +******************************************************************************/ + +#include "state.h" +#include +#include + +namespace lunarium +{ + State State::CreateEmpty() + { + State s; + s.DataDirectory = ""; + s.Display.FullScreenResolution.Width = 0; + s.Display.FullScreenResolution.Height = 0; + s.Display.IsFullScreen = false; + s.Display.VSyncEnabled = false; + s.Display.WindowedSize.Width = 0; + s.Display.WindowedSize.Height = 0; + s.Display.WindowStartPosition.X = 0; + s.Display.WindowStartPosition.Y = 0; + s.Interface.MainFont = ""; + + return s; + } + + State State::CreateDefault() + { + + State s; + s.DataDirectory = "data/"; + Sizei size = GetScreenResolution(); + s.Display.FullScreenResolution.Width = size.Width; + s.Display.FullScreenResolution.Height = size.Height; + s.Display.IsFullScreen = false; + s.Display.VSyncEnabled = true; + s.Display.WindowedSize.Width = 800; + s.Display.WindowedSize.Height = 600; + s.Display.WindowStartPosition.X = 100; + s.Display.WindowStartPosition.Y = 100; + s.Interface.MainFont = ""; + + return s; + } + + OpRes State::CreateFromFile(std::string filename, State& state) + { + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(filename.c_str()); + + if (!result) + { + return OpRes::Fail((std::string("Could not open file: ") + filename).c_str()); + } + + pugi::xml_node root = doc.child("State"); + if (pugi::node_null == root.type()) + { + return OpRes::Fail((filename + " does not contain a State element").c_str()); + } + + // Read in each state variable, fill in with a default if it is not found + state.DataDirectory = root.child("DataDirectory").child_value(); + if ("" == state.DataDirectory) + { + state.DataDirectory = "data/"; + } + + pugi::xml_node display = root.child("Display"); + if (pugi::node_null == display.type()) + { + Sizei size = GetScreenResolution(); + state.Display.FullScreenResolution.Width = size.Width; + state.Display.FullScreenResolution.Height = size.Height; + state.Display.IsFullScreen = false; + state.Display.VSyncEnabled = true; + state.Display.WindowedSize.Width = 800; + state.Display.WindowedSize.Height = 600; + state.Display.WindowStartPosition.X = 100; + state.Display.WindowStartPosition.Y = 100; + } + else + { + state.Display.FullScreenResolution.Width = display.child("FullScreenResolution").attribute("Width").as_int(); + state.Display.FullScreenResolution.Height = display.child("FullScreenResolution").attribute("Height").as_int(); + state.Display.IsFullScreen = display.attribute("IsFullScreen").as_bool(); + state.Display.VSyncEnabled = display.attribute("VSyncEnabled").as_bool(); + state.Display.WindowedSize.Width = display.child("WindowedSize").attribute("Width").as_int(); + state.Display.WindowedSize.Height = display.child("WindowedSize").attribute("Height").as_int();; + state.Display.WindowStartPosition.X = display.child("WindowStartPosition").attribute("X").as_int(); + state.Display.WindowStartPosition.Y = display.child("WindowStartPosition").attribute("Y").as_int(); + } + + + pugi::xml_node interface = root.child("Interface"); + if (pugi::node_null == display.type()) + { + state.Interface.MainFont = ""; + } + else + { + state.Interface.MainFont = interface.attribute("MainFont").value(); + } + + + + return OpRes::OK(); + } + + OpRes State::SaveToFile(std::string filename) + { + pugi::xml_document doc; + doc.append_child("State"); + + doc.child("State").append_child("DataDirectory"); + doc.child("State").child("DataDirectory").text().set(DataDirectory.c_str()); + + // Display + pugi::xml_node display = doc.child("State").append_child("Display"); + display.append_attribute("IsFullScreen").set_value(Display.IsFullScreen); + display.append_attribute("VSyncEnabled").set_value(Display.VSyncEnabled); + + pugi::xml_node fsr = display.append_child("FullScreenResolution"); + fsr.append_attribute("Width").set_value(Display.FullScreenResolution.Width); + fsr.append_attribute("Height").set_value(Display.FullScreenResolution.Height); + + pugi::xml_node ws = display.append_child("WindowedSize"); + ws.append_attribute("Width").set_value(Display.WindowedSize.Width); + ws.append_attribute("Height").set_value(Display.WindowedSize.Height); + + pugi::xml_node wsp = display.append_child("WindowStartPosition"); + wsp.append_attribute("X").set_value(Display.WindowStartPosition.X); + wsp.append_attribute("Y").set_value(Display.WindowStartPosition.Y); + + // Interface + pugi::xml_node interface = doc.child("State").append_child("Interface"); + interface.append_attribute("MainFont").set_value(Interface.MainFont.c_str()); + + return doc.save_file(filename.c_str()) + ? OpRes::OK() + : OpRes::Fail((std::string("Could not save xml file: ") + filename).c_str()); + } +} \ No newline at end of file diff --git a/src/core/state.h b/src/core/state.h new file mode 100644 index 0000000..e3cb39b --- /dev/null +++ b/src/core/state.h @@ -0,0 +1,58 @@ +/****************************************************************************** +* File - state.h +* Author - Joey Pollack +* Date - 2021/08/30 (y/m/d) +* Mod Date - 2021/08/30 (y/m/d) +* Description - Stores all of the settings for the engine. +******************************************************************************/ + +#ifndef STATE_H_ +#define STATE_H_ + +#include +#include + +namespace lunarium +{ + struct State + { + std::string DataDirectory; + struct + { + struct + { + int X; + int Y; + } WindowStartPosition; + + + struct + { + int Width; + int Height; + } WindowedSize; + + struct + { + int Width; + int Height; + } FullScreenResolution; + + bool IsFullScreen; + bool VSyncEnabled; + } Display; + + struct + { + std::string MainFont; + } Interface; + + // METHODS + static State CreateEmpty(); + static State CreateDefault(); + static OpRes CreateFromFile(std::string filename, State& state); + OpRes SaveToFile(std::string filename); + }; +} + +#endif // STATE_H_ \ No newline at end of file diff --git a/src/test_main.cpp b/src/test_main.cpp index 7aad191..4bce3ba 100644 --- a/src/test_main.cpp +++ b/src/test_main.cpp @@ -5,8 +5,9 @@ #include #include #include -#include "utils/INIFile.h" #include "utils/Logger.h" +#include "utils/OpRes.h" +#include "core/state.h" extern "C" { @@ -16,7 +17,7 @@ extern "C" } -// the following can also be but it results in +// the following can also be but it results in // an intellisense error #include "../build/LunariumConfig.h" @@ -69,6 +70,24 @@ int main(int argc, char** argv) std::cout << "\nPugiXML worked! -- x is: " << x << std::endl; } + std::cout <<"\nTesting loading a state from file..."; + lunarium::State testState; + if (lunarium::IsOK(lunarium::State::CreateFromFile("../test_data/test_state.xml", testState))) + { + std::cout << "\nIt worked! Full Screen Resolution Width: " << testState.Display.FullScreenResolution.Width; + std::cout << "\nSaveing out to test_save.xml"; + + if (lunarium::IsOK(testState.SaveToFile("../test_data/test_save.xml"))) + { + std::cout << "\nSuccess!\n"; + } + else + { + std::cout << "\nFailed to save the file...\n"; + } + + } + // UTILS TEST // NOTE: this works but is windows only so it won't be used in the engine // unless INIFile is re-written to be cross-platform diff --git a/src/utils/INIFile.cpp b/src/utils/INIFile.cpp deleted file mode 100644 index 1057f67..0000000 --- a/src/utils/INIFile.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** -* File - INIFile.h -* Author - Joey Pollack -* Date - 2017/11/28 (y/m/d) -* Mod Date - 2017/11/28 (y/m/d) -* Description - Read/Write from a .ini file -******************************************************************************/ - -#include "INIFile.h" - -// TODO: This needs to be re-written without the windows-specific functions -#define WIN32_LEAN_AND_MEAN -#include - -#include -#include - -namespace Lunarium -{ - INIFile::INIFile(const char * filename) - { - mFullPath = filename; - } - - INIFile::~INIFile() - { - } - - std::string INIFile::Read(const char* section, const char* key) - { - char buffer[256]; - GetPrivateProfileStringA(section, key, nullptr, buffer, 256, mFullPath.c_str()); - return std::string(buffer); - } - - int INIFile::ReadInt(const char* section, const char* key) - { - int val = GetPrivateProfileIntA(section, key, -1, mFullPath.c_str()); - return val; - } - - bool INIFile::ReadBool(const char* section, const char* key) - { - std::string buffer = Read(section, key); - - if (buffer.size() < 1) - throw std::runtime_error("ReadBool() Failed: buffer was empty!"); - - std::transform(buffer.begin(), buffer.end(), buffer.begin(), ::tolower); - - if (buffer == std::string("false")) - return false; - - if (buffer == std::string("true")) - return true; - - throw std::runtime_error("ReadBool() Failed: buffer not a boolean value!"); - - return false; - } - - double INIFile::ReadDouble(const char* section, const char* key) - { - throw "Not implemented!"; - return 0.0; - } - - void INIFile::Write(const char * section, const char * key, const char * value) - { - WritePrivateProfileStringA(section, key, value, mFullPath.c_str()); - } - - void INIFile::WriteInt(const char * section, const char * key, int value) - { - std::string strVal = std::to_string(value); - WritePrivateProfileStringA(section, key, strVal.c_str(), mFullPath.c_str()); - } - - void INIFile::WriteBool(const char * section, const char * key, bool value) - { - std::string strVal = "true"; - if (!value) - { - strVal = "false"; - } - - WritePrivateProfileStringA(section, key, strVal.c_str(), mFullPath.c_str()); - } - - void INIFile::WriteDouble(const char * section, const char * key, double value) - { - throw "INIFile::WriteDouble Not implemented!"; - } - - bool INIFile::KeyExists(const char* section, const char* key) - { - return Read(section, key).length() > 0; - } - - void INIFile::DeleteKey(const char* section, const char* key) - { - Write(section, key, nullptr); - } - - void INIFile::DeleteSection(const char * section) - { - Write(section, nullptr, nullptr); - } -} \ No newline at end of file diff --git a/src/utils/INIFile.h b/src/utils/INIFile.h deleted file mode 100644 index de3d870..0000000 --- a/src/utils/INIFile.h +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************** -* File - INIFile.h -* Author - Joey Pollack -* Date - 2017/11/28 (y/m/d) -* Mod Date - 2017/11/28 (y/m/d) -* Description - Read/Write from a .ini file -* Based on the C# class writen by Danny Beckett and released -* to public domain: -* https://stackoverflow.com/questions/217902/reading-writing-an-ini-file -******************************************************************************/ - -#ifndef _INI_FILE_H_ -#define _INI_FILE_H_ - -#include - -namespace Lunarium -{ - class INIFile - { - public: - - // filename must be a full, absolute path to the .ini file. - INIFile(const char* filename); - ~INIFile(); - - // Read methods - std::string Read(const char* section, const char* key); - int ReadInt(const char* section, const char* key); - bool ReadBool(const char* section, const char* key); - double ReadDouble(const char* section, const char* key); - - // Write methods - void Write(const char * section, const char* key, const char* value); - void WriteInt(const char * section, const char* key, int value); - void WriteBool(const char * section, const char* key, bool value); - void WriteDouble(const char * section, const char* key, double value); - - - // Management - bool KeyExists(const char* section, const char* key); - - void DeleteKey(const char* section, const char* key); - void DeleteSection(const char* section); - - - private: - bool mbFileOpen; - - std::string mFullPath; - }; - -} -#endif // _INI_FILE_H_ \ No newline at end of file diff --git a/src/utils/OpRes.cpp b/src/utils/OpRes.cpp new file mode 100644 index 0000000..1f7cab7 --- /dev/null +++ b/src/utils/OpRes.cpp @@ -0,0 +1,43 @@ +/****************************************************************************** +* File - OpRes.cpp +* Author - Joey Pollack +* Date - 2020/03/05 (y/m/d) +* Mod Date - 2020/03/05 (y/m/d) +* Description - Operation Result. Also contains a message describing the result. +* +******************************************************************************/ + +#include "OpRes.h" + +namespace lunarium +{ + bool OpRes::operator==(const OpRes& rhs) + { + return this->Type == rhs.Type; + } + + bool OpRes::operator==(ResultType rhs) + { + return this->Type == rhs; + } + + OpRes OpRes::OK() + { + return { ResultType::OK, "The operation succeeded" }; + } + + OpRes OpRes::Fail(const char* why) + { + return { ResultType::FAIL, why }; + } + + bool IsOK(OpRes&& res) + { + return res.Type == ResultType::OK; + } + + bool Failed(OpRes&& res) + { + return res.Type == ResultType::FAIL; + } +} \ No newline at end of file diff --git a/src/utils/OpRes.h b/src/utils/OpRes.h new file mode 100644 index 0000000..1258d21 --- /dev/null +++ b/src/utils/OpRes.h @@ -0,0 +1,43 @@ +/****************************************************************************** +* File - OpRes.h +* Author - Joey Pollack +* Date - 2020/03/05 (y/m/d) +* Mod Date - 2020/03/05 (y/m/d) +* Description - Operation Result. Also contains a message describing the result. +* +******************************************************************************/ + +#ifndef _OPERATION_RESULT_H_ +#define _OPERATION_RESULT_H_ + +#include + +namespace lunarium +{ + enum ResultType + { + OK, + WARNING, // Not used yet + FAIL + }; + + struct OpRes + { + ResultType Type; + std::string Description; + + bool operator==(const OpRes& rhs); + + bool operator==(ResultType rhs); + + static OpRes OK(); + + static OpRes Fail(const char* why); + }; + + bool IsOK(OpRes&& res); + + bool Failed(OpRes&& res); +} + +#endif // _OPERATION_RESULT_H_ \ No newline at end of file diff --git a/src/utils/helpers.cpp b/src/utils/helpers.cpp new file mode 100644 index 0000000..6162098 --- /dev/null +++ b/src/utils/helpers.cpp @@ -0,0 +1,51 @@ +/****************************************************************************** +* File - helpers.cpp +* Author - Joey Pollack +* Date - 2021/08/30 (y/m/d) +* Mod Date - 2021/08/30 (y/m/d) +* Description - Defines some helper methods for use through out the engine. +******************************************************************************/ + +#include "helpers.h" + +#ifdef WIN32 + #include +#else + #include +#endif // WIN32 + +namespace lunarium +{ + Sizei GetScreenResolution() + { + #ifdef WIN32 + return Sizei { GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN) }; + #else + Display* disp = XOpenDisplay(NULL); + Screen* scrn = DefaultScreenOfDisplay(disp); + return Sizei { scrn->width, scrn->height }; + #endif // WIN32 + } + + //template + std::string AsString(int value) + { + std::string str = ""; + str += value; + return str; + } + + std::string AsString(bool value) + { + std::string str = ""; + str += value; + return str; + } + + std::string AsString(float value) + { + std::string str = ""; + str += value; + return str; + } +} \ No newline at end of file diff --git a/src/utils/helpers.h b/src/utils/helpers.h new file mode 100644 index 0000000..11302cf --- /dev/null +++ b/src/utils/helpers.h @@ -0,0 +1,25 @@ +/****************************************************************************** +* File - helpers.h +* Author - Joey Pollack +* Date - 2021/08/30 (y/m/d) +* Mod Date - 2021/08/30 (y/m/d) +* Description - Defines some helper methods for use through out the engine. +******************************************************************************/ + +#ifndef HELPERS_H_ +#define HELPERS_H_ + +#include "types.h" +#include + +namespace lunarium +{ + Sizei GetScreenResolution(); + + //template + std::string AsString(int value); + std::string AsString(bool value); + std::string AsString(float value); +} + +#endif // HELPERS_H_ \ No newline at end of file diff --git a/src/utils/types.h b/src/utils/types.h new file mode 100644 index 0000000..8c29bdd --- /dev/null +++ b/src/utils/types.h @@ -0,0 +1,26 @@ +/****************************************************************************** +* File - types.h +* Author - Joey Pollack +* Date - 2021/08/30 (y/m/d) +* Mod Date - 2021/08/30 (y/m/d) +* Description - Defines some generic types for use through out the engine. +******************************************************************************/ + +#ifndef TYPES_H_ +#define TYPES_H_ + +namespace lunarium +{ + template + struct Size + { + T Width; + T Height; + }; + + typedef Size Sizei; + typedef Size Sizeu; + typedef Size Sizef; +} + +#endif // TYPES_H_ \ No newline at end of file diff --git a/test_data/test_state.xml b/test_data/test_state.xml new file mode 100644 index 0000000..55f5361 --- /dev/null +++ b/test_data/test_state.xml @@ -0,0 +1,9 @@ + + data/ + + + + + + + \ No newline at end of file