diff --git a/CMakeLists.txt b/CMakeLists.txt index 298d9528cb..ec0ca385e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -456,6 +456,22 @@ else () add_executable(dusklight ${DUSK_FILES}) endif () +# Add embedded data to target + +file(GLOB_RECURSE RANDOMIZER_DATA "src/dusk/randomizer/generator/data/*") +set(RANDO_ROOT_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +foreach (RANDOMIZER_FILE IN LISTS RANDOMIZER_DATA) + file(RELATIVE_PATH REL_PATH ${RANDO_ROOT_DATA_DIR} ${RANDOMIZER_FILE}) + if(REL_PATH MATCHES "^src/dusk/randomizer/generator/data/tests") + message(STATUS "Skipping Embed: ${REL_PATH}") + continue() + endif () + + message(STATUS "Embedding File: ${REL_PATH}") + b_embed(dusklight ${REL_PATH}) +endforeach () + target_compile_definitions(dusklight PRIVATE ${GAME_COMPILE_DEFS}) target_include_directories(dusklight PRIVATE ${GAME_INCLUDE_DIRS}) target_link_libraries(dusklight PRIVATE aurora::main ${GAME_LIBS} ${JSYSTEM_LINK_LIBRARIES}) diff --git a/src/dusk/randomizer/game/randomizer_context.cpp b/src/dusk/randomizer/game/randomizer_context.cpp index 69efdcd329..017d30343d 100644 --- a/src/dusk/randomizer/game/randomizer_context.cpp +++ b/src/dusk/randomizer/game/randomizer_context.cpp @@ -1044,7 +1044,7 @@ RandomizerContext WriteSeedData(const std::unique_ptr(); for (const auto& roomNode : stageNode.second) { @@ -1174,7 +1174,7 @@ RandomizerContext WriteSeedData(const std::unique_ptr(); for (const auto& flowNode : groupNode.second) { @@ -1207,7 +1207,7 @@ RandomizerContext WriteSeedData(const std::unique_ptr(); // TODO: Handle multiple languages diff --git a/src/dusk/randomizer/generator/logic/entrance_shuffle.cpp b/src/dusk/randomizer/generator/logic/entrance_shuffle.cpp index 17e6d9a51a..fb08d1d70b 100644 --- a/src/dusk/randomizer/generator/logic/entrance_shuffle.cpp +++ b/src/dusk/randomizer/generator/logic/entrance_shuffle.cpp @@ -37,13 +37,10 @@ namespace randomizer::logic::entrance_shuffle void SetAllEntrancesData(world::World* world) { - auto filepath = RANDO_DATA_PATH "entrance_shuffle_data.yaml"; - utility::file::Verify(filepath); - // Keep track of which double door entrances are together std::unordered_map> coupledDoors = {}; - auto entranceDataTree = LoadYAML(filepath); + auto entranceDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "entrance_shuffle_data.yaml"); for (const auto& entranceDataNode : entranceDataTree) { // Check to make sure all required fields are present diff --git a/src/dusk/randomizer/generator/logic/world.cpp b/src/dusk/randomizer/generator/logic/world.cpp index 74b6b99256..8b12c2713f 100644 --- a/src/dusk/randomizer/generator/logic/world.cpp +++ b/src/dusk/randomizer/generator/logic/world.cpp @@ -88,11 +88,7 @@ namespace randomizer::logic::world void World::BuildItemTable() { LOG_TO_DEBUG("Building Item Table for World " + std::to_string(this->GetID())); - // Check if we can open the file before parsing - auto filepath = RANDO_DATA_PATH "items.yaml"; - utility::file::Verify(filepath); - - auto itemDataTree = LoadYAML(filepath); + auto itemDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "items.yaml"); // Process all nodes of the yaml file. Each node contains one item for (const auto& itemNode : itemDataTree) { @@ -156,11 +152,8 @@ namespace randomizer::logic::world void World::BuildLocationTable() { LOG_TO_DEBUG("Building Location Table for World " + std::to_string(this->GetID())); - // check if we can open the file before parsing because exceptions won't work on console - const auto filepath = RANDO_DATA_PATH "locations.yaml"; - utility::file::Verify(filepath); + auto locationDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "locations.yaml"); - auto locationDataTree = LoadYAML(filepath); // Process all nodes of the yaml file. Each node contains one location int locationIdCounter = 0; for (const auto& locationNode : locationDataTree) @@ -229,11 +222,8 @@ namespace randomizer::logic::world void World::LoadLogicMacros() { LOG_TO_DEBUG("Loading Macros for World " + std::to_string(this->GetID())); - // check if we can open the file before parsing - auto filepath = RANDO_DATA_PATH "macros.yaml"; - utility::file::Verify(filepath); - auto macrosDataTree = LoadYAML(filepath); + auto macrosDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "macros.yaml"); // Process all nodes of the yaml file. Each node contains one macro int macroIdCounter = 0; @@ -261,34 +251,29 @@ namespace randomizer::logic::world std::unordered_set definedEvents = {}; std::unordered_set definedAreas = {}; - // I don't know if directory iterator works on console so all logic files are manually specified here for now - std::string folder = RANDO_DATA_PATH "world/"; - std::list files = { - "Root.yaml", - "overworld/Ordona Province.yaml", - "overworld/Faron Province.yaml", - "overworld/Eldin Province.yaml", - "overworld/Lanayru Province.yaml", - "overworld/Gerudo Desert.yaml", - "overworld/Snowpeak Province.yaml", - "dungeons/Forest Temple.yaml", - "dungeons/Goron Mines.yaml", - "dungeons/Lakebed Temple.yaml", - "dungeons/Arbiters Grounds.yaml", - "dungeons/Snowpeak Ruins.yaml", - "dungeons/Temple of Time.yaml", - "dungeons/City in the Sky.yaml", - "dungeons/Palace of Twilight.yaml", - "dungeons/Hyrule Castle.yaml", - }; + auto files = std::to_array({ + GET_EMBED_DATA(RANDO_DATA_PATH "world/Root.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/overworld/Ordona Province.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/overworld/Faron Province.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/overworld/Eldin Province.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/overworld/Lanayru Province.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/overworld/Gerudo Desert.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/overworld/Snowpeak Province.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Forest Temple.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Goron Mines.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Lakebed Temple.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Arbiters Grounds.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Snowpeak Ruins.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Temple of Time.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/City in the Sky.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Palace of Twilight.yaml"), + GET_EMBED_DATA(RANDO_DATA_PATH "world/dungeons/Hyrule Castle.yaml"), + }); // Loop through and process all files for (const auto& file : files) { - auto filepath = folder + file; - utility::file::Verify(filepath); - - auto worldDataTree = LoadYAML(filepath); + auto worldDataTree = YAML::Load(file); for (const auto& areaNode : worldDataTree) { YAMLVerifyFields(areaNode, "Name"); diff --git a/src/dusk/randomizer/generator/seedgen/settings.cpp b/src/dusk/randomizer/generator/seedgen/settings.cpp index 5c248bfeeb..ba2414277d 100644 --- a/src/dusk/randomizer/generator/seedgen/settings.cpp +++ b/src/dusk/randomizer/generator/seedgen/settings.cpp @@ -219,16 +219,7 @@ namespace randomizer::seedgen::settings std::unique_ptr LoadAllSettingsInfo() { std::unique_ptr settingInfoMap = std::make_unique(); - auto filepath = RANDO_DATA_PATH "settings_list.yaml"; - // check if we can open the file before parsing because exceptions won't work on console - std::ifstream file(filepath); - if (!file.is_open()) - { - throw std::runtime_error(std::string("Could not open ") + filepath); - } - file.close(); - - auto settingsDataTree = LoadYAML(filepath); + auto settingsDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "settings_list.yaml"); // Process all nodes of the yaml file. Each node contains one setting int settingIdCounter = 0; diff --git a/src/dusk/randomizer/generator/utility/text.cpp b/src/dusk/randomizer/generator/utility/text.cpp index d792d06a02..e2923a34f6 100644 --- a/src/dusk/randomizer/generator/utility/text.cpp +++ b/src/dusk/randomizer/generator/utility/text.cpp @@ -207,24 +207,29 @@ namespace randomizer { } static void LoadTextData(TextDatabase& tb) { - std::string dataPath = RANDO_DATA_PATH "text/languages"; - for (const auto& entry : std::filesystem::directory_iterator(dataPath)) { - if (entry.is_regular_file() && entry.path().extension() == ".yaml") { - auto language = string_to_language(entry.path().stem().string()); - auto textData = LoadYAML(entry.path()); - for (const auto& textNode : textData) { - const auto& name = textNode.first.as(); - for (const auto& typeNode : textNode.second) { - auto type = string_to_type(typeNode.first.as()); - auto typeData = typeNode.second; - const auto& text = typeData["Text"].as(); - tb[name][type].mtext[language] = text; - if (typeData["Gender"]) { - tb[name][type].mGender[language] = string_to_gender(typeData["Gender"].as()); - } - if (typeData["Plurality"]) { - tb[name][type].mPlurality[language] = string_to_plurality(typeData["Plurality"].as()); - } + struct LanguageEntry { + std::string language; + std::string languageData; + }; + auto files = std::to_array({ + {"english", GET_EMBED_DATA(RANDO_DATA_PATH "text/languages/english.yaml")}, + }); + + for (const auto& file : files) { + auto language = string_to_language(file.language); + auto textData = LOAD_EMBED_DATA(file.languageData); + for (const auto& textNode : textData) { + const auto& name = textNode.first.as(); + for (const auto& typeNode : textNode.second) { + auto type = string_to_type(typeNode.first.as()); + auto typeData = typeNode.second; + const auto& text = typeData["Text"].as(); + tb[name][type].mtext[language] = text; + if (typeData["Gender"]) { + tb[name][type].mGender[language] = string_to_gender(typeData["Gender"].as()); + } + if (typeData["Plurality"]) { + tb[name][type].mPlurality[language] = string_to_plurality(typeData["Plurality"].as()); } } } diff --git a/src/dusk/randomizer/generator/utility/yaml.hpp b/src/dusk/randomizer/generator/utility/yaml.hpp index 78a7d289fc..aa7c01a248 100644 --- a/src/dusk/randomizer/generator/utility/yaml.hpp +++ b/src/dusk/randomizer/generator/utility/yaml.hpp @@ -4,6 +4,12 @@ #include "../utility/file.hpp" #include "../utility/path.hpp" +#include "battery/embed.hpp" + +#define GET_EMBED_DATA(path) b::embed().str() +#define LOAD_EMBED_DATA(data) YAML::Load(data) + +#define LOAD_EMBED_YAML(path) LOAD_EMBED_DATA(GET_EMBED_DATA(path)) // this wrapper is here to avoid path encoding issues // removes any possible path -> string oddities or the need to open the file manually diff --git a/src/dusk/randomizer/randomizer.cmake b/src/dusk/randomizer/randomizer.cmake index fe958e42f9..ffb5a7bb45 100644 --- a/src/dusk/randomizer/randomizer.cmake +++ b/src/dusk/randomizer/randomizer.cmake @@ -6,7 +6,7 @@ set(RANDO_SAVE_PATH "${CMAKE_BINARY_DIR}/randomizer/") set(GAME_COMPILE_DEFS ${GAME_COMPILE_DEFS} RANDOMIZER_ONLY=${RANDOMIZER_ONLY} RANDO_SAVE_PATH="${RANDO_SAVE_PATH}" - RANDO_DATA_PATH="${CMAKE_SOURCE_DIR}/src/dusk/randomizer/generator/data/") + RANDO_DATA_PATH="src/dusk/randomizer/generator/data/") if(RANDO_ERROR_LOG) message("Error Log will be saved") @@ -44,7 +44,14 @@ FetchContent_Declare( GIT_TAG v0.2.0-rc0 ) -FetchContent_MakeAvailable(yaml-cpp base64pp) +message(STATUS "randomizer: Fetching battery-embed") +FetchContent_Declare( + battery-embed + GIT_REPOSITORY https://github.com/batterycenter/embed.git + GIT_TAG fdbae3f +) + +FetchContent_MakeAvailable(yaml-cpp base64pp battery-embed) string(LENGTH "${CMAKE_SOURCE_DIR}/" SOURCE_PATH_SIZE) set(GAME_COMPILE_DEFS ${GAME_COMPILE_DEFS} SOURCE_PATH_SIZE=${SOURCE_PATH_SIZE})