From 9247b8df8a9f685cb0e92a6dc800227244ff6083 Mon Sep 17 00:00:00 2001 From: freezarite Date: Tue, 3 Dec 2024 18:17:31 +0100 Subject: [PATCH 01/10] started work on config-system added nlohmann_json library as submodule and to CMakeLists.txt created basic config.json file in root folder created ConfigLoader.h and added basic functionalities to it --- .gitmodules | 3 +++ CMakeLists.txt | 6 +++++- config.json | 3 +++ extern/nlohmann_json | 1 + include/ConfigLoader.h | 24 ++++++++++++++++++++++++ src/ConfigLoader.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 config.json create mode 160000 extern/nlohmann_json create mode 100644 include/ConfigLoader.h create mode 100644 src/ConfigLoader.cpp diff --git a/.gitmodules b/.gitmodules index 6dd82fa..9f871ba 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,6 @@ path = docs/doxygen-awesome-css url = https://github.com/jothepro/doxygen-awesome-css.git +[submodule "extern/nlohmann_json"] + path = extern/nlohmann_json + url = https://github.com/nlohmann/json.git diff --git a/CMakeLists.txt b/CMakeLists.txt index d38fa27..12d886d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,13 @@ add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL) +add_subdirectory(extern/nlohmann_json EXCLUDE_FROM_ALL) file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp) -add_library(${PROJECT_NAME} ${SOURCES}) +add_library(${PROJECT_NAME} ${SOURCES} + include/ConfigLoader.h + src/ConfigLoader.cpp) target_include_directories(${PROJECT_NAME} PUBLIC ${ENGINE_INCLUDE_DIR}) @@ -37,6 +40,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu SDL3_mixer::SDL3_mixer-static SDL3_ttf::SDL3_ttf-static tmxlite + nlohmann_json::nlohmann_json ) if(CMAKE_BUILD_TYPE MATCHES "Debug") diff --git a/config.json b/config.json new file mode 100644 index 0000000..2aff41b --- /dev/null +++ b/config.json @@ -0,0 +1,3 @@ +{ + "fullscreen": false +} \ No newline at end of file diff --git a/extern/nlohmann_json b/extern/nlohmann_json new file mode 160000 index 0000000..a006a7a --- /dev/null +++ b/extern/nlohmann_json @@ -0,0 +1 @@ +Subproject commit a006a7a48bb30a247f0344b788c62c2806edd90b diff --git a/include/ConfigLoader.h b/include/ConfigLoader.h new file mode 100644 index 0000000..d0115a4 --- /dev/null +++ b/include/ConfigLoader.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +using json = nlohmann::json; + +class ConfigLoader { + +public: + ConfigLoader(); + ~ConfigLoader(); + + void init(); + + void setCustomConfig(std::string path); + +private: + json baseConfig; + std::optional customConfig; + json finalConfig; + + json loadConfigFromJSON(const std::string& path); + json mergeConfigs(json baseConfig, json customConfig); // + +ConfigLoader::ConfigLoader() { + baseConfig = loadConfigFromJSON("config.json"); +} + +void ConfigLoader::init() { + if (!customConfig.has_value()) { + finalConfig = baseConfig; + return; + } + finalConfig = mergeConfigs(baseConfig, customConfig.value()); +} + +json ConfigLoader::loadConfigFromJSON(const std::string& path) { + std::ifstream config_file(path); + json config; + + if (!config_file.is_open()) { + throw std::runtime_error(std::string("Could not load config file at: " + path)); + } + + config_file >> config; + return config; +} + + +void ConfigLoader::setCustomConfig(std::string path) { + customConfig.emplace(loadConfigFromJSON(path)); +} + +json ConfigLoader::mergeConfigs(json baseConfig, json customConfig) { + for (auto& entry : customConfig.items()) { + baseConfig[entry.key()] = entry.value(); + } + return baseConfig; +} + + From 5e48f4e34ff4fd963880c08fda5f4540d96b4fdb Mon Sep 17 00:00:00 2001 From: freezarite Date: Fri, 13 Dec 2024 14:36:43 +0100 Subject: [PATCH 02/10] Config now gets read by the GameInternal.cpp Made the process of adding a custom Config file work via a Virtual function within Game.h --- include/ConfigLoader.h | 4 +++- include/Game.h | 1 + src/ConfigLoader.cpp | 11 +++++++++-- src/GameInternal.cpp | 11 +++++++++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/ConfigLoader.h b/include/ConfigLoader.h index d0115a4..8ba9c55 100644 --- a/include/ConfigLoader.h +++ b/include/ConfigLoader.h @@ -12,7 +12,9 @@ public: void init(); - void setCustomConfig(std::string path); + void setCustomConfig(const std::optional& path); + + json getFinalConfig(); private: json baseConfig; diff --git a/include/Game.h b/include/Game.h index 3eb990d..75f6713 100644 --- a/include/Game.h +++ b/include/Game.h @@ -9,6 +9,7 @@ public: virtual void init() = 0; virtual void update(uint_fast16_t diffTime) = 0; + virtual std::optional getConfigFilePath() {return std::nullopt;} GameInternal* gameInternal; //!< \deprecated }; diff --git a/src/ConfigLoader.cpp b/src/ConfigLoader.cpp index 4c8cb04..4620c56 100644 --- a/src/ConfigLoader.cpp +++ b/src/ConfigLoader.cpp @@ -6,6 +6,8 @@ ConfigLoader::ConfigLoader() { baseConfig = loadConfigFromJSON("config.json"); } +ConfigLoader::~ConfigLoader() {} + void ConfigLoader::init() { if (!customConfig.has_value()) { finalConfig = baseConfig; @@ -27,8 +29,8 @@ json ConfigLoader::loadConfigFromJSON(const std::string& path) { } -void ConfigLoader::setCustomConfig(std::string path) { - customConfig.emplace(loadConfigFromJSON(path)); +void ConfigLoader::setCustomConfig(const std::optional& path) { + customConfig = path; } json ConfigLoader::mergeConfigs(json baseConfig, json customConfig) { @@ -38,4 +40,9 @@ json ConfigLoader::mergeConfigs(json baseConfig, json customConfig) { return baseConfig; } +json ConfigLoader::getFinalConfig() { + return finalConfig; +} + + diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 1e4eac3..c1df0be 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -15,6 +15,8 @@ #include +#include "ConfigLoader.h" + GameInternal::GameInternal() : manager(this), renderManager(), @@ -29,13 +31,19 @@ GameInternal::~GameInternal() = default; SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen) { + this->gameInstance = GameFactory::instance().create(this); + ConfigLoader().setCustomConfig(this->gameInstance->getConfigFilePath()); + ConfigLoader().init(); + + json config = ConfigLoader().getFinalConfig(); + GameInternal::assets = new AssetManager(&manager); GameInternal::textureManager = new TextureManager(&manager); GameInternal::soundManager = new SoundManager(); GameInternal::collisionHandler = new CollisionHandler(manager); // why does this use a referrence, but AssetManager a pointer? int flags = 0; - if (fullscreen) + if (config.at("fullscreen")) { flags = SDL_WINDOW_FULLSCREEN; } @@ -95,7 +103,6 @@ SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int widt // loading music // assets->addMusic("background_music", "assets/sound/background_music.mp3"); - this->gameInstance = GameFactory::instance().create(this); this->gameInstance->init(); return SDL_APP_CONTINUE; From acdbf29896de68c3bffeed9b33b32850028f11ef Mon Sep 17 00:00:00 2001 From: freezarite Date: Mon, 16 Dec 2024 05:47:28 +0100 Subject: [PATCH 03/10] Fixed a bug where the custom json was not loaded correctly Changed base config location to ./engine/config.json to make implementation better for the game-dev --- src/ConfigLoader.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ConfigLoader.cpp b/src/ConfigLoader.cpp index 4620c56..65381f5 100644 --- a/src/ConfigLoader.cpp +++ b/src/ConfigLoader.cpp @@ -3,7 +3,9 @@ #include ConfigLoader::ConfigLoader() { - baseConfig = loadConfigFromJSON("config.json"); + //TODO: look into adaptive paths for better handling as this requires the implemented game + // to have ./engine in the root folder + baseConfig = loadConfigFromJSON("./engine/config.json"); } ConfigLoader::~ConfigLoader() {} @@ -30,7 +32,9 @@ json ConfigLoader::loadConfigFromJSON(const std::string& path) { void ConfigLoader::setCustomConfig(const std::optional& path) { - customConfig = path; + if (path.has_value()) { + customConfig = loadConfigFromJSON(path.value()); + } } json ConfigLoader::mergeConfigs(json baseConfig, json customConfig) { From 691ea06eb0afde281f35c0e92f60c800836396c4 Mon Sep 17 00:00:00 2001 From: freezarite Date: Mon, 16 Dec 2024 06:02:58 +0100 Subject: [PATCH 04/10] Added and implemented some more config options in the GameInternal.cpp. Also removed GameInternal::init() parameters as they are no longer needed --- config.json | 6 +++++- include/GameInternal.h | 2 +- src/GameInternal.cpp | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index 2aff41b..0e0eb80 100644 --- a/config.json +++ b/config.json @@ -1,3 +1,7 @@ { - "fullscreen": false + "fullscreen": false, + "title": "VGG (Very Good Game)", + "height": 100, + "width": 100, + "icon": "./engine/internalAssets/iconImage.bmp" } \ No newline at end of file diff --git a/include/GameInternal.h b/include/GameInternal.h index 7cb3b1f..98c8fd1 100644 --- a/include/GameInternal.h +++ b/include/GameInternal.h @@ -27,7 +27,7 @@ public: GameInternal(); ~GameInternal(); - SDL_AppResult init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen); + SDL_AppResult init(); void handleEvents(); void update(Uint64 frameTime); diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index c1df0be..7d5f5fc 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -29,7 +29,7 @@ GameInternal::GameInternal() : GameInternal::~GameInternal() = default; -SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen) +SDL_AppResult GameInternal::init() { this->gameInstance = GameFactory::instance().create(this); ConfigLoader().setCustomConfig(this->gameInstance->getConfigFilePath()); @@ -60,7 +60,7 @@ SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int widt return SDL_APP_FAILURE; } - window = SDL_CreateWindow(title, width, height, flags); + window = SDL_CreateWindow(config.at("title").get().c_str(), config.at("width"), config.at("height"), flags); if (!window) { std::cout << "ERROR: Window couldnt be created! " << SDL_GetError() << std::endl; @@ -70,7 +70,7 @@ SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int widt // bad SDL_Surface* icon; - if((icon = SDL_LoadBMP("assets/iconImage.bmp"))) + if((icon = SDL_LoadBMP(config.at("icon").get().c_str()))) { SDL_SetWindowIcon(window, icon); } From 1f3cf01419be9d378dac53f9760e473117067f37 Mon Sep 17 00:00:00 2001 From: freezarite Date: Mon, 16 Dec 2024 06:08:52 +0100 Subject: [PATCH 05/10] fixed a bug with the implementation of the nlohmann library in the CMakeLists.txt fixed a bug where the config was not loaded correctly in the GameInternal.cpp --- CMakeLists.txt | 3 +-- src/GameInternal.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12d886d..2b44666 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL) -add_subdirectory(extern/nlohmann_json EXCLUDE_FROM_ALL) +include_directories(extern/nlohmann_json/include) file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp) @@ -40,7 +40,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu SDL3_mixer::SDL3_mixer-static SDL3_ttf::SDL3_ttf-static tmxlite - nlohmann_json::nlohmann_json ) if(CMAKE_BUILD_TYPE MATCHES "Debug") diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 7d5f5fc..65619f2 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -31,11 +31,13 @@ GameInternal::~GameInternal() = default; SDL_AppResult GameInternal::init() { - this->gameInstance = GameFactory::instance().create(this); - ConfigLoader().setCustomConfig(this->gameInstance->getConfigFilePath()); - ConfigLoader().init(); + ConfigLoader* loader = new ConfigLoader(); - json config = ConfigLoader().getFinalConfig(); + this->gameInstance = GameFactory::instance().create(this); + loader->setCustomConfig(this->gameInstance->getConfigFilePath()); + loader->init(); + + json config = loader->getFinalConfig(); GameInternal::assets = new AssetManager(&manager); GameInternal::textureManager = new TextureManager(&manager); From 55b60624c4c43204f5ce830c737c722385718eb1 Mon Sep 17 00:00:00 2001 From: freezarite Date: Mon, 16 Dec 2024 06:10:31 +0100 Subject: [PATCH 06/10] added a folder to hold internal assets for the standard config of the engine --- internalAssets/iconImage.bmp | Bin 0 -> 3126 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 internalAssets/iconImage.bmp diff --git a/internalAssets/iconImage.bmp b/internalAssets/iconImage.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6eddbefc55ade778d7ad509e6d00db55652a5cc4 GIT binary patch literal 3126 zcmeH{ze)o^5Qk%}m6fHXPY?t9lDhB&NEsUdOv^pZZ|#1VLJ zsUZzXuj(s{o`TL$d_EruIIAmdfM!&l54WR Date: Mon, 16 Dec 2024 06:21:26 +0100 Subject: [PATCH 07/10] removed no longer used variables in Constants.h updated _Init.cpp to use updated init() function from GameInternal.cpp --- include/Constants.h | 3 --- src/_Init.cpp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/Constants.h b/include/Constants.h index 713f1bd..2c70809 100644 --- a/include/Constants.h +++ b/include/Constants.h @@ -11,9 +11,6 @@ constexpr std::size_t MAX_GROUPS = 32; constexpr std::size_t MAX_STATS = 8; constexpr std::size_t MAX_TEAMS = 8; -constexpr int SCREEN_SIZE_HEIGHT = 640; -constexpr int SCREEN_SIZE_WIDTH = 800; - constexpr int FPS = 60; constexpr int TILE_SIZE = 32; diff --git a/src/_Init.cpp b/src/_Init.cpp index cb82136..d108b73 100644 --- a/src/_Init.cpp +++ b/src/_Init.cpp @@ -19,7 +19,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { *appstate = vego::game = new GameInternal(); - return vego::game->init("No_Name_Chicken_Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_SIZE_WIDTH, SCREEN_SIZE_HEIGHT, false); + return vego::game->init(); } SDL_AppResult SDL_AppIterate(void *appstate) { From abe018f99bf6b19c2d389580b64b247bc3cdbd60 Mon Sep 17 00:00:00 2001 From: freezarite Date: Mon, 16 Dec 2024 13:12:53 +0100 Subject: [PATCH 08/10] fixed some issues stemming from the removal of the window-size constant variables --- include/GameInternal.h | 3 +++ src/AssetManager.cpp | 5 +++-- src/CollisionHandler.cpp | 9 +++++---- src/GameInternal.cpp | 14 +++++++------- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/include/GameInternal.h b/include/GameInternal.h index 98c8fd1..3850b43 100644 --- a/include/GameInternal.h +++ b/include/GameInternal.h @@ -11,6 +11,7 @@ #include "Vector2D.h" #include "Entity.h" #include "RenderManager.h" +#include "ConfigLoader.h" typedef std::function gamefunction; @@ -48,6 +49,8 @@ public: RenderManager renderManager; Map* map; // game specific, might not be needed for all types of games + ConfigLoader* config; + std::vector& tiles; std::vector& players; std::vector& projectiles; diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index ae8242a..553617a 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -14,6 +14,7 @@ #include "Vector2D.h" #include "PowerupComponent.h" #include +#include #include "Textures.h" @@ -76,8 +77,8 @@ Vector2D AssetManager::calculateSpawnPosition() { SDL_Rect spawnRect; spawnRect.h = spawnRect.w = 32; - spawnRect.x = rand() % (SCREEN_SIZE_WIDTH - spawnRect.w); - spawnRect.y = rand() % (SCREEN_SIZE_HEIGHT - spawnRect.h); + spawnRect.x = rand() % (VEGO_Game().config->getFinalConfig().at("width").get() - spawnRect.w); + spawnRect.y = rand() % (VEGO_Game().config->getFinalConfig().at("height").get() - spawnRect.h); conflict = false; for (auto cc : this->man->getGame()->collisionHandler->getColliders({ Entity::GroupLabel::MAPTILES })) { diff --git a/src/CollisionHandler.cpp b/src/CollisionHandler.cpp index 5821303..0177728 100644 --- a/src/CollisionHandler.cpp +++ b/src/CollisionHandler.cpp @@ -10,6 +10,7 @@ #include #include #include +#include IntersectionBitSet CollisionHandler::getIntersection(Entity* entityA, Entity* entityB, Vector2D posModA, Vector2D posModB) { @@ -66,20 +67,20 @@ IntersectionBitSet CollisionHandler::getIntersectionWithBounds(Entity* entity, V // all 4 directions and both sides to allow checking for fully out of bounds if (collider->x + posMod.x < 0 || - collider->x + posMod.x > SCREEN_SIZE_WIDTH) { + collider->x + posMod.x > VEGO_Game().config->getFinalConfig().at("width")) { intersections.set((size_t) Direction::LEFT); } if (collider->x + collider->w + posMod.x < 0 || - collider->x + collider->w + posMod.x > SCREEN_SIZE_WIDTH) + collider->x + collider->w + posMod.x > VEGO_Game().config->getFinalConfig().at("width")) intersections.set((size_t) Direction::RIGHT); if (collider->y + posMod.y < 0 || - collider->y + posMod.y > SCREEN_SIZE_HEIGHT) + collider->y + posMod.y > VEGO_Game().config->getFinalConfig().at("height")) intersections.set((size_t) Direction::UP); if (collider->y + collider->h + posMod.y < 0 || - collider->y + collider->h + posMod.y > SCREEN_SIZE_HEIGHT) + collider->y + collider->h + posMod.y > VEGO_Game().config->getFinalConfig().at("height")) intersections.set((size_t) Direction::DOWN); return intersections; diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 65619f2..3c55148 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -31,13 +31,13 @@ GameInternal::~GameInternal() = default; SDL_AppResult GameInternal::init() { - ConfigLoader* loader = new ConfigLoader(); + config = new ConfigLoader; this->gameInstance = GameFactory::instance().create(this); - loader->setCustomConfig(this->gameInstance->getConfigFilePath()); - loader->init(); + config->setCustomConfig(this->gameInstance->getConfigFilePath()); + config->init(); - json config = loader->getFinalConfig(); + json finalConfig = config->getFinalConfig(); GameInternal::assets = new AssetManager(&manager); GameInternal::textureManager = new TextureManager(&manager); @@ -45,7 +45,7 @@ SDL_AppResult GameInternal::init() GameInternal::collisionHandler = new CollisionHandler(manager); // why does this use a referrence, but AssetManager a pointer? int flags = 0; - if (config.at("fullscreen")) + if (finalConfig.at("fullscreen")) { flags = SDL_WINDOW_FULLSCREEN; } @@ -62,7 +62,7 @@ SDL_AppResult GameInternal::init() return SDL_APP_FAILURE; } - window = SDL_CreateWindow(config.at("title").get().c_str(), config.at("width"), config.at("height"), flags); + window = SDL_CreateWindow(finalConfig.at("title").get().c_str(), finalConfig.at("width"), finalConfig.at("height"), flags); if (!window) { std::cout << "ERROR: Window couldnt be created! " << SDL_GetError() << std::endl; @@ -72,7 +72,7 @@ SDL_AppResult GameInternal::init() // bad SDL_Surface* icon; - if((icon = SDL_LoadBMP(config.at("icon").get().c_str()))) + if((icon = SDL_LoadBMP(finalConfig.at("icon").get().c_str()))) { SDL_SetWindowIcon(window, icon); } From 91f15671c0cfa6d7ca94a651de712562f17d3389 Mon Sep 17 00:00:00 2001 From: freezarite Date: Tue, 17 Dec 2024 16:08:28 +0100 Subject: [PATCH 09/10] fixed pull request issues --- CMakeLists.txt | 7 +++---- config.json | 4 ++-- include/ConfigLoader.h | 4 ++-- include/Game.h | 2 +- src/AssetManager.cpp | 4 ++-- src/CollisionHandler.cpp | 8 ++++---- src/ConfigLoader.cpp | 19 +++++++++---------- src/GameInternal.cpp | 8 +++++--- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b44666..b0764f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,13 +24,11 @@ add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL) -include_directories(extern/nlohmann_json/include) +add_subdirectory(extern/nlohmann_json EXCLUDE_FROM_ALL) file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp) -add_library(${PROJECT_NAME} ${SOURCES} - include/ConfigLoader.h - src/ConfigLoader.cpp) +add_library(${PROJECT_NAME} ${SOURCES}) target_include_directories(${PROJECT_NAME} PUBLIC ${ENGINE_INCLUDE_DIR}) @@ -39,6 +37,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu SDL3_image::SDL3_image-static SDL3_mixer::SDL3_mixer-static SDL3_ttf::SDL3_ttf-static + nlohmann_json::nlohmann_json tmxlite ) diff --git a/config.json b/config.json index 0e0eb80..e4ee3bf 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "fullscreen": false, "title": "VGG (Very Good Game)", - "height": 100, - "width": 100, + "screen_height": 100, + "screen_width": 100, "icon": "./engine/internalAssets/iconImage.bmp" } \ No newline at end of file diff --git a/include/ConfigLoader.h b/include/ConfigLoader.h index 8ba9c55..d92977e 100644 --- a/include/ConfigLoader.h +++ b/include/ConfigLoader.h @@ -17,8 +17,8 @@ public: json getFinalConfig(); private: - json baseConfig; - std::optional customConfig; + + std::optional customConfigPath; json finalConfig; json loadConfigFromJSON(const std::string& path); diff --git a/include/Game.h b/include/Game.h index 75f6713..84e3b8e 100644 --- a/include/Game.h +++ b/include/Game.h @@ -9,7 +9,7 @@ public: virtual void init() = 0; virtual void update(uint_fast16_t diffTime) = 0; - virtual std::optional getConfigFilePath() {return std::nullopt;} + virtual std::optional setConfigFilePath() {return std::nullopt;} GameInternal* gameInternal; //!< \deprecated }; diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 553617a..75e78ec 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -77,8 +77,8 @@ Vector2D AssetManager::calculateSpawnPosition() { SDL_Rect spawnRect; spawnRect.h = spawnRect.w = 32; - spawnRect.x = rand() % (VEGO_Game().config->getFinalConfig().at("width").get() - spawnRect.w); - spawnRect.y = rand() % (VEGO_Game().config->getFinalConfig().at("height").get() - spawnRect.h); + spawnRect.x = rand() % (VEGO_Game().config->getFinalConfig().at("screen_width").get() - spawnRect.w); + spawnRect.y = rand() % (VEGO_Game().config->getFinalConfig().at("screen_height").get() - spawnRect.h); conflict = false; for (auto cc : this->man->getGame()->collisionHandler->getColliders({ Entity::GroupLabel::MAPTILES })) { diff --git a/src/CollisionHandler.cpp b/src/CollisionHandler.cpp index 0177728..d153d0c 100644 --- a/src/CollisionHandler.cpp +++ b/src/CollisionHandler.cpp @@ -67,20 +67,20 @@ IntersectionBitSet CollisionHandler::getIntersectionWithBounds(Entity* entity, V // all 4 directions and both sides to allow checking for fully out of bounds if (collider->x + posMod.x < 0 || - collider->x + posMod.x > VEGO_Game().config->getFinalConfig().at("width")) { + collider->x + posMod.x > VEGO_Game().config->getFinalConfig().at("screen_width")) { intersections.set((size_t) Direction::LEFT); } if (collider->x + collider->w + posMod.x < 0 || - collider->x + collider->w + posMod.x > VEGO_Game().config->getFinalConfig().at("width")) + collider->x + collider->w + posMod.x > VEGO_Game().config->getFinalConfig().at("screen_width")) intersections.set((size_t) Direction::RIGHT); if (collider->y + posMod.y < 0 || - collider->y + posMod.y > VEGO_Game().config->getFinalConfig().at("height")) + collider->y + posMod.y > VEGO_Game().config->getFinalConfig().at("screen_height")) intersections.set((size_t) Direction::UP); if (collider->y + collider->h + posMod.y < 0 || - collider->y + collider->h + posMod.y > VEGO_Game().config->getFinalConfig().at("height")) + collider->y + collider->h + posMod.y > VEGO_Game().config->getFinalConfig().at("screen_height")) intersections.set((size_t) Direction::DOWN); return intersections; diff --git a/src/ConfigLoader.cpp b/src/ConfigLoader.cpp index 65381f5..7b244e4 100644 --- a/src/ConfigLoader.cpp +++ b/src/ConfigLoader.cpp @@ -2,20 +2,21 @@ #include -ConfigLoader::ConfigLoader() { - //TODO: look into adaptive paths for better handling as this requires the implemented game - // to have ./engine in the root folder - baseConfig = loadConfigFromJSON("./engine/config.json"); -} +ConfigLoader::ConfigLoader() {} ConfigLoader::~ConfigLoader() {} void ConfigLoader::init() { - if (!customConfig.has_value()) { + //TODO: look into adaptive paths for better handling as this requires the implemented game + // to have ./engine in the root folder + const json baseConfig = loadConfigFromJSON("./engine/config.json"); + + if (!customConfigPath.has_value()) { finalConfig = baseConfig; return; } - finalConfig = mergeConfigs(baseConfig, customConfig.value()); + + finalConfig = mergeConfigs(baseConfig, loadConfigFromJSON(customConfigPath.value())); } json ConfigLoader::loadConfigFromJSON(const std::string& path) { @@ -32,9 +33,7 @@ json ConfigLoader::loadConfigFromJSON(const std::string& path) { void ConfigLoader::setCustomConfig(const std::optional& path) { - if (path.has_value()) { - customConfig = loadConfigFromJSON(path.value()); - } + customConfigPath = path; } json ConfigLoader::mergeConfigs(json baseConfig, json customConfig) { diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 3c55148..77becb6 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -31,10 +31,10 @@ GameInternal::~GameInternal() = default; SDL_AppResult GameInternal::init() { - config = new ConfigLoader; + config = new ConfigLoader(); this->gameInstance = GameFactory::instance().create(this); - config->setCustomConfig(this->gameInstance->getConfigFilePath()); + config->setCustomConfig(this->gameInstance->setConfigFilePath()); config->init(); json finalConfig = config->getFinalConfig(); @@ -62,7 +62,9 @@ SDL_AppResult GameInternal::init() return SDL_APP_FAILURE; } - window = SDL_CreateWindow(finalConfig.at("title").get().c_str(), finalConfig.at("width"), finalConfig.at("height"), flags); + window = SDL_CreateWindow(finalConfig.at("title").get().c_str(), + finalConfig.at("screen_width"), finalConfig.at("screen_height"), flags); + if (!window) { std::cout << "ERROR: Window couldnt be created! " << SDL_GetError() << std::endl; From 201b5c8b5dfd16da0470b3dae2b4df963b193959 Mon Sep 17 00:00:00 2001 From: freezarite Date: Tue, 14 Jan 2025 19:27:56 +0100 Subject: [PATCH 10/10] added documentation --- include/ConfigLoader.h | 40 ++++++++++++++++++++++++++++++++++++++-- include/Game.h | 9 +++++++++ src/ConfigLoader.cpp | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/include/ConfigLoader.h b/include/ConfigLoader.h index d92977e..6262f2b 100644 --- a/include/ConfigLoader.h +++ b/include/ConfigLoader.h @@ -4,16 +4,52 @@ using json = nlohmann::json; +/*! + * \class ConfigLoader + * \brief Enables configuration of specific engine variables via a custom JSON file. + * + * The Config loader is responsible to handling customization for engine parameters like the + * window icon, window title, ... through json files. + * + * It includes a standard config file and the option to add a custom one by overwriting the setConfigFilePath() + * function within the implementation of the \ref Game class. Those files get merged, with a priorization on + * the parameters set within the custom config file. + * + * + * The currently available config parameters with their default values are: + * \include ../config.json + * + */ + class ConfigLoader { public: ConfigLoader(); ~ConfigLoader(); + /*! + * \brief Creates the final config for the engine + * + * Loads the default config and then creates the final config by either merging + * (if the custom config has been set) or by implementing the standard config (if no custom + * config was set). + * + * \private + */ void init(); - + /*! + * \brief Sets the customConfigPath variable + * + * \param path optional variable that should include the path to the custom config JSON file + * + * \private + */ void setCustomConfig(const std::optional& path); - + /*! + * \brief Gets final configuration + * \return `json` variable containing the final config + * \private + */ json getFinalConfig(); private: diff --git a/include/Game.h b/include/Game.h index 84e3b8e..d4a8e8a 100644 --- a/include/Game.h +++ b/include/Game.h @@ -9,6 +9,15 @@ public: virtual void init() = 0; virtual void update(uint_fast16_t diffTime) = 0; + + /*! + * \brief Sets the path for a custom config file. + * + * Virtual function to be overwritten in the implementation to return the path of a custom config JSON file. + * \sa Layout of the config file is shown in ConfigLoader + * + * \return std::optional + */ virtual std::optional setConfigFilePath() {return std::nullopt;} GameInternal* gameInternal; //!< \deprecated diff --git a/src/ConfigLoader.cpp b/src/ConfigLoader.cpp index 7b244e4..9e9911c 100644 --- a/src/ConfigLoader.cpp +++ b/src/ConfigLoader.cpp @@ -8,7 +8,7 @@ ConfigLoader::~ConfigLoader() {} void ConfigLoader::init() { //TODO: look into adaptive paths for better handling as this requires the implemented game - // to have ./engine in the root folder + // to have ./engine in the root folder (very low prio) const json baseConfig = loadConfigFromJSON("./engine/config.json"); if (!customConfigPath.has_value()) {