diff --git a/src/ObjLoading/Game/T6/FontIcon/LoaderFontIconT6.cpp b/src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.cpp similarity index 96% rename from src/ObjLoading/Game/T6/FontIcon/LoaderFontIconT6.cpp rename to src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.cpp index 43cde72c..ca53435b 100644 --- a/src/ObjLoading/Game/T6/FontIcon/LoaderFontIconT6.cpp +++ b/src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.cpp @@ -1,4 +1,4 @@ -#include "LoaderFontIconT6.h" +#include "CsvLoaderFontIconT6.h" #include "Csv/CsvStream.h" #include "Game/T6/CommonT6.h" @@ -30,10 +30,10 @@ namespace constexpr unsigned COL_COUNT_ALIAS = 4; constexpr unsigned COL_COUNT_MIN = std::min(COL_COUNT_ICON, COL_COUNT_ALIAS); - class FontIconLoader final : public AssetCreator + class CsvFontIconLoader final : public AssetCreator { public: - FontIconLoader(MemoryManager& memory, ISearchPath& searchPath) + CsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath) : m_memory(memory), m_search_path(searchPath) { @@ -284,8 +284,8 @@ namespace namespace T6 { - std::unique_ptr> CreateFontIconLoader(MemoryManager& memory, ISearchPath& searchPath) + std::unique_ptr> CreateCsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath) { - return std::make_unique(memory, searchPath); + return std::make_unique(memory, searchPath); } } // namespace T6 diff --git a/src/ObjLoading/Game/T6/FontIcon/LoaderFontIconT6.h b/src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.h similarity index 61% rename from src/ObjLoading/Game/T6/FontIcon/LoaderFontIconT6.h rename to src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.h index e9f658e8..7bb1e58f 100644 --- a/src/ObjLoading/Game/T6/FontIcon/LoaderFontIconT6.h +++ b/src/ObjLoading/Game/T6/FontIcon/CsvLoaderFontIconT6.h @@ -9,5 +9,5 @@ namespace T6 { - std::unique_ptr> CreateFontIconLoader(MemoryManager& memory, ISearchPath& searchPath); + std::unique_ptr> CreateCsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath); } // namespace T6 diff --git a/src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.cpp b/src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.cpp new file mode 100644 index 00000000..002e778c --- /dev/null +++ b/src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.cpp @@ -0,0 +1,150 @@ +#include "JsonLoaderFontIconT6.h" + +#include "Game/T6/CommonT6.h" +#include "Game/T6/FontIcon/FontIconCommonT6.h" +#include "Game/T6/FontIcon/JsonFontIconT6.h" +#include "Game/T6/T6.h" + +#include +#include +#include +#include + +using namespace nlohmann; +using namespace T6; + +namespace +{ + class JsonFontIconLoader final : public AssetCreator + { + public: + JsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath) + : m_memory(memory), + m_search_path(searchPath) + { + } + + AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override + { + const auto file = m_search_path.Open(font_icon::GetJsonFileNameForAssetName(assetName)); + if (!file.IsOpen()) + return AssetCreationResult::NoAction(); + + auto* fontIcon = m_memory.Alloc(); + fontIcon->name = m_memory.Dup(assetName.c_str()); + AssetRegistration registration(assetName, fontIcon); + + try + { + const auto jRoot = json::parse(*file.m_stream); + std::string type; + unsigned version; + + jRoot.at("_type").get_to(type); + jRoot.at("_version").get_to(version); + + if (type != "font-icon" || version != 1u) + { + std::cerr << std::format("Tried to load font icon \"{}\" but did not find expected type font-icon of version 1\n", assetName); + return AssetCreationResult::Failure(); + } + + const auto jFontIcon = jRoot.get(); + if (CreateFontIconFromJson(jFontIcon, *fontIcon, registration, context)) + return AssetCreationResult::Success(context.AddAsset(std::move(registration))); + } + catch (const json::exception& e) + { + std::cerr << std::format("Failed to parse json of font icon: {}\n", e.what()); + } + + return AssetCreationResult::Failure(); + } + + private: + bool CreateFontIconFromJson(const JsonFontIcon& jFontIcon, + FontIcon& fontIcon, + AssetRegistration& registration, + AssetCreationContext& context) const + { + std::vector aliases; + + fontIcon.numEntries = static_cast(jFontIcon.entries.size()); + fontIcon.fontIconEntry = m_memory.Alloc(fontIcon.numEntries); + + for (auto entryIndex = 0u; entryIndex < fontIcon.numEntries; entryIndex++) + { + if (!CreateFontIconEntryFromJson(jFontIcon.entries[entryIndex], fontIcon.fontIconEntry[entryIndex], aliases, registration, context)) + return false; + } + + std::sort(fontIcon.fontIconEntry, + &fontIcon.fontIconEntry[fontIcon.numEntries], + [](const FontIconEntry& e0, const FontIconEntry& e1) -> bool + { + return e0.fontIconName.hash < e1.fontIconName.hash; + }); + + if (!aliases.empty()) + { + fontIcon.numAliasEntries = static_cast(aliases.size()); + fontIcon.fontIconAlias = m_memory.Alloc(fontIcon.numAliasEntries); + std::memcpy(fontIcon.fontIconAlias, aliases.data(), sizeof(FontIconAlias) * fontIcon.numAliasEntries); + + std::sort(fontIcon.fontIconAlias, + &fontIcon.fontIconAlias[fontIcon.numAliasEntries], + [](const FontIconAlias& a0, const FontIconAlias& a1) -> bool + { + return a0.aliasHash < a1.aliasHash; + }); + } + + return true; + } + + bool CreateFontIconEntryFromJson(const JsonFontIconEntry& jFontIconEntry, + FontIconEntry& fontIconEntry, + std::vector& aliases, + AssetRegistration& registration, + AssetCreationContext& context) const + { + fontIconEntry.fontIconName.string = m_memory.Dup(jFontIconEntry.name.c_str()); + fontIconEntry.fontIconName.hash = Common::Com_HashString(jFontIconEntry.name.c_str()); + + auto* materialDependency = context.LoadDependency(jFontIconEntry.material); + if (materialDependency == nullptr) + { + std::cerr << std::format("Failed to load material \"{}\" for font icon entry \"{}\"\n", jFontIconEntry.material, jFontIconEntry.name); + return false; + } + registration.AddDependency(materialDependency); + fontIconEntry.fontIconMaterialHandle = materialDependency->Asset(); + + fontIconEntry.fontIconSize = static_cast(jFontIconEntry.size); + fontIconEntry.xScale = jFontIconEntry.scale.has_value() ? jFontIconEntry.scale->x : 0; + fontIconEntry.yScale = jFontIconEntry.scale.has_value() ? jFontIconEntry.scale->y : 0; + + for (const auto& alias : jFontIconEntry.aliases) + aliases.emplace_back(Common::Com_HashString(alias.c_str()), fontIconEntry.fontIconName.hash); + + if (jFontIconEntry.aliasHashes.has_value()) + { + for (const auto aliasHash : *jFontIconEntry.aliasHashes) + aliases.emplace_back(aliasHash, fontIconEntry.fontIconName.hash); + } + + return true; + } + + MemoryManager& m_memory; + ISearchPath& m_search_path; + }; +} // namespace + +namespace T6 +{ + std::unique_ptr> CreateJsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath) + { + return std::make_unique(memory, searchPath); + } +} // namespace T6 diff --git a/src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.h b/src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.h new file mode 100644 index 00000000..7938827a --- /dev/null +++ b/src/ObjLoading/Game/T6/FontIcon/JsonLoaderFontIconT6.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Asset/IAssetCreator.h" +#include "Game/T6/T6.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" + +#include + +namespace T6 +{ + std::unique_ptr> CreateJsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath); +} // namespace T6 diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 37afdf89..a1f029f3 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -1,7 +1,8 @@ #include "ObjLoaderT6.h" #include "Asset/GlobalAssetPoolsLoader.h" -#include "FontIcon/LoaderFontIconT6.h" +#include "FontIcon/CsvLoaderFontIconT6.h" +#include "FontIcon/JsonLoaderFontIconT6.h" #include "Game/T6/CommonT6.h" #include "Game/T6/GameAssetPoolT6.h" #include "Game/T6/GameT6.h" @@ -412,7 +413,8 @@ namespace T6 // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); - collection.AddAssetCreator(CreateFontIconLoader(memory, searchPath)); + collection.AddAssetCreator(CreateCsvFontIconLoader(memory, searchPath)); + collection.AddAssetCreator(CreateJsonFontIconLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));