From 79c1284193cde1f7a5b61bc598c6ea0000af8b36 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 23 Mar 2021 17:16:36 +0100 Subject: [PATCH] Add asset loader for localize files --- .../Localize/LocalizeCommon.cpp | 0 .../Localize/LocalizeCommon.h | 0 src/ObjCommon/Localize/LocalizeFile.cpp | 10 +++ src/ObjCommon/Localize/LocalizeFile.h | 12 ++++ .../AssetLoading/AssetLoadingManager.cpp | 4 +- src/ObjLoading/AssetLoading/IAssetLoader.h | 4 +- .../IW4/AssetLoaders/AssetLoaderRawFile.cpp | 2 +- .../IW4/AssetLoaders/AssetLoaderRawFile.h | 2 +- .../AssetLoaders/AssetLoaderLocalizeEntry.cpp | 52 ++++++++++++++ .../AssetLoaders/AssetLoaderLocalizeEntry.h | 17 +++++ .../Game/T6/AssetLoaders/AssetLoaderQdb.cpp | 2 +- .../Game/T6/AssetLoaders/AssetLoaderQdb.h | 2 +- .../T6/AssetLoaders/AssetLoaderRawFile.cpp | 2 +- .../Game/T6/AssetLoaders/AssetLoaderRawFile.h | 2 +- .../AssetLoaderScriptParseTree.cpp | 2 +- .../AssetLoaders/AssetLoaderScriptParseTree.h | 2 +- .../Game/T6/AssetLoaders/AssetLoaderSlug.cpp | 2 +- .../Game/T6/AssetLoaders/AssetLoaderSlug.h | 2 +- .../AssetLoaders/AssetLoaderStringTable.cpp | 2 +- .../T6/AssetLoaders/AssetLoaderStringTable.h | 2 +- src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 3 +- .../LocalizeFile/LocalizeFileLexer.cpp | 9 +++ .../Parsing/LocalizeFile/LocalizeFileLexer.h | 9 +++ .../LocalizeFile/LocalizeFileParser.cpp | 38 ++++++++++ .../Parsing/LocalizeFile/LocalizeFileParser.h | 17 +++++ .../LocalizeFile/LocalizeFileParserState.cpp | 12 ++++ .../LocalizeFile/LocalizeFileParserState.h | 22 ++++++ .../LocalizeFile/LocalizeFileReader.cpp | 41 +++++++++++ .../Parsing/LocalizeFile/LocalizeFileReader.h | 25 +++++++ .../Sequence/SequenceLocalizeFileConfig.cpp | 18 +++++ .../Sequence/SequenceLocalizeFileConfig.h | 12 ++++ .../SequenceLocalizeFileConsumeEmptyLines.cpp | 16 +++++ .../SequenceLocalizeFileConsumeEmptyLines.h | 12 ++++ .../SequenceLocalizeFileEndMarker.cpp | 17 +++++ .../Sequence/SequenceLocalizeFileEndMarker.h | 12 ++++ .../SequenceLocalizeFileLanguageValue.cpp | 72 +++++++++++++++++++ .../SequenceLocalizeFileLanguageValue.h | 17 +++++ .../Sequence/SequenceLocalizeFileNotes.cpp | 18 +++++ .../Sequence/SequenceLocalizeFileNotes.h | 12 ++++ .../SequenceLocalizeFileReference.cpp | 20 ++++++ .../Sequence/SequenceLocalizeFileReference.h | 14 ++++ .../Sequence/SequenceLocalizeFileVersion.cpp | 23 ++++++ .../Sequence/SequenceLocalizeFileVersion.h | 14 ++++ .../Dumping/Localize/StringFileDumper.cpp | 3 +- .../AssetDumpers/AssetDumperLocalizeEntry.cpp | 2 +- .../AssetDumpers/AssetDumperLocalizeEntry.cpp | 7 +- .../Simple/Matcher/SimpleMatcherFactory.cpp | 11 +++ .../Simple/Matcher/SimpleMatcherFactory.h | 2 + .../Matcher/SimpleMatcherKeywordPrefix.cpp | 14 ++++ .../Matcher/SimpleMatcherKeywordPrefix.h | 17 +++++ 50 files changed, 609 insertions(+), 23 deletions(-) rename src/{ObjWriting/Dumping => ObjCommon}/Localize/LocalizeCommon.cpp (100%) rename src/{ObjWriting/Dumping => ObjCommon}/Localize/LocalizeCommon.h (100%) create mode 100644 src/ObjCommon/Localize/LocalizeFile.cpp create mode 100644 src/ObjCommon/Localize/LocalizeFile.h create mode 100644 src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.cpp create mode 100644 src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.h create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.cpp create mode 100644 src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.h create mode 100644 src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.cpp create mode 100644 src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.h diff --git a/src/ObjWriting/Dumping/Localize/LocalizeCommon.cpp b/src/ObjCommon/Localize/LocalizeCommon.cpp similarity index 100% rename from src/ObjWriting/Dumping/Localize/LocalizeCommon.cpp rename to src/ObjCommon/Localize/LocalizeCommon.cpp diff --git a/src/ObjWriting/Dumping/Localize/LocalizeCommon.h b/src/ObjCommon/Localize/LocalizeCommon.h similarity index 100% rename from src/ObjWriting/Dumping/Localize/LocalizeCommon.h rename to src/ObjCommon/Localize/LocalizeCommon.h diff --git a/src/ObjCommon/Localize/LocalizeFile.cpp b/src/ObjCommon/Localize/LocalizeFile.cpp new file mode 100644 index 00000000..4617d5d0 --- /dev/null +++ b/src/ObjCommon/Localize/LocalizeFile.cpp @@ -0,0 +1,10 @@ +#include "LocalizeFile.h" + +LocalizeFileEntry::LocalizeFileEntry() += default; + +LocalizeFileEntry::LocalizeFileEntry(std::string key, std::string value) + : m_key(std::move(key)), + m_value(std::move(value)) +{ +} diff --git a/src/ObjCommon/Localize/LocalizeFile.h b/src/ObjCommon/Localize/LocalizeFile.h new file mode 100644 index 00000000..73ac2dad --- /dev/null +++ b/src/ObjCommon/Localize/LocalizeFile.h @@ -0,0 +1,12 @@ +#pragma once +#include + +class LocalizeFileEntry +{ +public: + std::string m_key; + std::string m_value; + + LocalizeFileEntry(); + LocalizeFileEntry(std::string key, std::string value); +}; diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp index 71b139d3..f9df2734 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp +++ b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp @@ -59,14 +59,14 @@ XAssetInfoGeneric* AssetLoadingManager::LoadIgnoredDependency(const asset_type_t XAssetInfoGeneric* AssetLoadingManager::LoadAssetDependency(const asset_type_t assetType, const std::string& assetName, IAssetLoader* loader) { - if (loader->CanLoadFromGdt() && loader->LoadFromGdt(assetName, &m_context, m_context.m_zone->GetMemory(), this)) + if (loader->CanLoadFromGdt() && loader->LoadFromGdt(assetName, &m_context, m_context.m_zone->GetMemory(), this, m_context.m_zone)) { auto* lastDependency = m_last_dependency_loaded; m_last_dependency_loaded = nullptr; return lastDependency; } - if (loader->CanLoadFromRaw() && loader->LoadFromRaw(assetName, m_context.m_raw_search_path, m_context.m_zone->GetMemory(), this)) + if (loader->CanLoadFromRaw() && loader->LoadFromRaw(assetName, m_context.m_raw_search_path, m_context.m_zone->GetMemory(), this, m_context.m_zone)) { auto* lastDependency = m_last_dependency_loaded; m_last_dependency_loaded = nullptr; diff --git a/src/ObjLoading/AssetLoading/IAssetLoader.h b/src/ObjLoading/AssetLoading/IAssetLoader.h index 0a05b719..3b9f26cf 100644 --- a/src/ObjLoading/AssetLoading/IAssetLoader.h +++ b/src/ObjLoading/AssetLoading/IAssetLoader.h @@ -36,12 +36,12 @@ public: return false; } - virtual bool LoadFromGdt(const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager) const + virtual bool LoadFromGdt(const std::string& assetName, IGdtQueryable* gdtQueryable, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { return false; } - virtual bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const + virtual bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { return false; } diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp index 68b9d13f..aaea2db6 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp @@ -20,7 +20,7 @@ bool AssetLoaderRawFile::CanLoadFromRaw() const return true; } -bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const +bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h index b5bc195d..3e5ac6d0 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h @@ -11,6 +11,6 @@ namespace IW4 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; - bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.cpp new file mode 100644 index 00000000..cd838610 --- /dev/null +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.cpp @@ -0,0 +1,52 @@ +#include "AssetLoaderLocalizeEntry.h" + +#include + + +#include "Localize/LocalizeCommon.h" +#include "Parsing/LocalizeFile/LocalizeFileReader.h" + +using namespace T6; + +XAssetInfoGeneric* AssetLoaderLocalizeEntry::LoadFromGlobalAssetPools(const std::string& assetName) const +{ + return nullptr; +} + +void* AssetLoaderLocalizeEntry::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + return nullptr; +} + +bool AssetLoaderLocalizeEntry::CanLoadFromRaw() const +{ + return true; +} + +bool AssetLoaderLocalizeEntry::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const +{ + std::string fileName; + { + std::ostringstream str; + str << LocalizeCommon::GetNameOfLanguage(zone->m_language) << "/localizedstrings/" << assetName << ".str"; + fileName = str.str(); + } + + const auto file = searchPath->Open(fileName); + if (!file.IsOpen()) + return false; + + LocalizeFileReader reader(*file.m_stream, assetName, zone->m_language); + const auto localizeEntries = reader.ReadLocalizeFile(); + + for(const auto& entry : localizeEntries) + { + auto* localizeEntry = memory->Create(); + localizeEntry->name = memory->Dup(entry.m_key.c_str()); + localizeEntry->value = memory->Dup(entry.m_value.c_str()); + + manager->AddAsset(ASSET_TYPE_LOCALIZE_ENTRY, entry.m_key, localizeEntry); + } + + return true; +} diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.h new file mode 100644 index 00000000..a2011201 --- /dev/null +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderLocalizeEntry.h @@ -0,0 +1,17 @@ +#pragma once +#include "Game/T6/T6.h" +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" + +namespace T6 +{ + class AssetLoaderLocalizeEntry final : public BasicAssetLoader + { + public: + _NODISCARD XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const override; + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; + _NODISCARD bool CanLoadFromRaw() const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; + }; +} diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.cpp index 3e5a4c17..5508d459 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.cpp @@ -20,7 +20,7 @@ bool AssetLoaderQdb::CanLoadFromRaw() const return true; } -bool AssetLoaderQdb::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const +bool AssetLoaderQdb::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.h index f000d74c..5a4ea355 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.h +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderQdb.h @@ -11,6 +11,6 @@ namespace T6 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; - bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp index a909ffcc..e4ce9789 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp @@ -20,7 +20,7 @@ bool AssetLoaderRawFile::CanLoadFromRaw() const return true; } -bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const +bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h index 1e9ce61c..f233aecf 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h @@ -11,6 +11,6 @@ namespace T6 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; - bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.cpp index 491ab97d..eeaffa41 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.cpp @@ -20,7 +20,7 @@ bool AssetLoaderScriptParseTree::CanLoadFromRaw() const return true; } -bool AssetLoaderScriptParseTree::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const +bool AssetLoaderScriptParseTree::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.h index f07ffae2..6092b6a8 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.h +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderScriptParseTree.h @@ -11,6 +11,6 @@ namespace T6 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; - bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.cpp index 38bae296..b1d42555 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.cpp @@ -20,7 +20,7 @@ bool AssetLoaderSlug::CanLoadFromRaw() const return true; } -bool AssetLoaderSlug::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const +bool AssetLoaderSlug::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.h index 8c3586ad..83f2d030 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.h +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSlug.h @@ -11,6 +11,6 @@ namespace T6 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; - bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp index f5f85b27..5ee2d766 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp @@ -22,7 +22,7 @@ bool AssetLoaderStringTable::CanLoadFromRaw() const return true; } -bool AssetLoaderStringTable::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const +bool AssetLoaderStringTable::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.h index 2da2c444..40be6faf 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.h +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.h @@ -11,6 +11,6 @@ namespace T6 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; - bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 164c245e..d023f715 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -4,6 +4,7 @@ #include "Game/T6/GameAssetPoolT6.h" #include "ObjContainer/IPak/IPak.h" #include "ObjLoading.h" +#include "AssetLoaders/AssetLoaderLocalizeEntry.h" #include "AssetLoaders/AssetLoaderQdb.h" #include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoaders/AssetLoaderScriptParseTree.h" @@ -46,7 +47,7 @@ namespace T6 REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_FONTICON, FontIcon)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENULIST, MenuList)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_MENU, menuDef_t)) - REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry)) + REGISTER_ASSET_LOADER(AssetLoaderLocalizeEntry) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_WEAPON, WeaponVariantDef)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT, WeaponAttachment)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_ATTACHMENT_UNIQUE, WeaponAttachmentUnique)) diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.cpp b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.cpp new file mode 100644 index 00000000..358a83f9 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.cpp @@ -0,0 +1,9 @@ +#include "LocalizeFileLexer.h" + +LocalizeFileLexer::LocalizeFileLexer(IParserLineStream* stream) + : SimpleLexer(stream) +{ + SetShouldEmitNewLineTokens(true); + SetShouldReadNumbers(false); + SetShouldReadStrings(true); +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.h b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.h new file mode 100644 index 00000000..57a85244 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileLexer.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Parsing/Simple/SimpleLexer.h" + +class LocalizeFileLexer final : public SimpleLexer +{ +public: + explicit LocalizeFileLexer(IParserLineStream* stream); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.cpp b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.cpp new file mode 100644 index 00000000..356e6980 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.cpp @@ -0,0 +1,38 @@ +#include "LocalizeFileParser.h" + +#include "Sequence/SequenceLocalizeFileConfig.h" +#include "Sequence/SequenceLocalizeFileConsumeEmptyLines.h" +#include "Sequence/SequenceLocalizeFileEndMarker.h" +#include "Sequence/SequenceLocalizeFileLanguageValue.h" +#include "Sequence/SequenceLocalizeFileNotes.h" +#include "Sequence/SequenceLocalizeFileReference.h" +#include "Sequence/SequenceLocalizeFileVersion.h" + +LocalizeFileParser::LocalizeFileParser(SimpleLexer* lexer, GameLanguage language) + : AbstractParser(lexer, std::make_unique(language)) +{ +} + +const std::vector::sequence_t*>& LocalizeFileParser::GetTestsForState() +{ + static std::vector tests({ + new SequenceLocalizeFileReference(), + new SequenceLocalizeFileConfig(), + new SequenceLocalizeFileNotes(), + new SequenceLocalizeFileVersion(), + new SequenceLocalizeFileEndMarker(), + new SequenceLocalizeFileLanguageValue(), + new SequenceLocalizeFileConsumeEmptyLines() + }); + + static std::vector noTests({ + new SequenceLocalizeFileConsumeEmptyLines() + }); + + return !m_state->m_end ? tests : noTests; +} + +std::vector LocalizeFileParser::GetParsedValues() +{ + return std::move(m_state->m_entries); +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.h b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.h new file mode 100644 index 00000000..b730d503 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParser.h @@ -0,0 +1,17 @@ +#pragma once + +#include "LocalizeFileParserState.h" +#include "Game/GameLanguage.h" +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Impl/AbstractParser.h" + +class LocalizeFileParser final : public AbstractParser +{ +protected: + const std::vector& GetTestsForState() override; + +public: + LocalizeFileParser(SimpleLexer* lexer, GameLanguage language); + std::vector GetParsedValues(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.cpp b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.cpp new file mode 100644 index 00000000..803081ec --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.cpp @@ -0,0 +1,12 @@ +#include "LocalizeFileParserState.h" + +#include "Localize/LocalizeCommon.h" + +LocalizeFileParserState::LocalizeFileParserState(const GameLanguage language) + : m_end(false), + m_language(language) +{ + m_language_name_caps = LocalizeCommon::GetNameOfLanguage(m_language); + for (auto& c : m_language_name_caps) + c = static_cast(toupper(c)); +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.h b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.h new file mode 100644 index 00000000..d8f01b01 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileParserState.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include + +#include "Game/GameLanguage.h" +#include "Localize/LocalizeFile.h" + +class LocalizeFileParserState +{ +public: + bool m_end; + + std::vector m_entries; + + GameLanguage m_language; + std::string m_language_name_caps; + + std::string m_current_reference; + std::unordered_set m_current_reference_languages; + + explicit LocalizeFileParserState(GameLanguage language); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.cpp b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.cpp new file mode 100644 index 00000000..14451a71 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.cpp @@ -0,0 +1,41 @@ +#include "LocalizeFileReader.h" + +#include "LocalizeFileLexer.h" +#include "LocalizeFileParser.h" +#include "Parsing/Impl/CommentRemovingStreamProxy.h" +#include "Parsing/Impl/ParserInputStream.h" + +LocalizeFileReader::LocalizeFileReader(std::istream& stream, std::string fileName, GameLanguage language) + : m_file_name(std::move(fileName)), + m_stream(nullptr), + m_language(language) +{ + OpenBaseStream(stream); + SetupStreamProxies(); + m_stream = m_open_streams.back().get(); +} + +bool LocalizeFileReader::OpenBaseStream(std::istream& stream) +{ + m_open_streams.emplace_back(std::make_unique(stream, m_file_name)); + return true; +} + +void LocalizeFileReader::SetupStreamProxies() +{ + m_open_streams.emplace_back(std::make_unique(m_open_streams.back().get())); + + m_stream = m_open_streams.back().get(); +} + +std::vector LocalizeFileReader::ReadLocalizeFile() +{ + const auto lexer = std::make_unique(m_stream); + const auto parser = std::make_unique(lexer.get(), m_language); + + if (parser->Parse()) + return parser->GetParsedValues(); + + std::cout << "Parsing localization file failed!" << std::endl; + return std::vector(); +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.h b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.h new file mode 100644 index 00000000..43645efd --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/LocalizeFileReader.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +#include "Game/GameLanguage.h" +#include "Localize/LocalizeFile.h" +#include "Parsing/IParserLineStream.h" + +class LocalizeFileReader +{ + std::string m_file_name; + IParserLineStream* m_stream; + std::vector> m_open_streams; + GameLanguage m_language; + + bool OpenBaseStream(std::istream& stream); + void SetupStreamProxies(); + +public: + LocalizeFileReader(std::istream& stream, std::string fileName, GameLanguage language); + + std::vector ReadLocalizeFile(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.cpp new file mode 100644 index 00000000..a8c0e2b2 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.cpp @@ -0,0 +1,18 @@ +#include "SequenceLocalizeFileConfig.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileConfig::SequenceLocalizeFileConfig() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("CONFIG"), + create.String(), + create.Type(SimpleParserValueType::NEW_LINE) + }); +} + +void SequenceLocalizeFileConfig::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.h new file mode 100644 index 00000000..a17bd0c9 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConfig.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileConfig final : public LocalizeFileParser::sequence_t +{ +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileConfig(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.cpp new file mode 100644 index 00000000..e9fe0e28 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.cpp @@ -0,0 +1,16 @@ +#include "SequenceLocalizeFileConsumeEmptyLines.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileConsumeEmptyLines::SequenceLocalizeFileConsumeEmptyLines() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Type(SimpleParserValueType::NEW_LINE) + }); +} + +void SequenceLocalizeFileConsumeEmptyLines::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.h new file mode 100644 index 00000000..6f3b0e9e --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileConsumeEmptyLines.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileConsumeEmptyLines final : public LocalizeFileParser::sequence_t +{ +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileConsumeEmptyLines(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.cpp new file mode 100644 index 00000000..960ce3d1 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.cpp @@ -0,0 +1,17 @@ +#include "SequenceLocalizeFileEndMarker.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileEndMarker::SequenceLocalizeFileEndMarker() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("ENDMARKER") + }); +} + +void SequenceLocalizeFileEndMarker::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ + state->m_end = true; +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.h new file mode 100644 index 00000000..6c77f1ea --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileEndMarker.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileEndMarker final : public LocalizeFileParser::sequence_t +{ +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileEndMarker(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.cpp new file mode 100644 index 00000000..eff5fae0 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.cpp @@ -0,0 +1,72 @@ +#include "SequenceLocalizeFileLanguageValue.h" + +#include + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileLanguageValue::SequenceLocalizeFileLanguageValue() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.KeywordPrefix("LANG_").Capture(CAPTURE_LANGUAGE_NAME), + create.String().Capture(CAPTURE_ENTRY_VALUE), + create.Type(SimpleParserValueType::NEW_LINE) + }); +} + +std::string SequenceLocalizeFileLanguageValue::UnescapeValue(const std::string& value) +{ + std::ostringstream str; + + auto isEscaped = false; + for(auto c : value) + { + if(isEscaped) + { + switch(c) + { + case 'n': + str << '\n'; + break; + + case 'r': + str << '\r'; + break; + + default: + str << c; + break; + } + } + else if(c == '\\') + { + isEscaped = true; + } + else + { + str << c; + } + } + + return str.str(); +} + +void SequenceLocalizeFileLanguageValue::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ + const auto& langToken = result.NextCapture(CAPTURE_LANGUAGE_NAME); + const auto& valueToken = result.NextCapture(CAPTURE_ENTRY_VALUE); + + const auto langName = langToken.IdentifierValue().substr(std::char_traits::length("LANG_")); + const auto alreadyDefinedLanguage = state->m_current_reference_languages.find(langName); + if(alreadyDefinedLanguage != state->m_current_reference_languages.end()) + { + std::ostringstream str; + str << "Value for reference \"" << state->m_current_reference << "\" already defined for language \"" << langToken.IdentifierValue() << "\""; + throw ParsingException(langToken.GetPos(), str.str()); + } + state->m_current_reference_languages.emplace(langName); + + if(langName == state->m_language_name_caps) + state->m_entries.emplace_back(state->m_current_reference, UnescapeValue(valueToken.StringValue())); +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.h new file mode 100644 index 00000000..ffe2dbe1 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileLanguageValue.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileLanguageValue final : public LocalizeFileParser::sequence_t +{ + static constexpr auto CAPTURE_LANGUAGE_NAME = 1; + static constexpr auto CAPTURE_ENTRY_VALUE = 2; + + static std::string UnescapeValue(const std::string& value); + +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileLanguageValue(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.cpp new file mode 100644 index 00000000..f00d45ec --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.cpp @@ -0,0 +1,18 @@ +#include "SequenceLocalizeFileNotes.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileNotes::SequenceLocalizeFileNotes() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("FILENOTES"), + create.String(), + create.Type(SimpleParserValueType::NEW_LINE) + }); +} + +void SequenceLocalizeFileNotes::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.h new file mode 100644 index 00000000..e36d19c0 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileNotes.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileNotes final : public LocalizeFileParser::sequence_t +{ +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileNotes(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.cpp new file mode 100644 index 00000000..cb20ab81 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.cpp @@ -0,0 +1,20 @@ +#include "SequenceLocalizeFileReference.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileReference::SequenceLocalizeFileReference() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("REFERENCE"), + create.Identifier().Capture(CAPTURE_REFERENCE_NAME), + create.Type(SimpleParserValueType::NEW_LINE) + }); +} + +void SequenceLocalizeFileReference::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ + state->m_current_reference = result.NextCapture(CAPTURE_REFERENCE_NAME).IdentifierValue(); + state->m_current_reference_languages.clear(); +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.h new file mode 100644 index 00000000..c0d78402 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileReference.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileReference final : public LocalizeFileParser::sequence_t +{ + static constexpr auto CAPTURE_REFERENCE_NAME = 1; + +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileReference(); +}; diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.cpp b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.cpp new file mode 100644 index 00000000..0f195c61 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.cpp @@ -0,0 +1,23 @@ +#include "SequenceLocalizeFileVersion.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceLocalizeFileVersion::SequenceLocalizeFileVersion() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Keyword("VERSION"), + create.String().Capture(CAPTURE_VERSION), + create.Type(SimpleParserValueType::NEW_LINE) + }); +} + +void SequenceLocalizeFileVersion::ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const +{ + const auto& versionCapture = result.NextCapture(CAPTURE_VERSION); + if(versionCapture.StringValue() != "1") + { + throw ParsingException(versionCapture.GetPos(), "Localize file needs to be version 1"); + } +} diff --git a/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.h b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.h new file mode 100644 index 00000000..a74fdae8 --- /dev/null +++ b/src/ObjLoading/Parsing/LocalizeFile/Sequence/SequenceLocalizeFileVersion.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Parsing/LocalizeFile/LocalizeFileParser.h" + +class SequenceLocalizeFileVersion final : public LocalizeFileParser::sequence_t +{ + static constexpr auto CAPTURE_VERSION = 1; + +protected: + void ProcessMatch(LocalizeFileParserState* state, SequenceResult& result) const override; + +public: + SequenceLocalizeFileVersion(); +}; diff --git a/src/ObjWriting/Dumping/Localize/StringFileDumper.cpp b/src/ObjWriting/Dumping/Localize/StringFileDumper.cpp index c3741fdc..14d85237 100644 --- a/src/ObjWriting/Dumping/Localize/StringFileDumper.cpp +++ b/src/ObjWriting/Dumping/Localize/StringFileDumper.cpp @@ -44,7 +44,8 @@ void StringFileDumper::WriteLocalizeEntry(const std::string& reference, const st m_stream << "\n"; m_stream << "REFERENCE " << reference <<"\n"; - const auto escapedValue = std::regex_replace(value, std::regex("\n"), "\\n"); + auto escapedValue = std::regex_replace(value, std::regex("\n"), "\\n"); + escapedValue = std::regex_replace(escapedValue, std::regex("\r"), "\\r"); const auto valueSpacing = std::string(15 - m_language_caps.length(), ' '); m_stream << "LANG_" << m_language_caps << valueSpacing << "\"" << escapedValue << "\"\n"; diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLocalizeEntry.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLocalizeEntry.cpp index f051d19b..d06bc22f 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLocalizeEntry.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperLocalizeEntry.cpp @@ -3,7 +3,7 @@ #include #include -#include "Dumping/Localize/LocalizeCommon.h" +#include "Localize/LocalizeCommon.h" #include "Dumping/Localize/StringFileDumper.h" using namespace IW4; diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperLocalizeEntry.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperLocalizeEntry.cpp index 7e04ff7b..369a9dce 100644 --- a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperLocalizeEntry.cpp +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperLocalizeEntry.cpp @@ -3,7 +3,7 @@ #include #include -#include "Dumping/Localize/LocalizeCommon.h" +#include "Localize/LocalizeCommon.h" #include "Dumping/Localize/StringFileDumper.h" using namespace T6; @@ -17,13 +17,12 @@ void AssetDumperLocalizeEntry::DumpPool(AssetDumpingContext& context, AssetPool< const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone->m_language); fs::path stringsPath(context.m_base_path); stringsPath.append(language); - stringsPath.append("/localizedstrings"); + stringsPath.append("localizedstrings"); create_directories(stringsPath); auto stringFilePath(stringsPath); - stringFilePath.append(context.m_zone->m_name); - stringFilePath.append(".str"); + stringFilePath.append(context.m_zone->m_name + ".str"); std::ofstream stringFile(stringFilePath, std::fstream::out | std::ofstream::binary); diff --git a/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.cpp b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.cpp index d07edd02..85c9c9b6 100644 --- a/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.cpp +++ b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.cpp @@ -3,6 +3,7 @@ #include "SimpleMatcherAnyCharacterBesides.h" #include "SimpleMatcherCharacter.h" #include "SimpleMatcherKeyword.h" +#include "SimpleMatcherKeywordPrefix.h" #include "SimpleMatcherValueType.h" SimpleMatcherFactory::SimpleMatcherFactory(const IMatcherForLabelSupplier* labelSupplier) @@ -20,11 +21,21 @@ MatcherFactoryWrapper SimpleMatcherFactory::Keyword(std::stri return MatcherFactoryWrapper(std::make_unique(std::move(value))); } +MatcherFactoryWrapper SimpleMatcherFactory::KeywordPrefix(std::string value) const +{ + return MatcherFactoryWrapper(std::make_unique(std::move(value))); +} + MatcherFactoryWrapper SimpleMatcherFactory::Identifier() const { return MatcherFactoryWrapper(std::make_unique(SimpleParserValueType::IDENTIFIER)); } +MatcherFactoryWrapper SimpleMatcherFactory::String() const +{ + return MatcherFactoryWrapper(std::make_unique(SimpleParserValueType::STRING)); +} + MatcherFactoryWrapper SimpleMatcherFactory::Integer() const { return MatcherFactoryWrapper(std::make_unique(SimpleParserValueType::INTEGER)); diff --git a/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.h b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.h index abbec723..668ee2e1 100644 --- a/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.h +++ b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherFactory.h @@ -12,7 +12,9 @@ public: _NODISCARD MatcherFactoryWrapper Type(SimpleParserValueType type) const; _NODISCARD MatcherFactoryWrapper Keyword(std::string value) const; + _NODISCARD MatcherFactoryWrapper KeywordPrefix(std::string value) const; _NODISCARD MatcherFactoryWrapper Identifier() const; + _NODISCARD MatcherFactoryWrapper String() const; _NODISCARD MatcherFactoryWrapper Integer() const; _NODISCARD MatcherFactoryWrapper FloatingPoint() const; _NODISCARD MatcherFactoryWrapper Char(char c) const; diff --git a/src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.cpp b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.cpp new file mode 100644 index 00000000..303ddaf6 --- /dev/null +++ b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.cpp @@ -0,0 +1,14 @@ +#include "SimpleMatcherKeywordPrefix.h" + +SimpleMatcherKeywordPrefix::SimpleMatcherKeywordPrefix(std::string value) + : m_value(std::move(value)) +{ +} + +MatcherResult SimpleMatcherKeywordPrefix::CanMatch(ILexer* lexer, const unsigned tokenOffset) +{ + const auto& token = lexer->GetToken(tokenOffset); + return token.m_type == SimpleParserValueType::IDENTIFIER && token.IdentifierValue().compare(0, m_value.size(), m_value) == 0 + ? MatcherResult::Match(1) + : MatcherResult::NoMatch(); +} diff --git a/src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.h b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.h new file mode 100644 index 00000000..29bc1941 --- /dev/null +++ b/src/Parser/Parsing/Simple/Matcher/SimpleMatcherKeywordPrefix.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Matcher/AbstractMatcher.h" + +class SimpleMatcherKeywordPrefix final : public AbstractMatcher +{ + std::string m_value; + +protected: + MatcherResult CanMatch(ILexer* lexer, unsigned tokenOffset) override; + +public: + explicit SimpleMatcherKeywordPrefix(std::string value); +};