From 87c2e58c4b34d19f6b8744ea71a330e28934bcb0 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 2 Jan 2022 01:34:42 +0100 Subject: [PATCH] Add implementation for stringtable assetloader iw4 --- src/Common/Game/IW4/CommonIW4.cpp | 16 +++++ src/Common/Game/IW4/CommonIW4.h | 2 + .../AssetLoaders/AssetLoaderStringTable.cpp | 62 +++++++++++++++++++ .../IW4/AssetLoaders/AssetLoaderStringTable.h | 2 + .../AssetLoaders/AssetLoaderStringTable.cpp | 5 +- .../AssetLoaders/AssetLoaderStringTable.cpp | 6 +- 6 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/Common/Game/IW4/CommonIW4.cpp b/src/Common/Game/IW4/CommonIW4.cpp index 9c010880..6a512836 100644 --- a/src/Common/Game/IW4/CommonIW4.cpp +++ b/src/Common/Game/IW4/CommonIW4.cpp @@ -4,6 +4,22 @@ using namespace IW4; +int Common::StringTable_HashString(const char* str) +{ + if (!str) + return 0; + + auto result = 0; + auto offset = 0; + while (str[offset]) + { + const auto c = tolower(str[offset++]); + result = c + 31 * result; + } + + return result; +} + PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in) { return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast(in))}; diff --git a/src/Common/Game/IW4/CommonIW4.h b/src/Common/Game/IW4/CommonIW4.h index 8357c5e1..053fd47b 100644 --- a/src/Common/Game/IW4/CommonIW4.h +++ b/src/Common/Game/IW4/CommonIW4.h @@ -198,6 +198,8 @@ namespace IW4 class Common { public: + static int StringTable_HashString(const char* str); + static PackedTexCoords Vec2PackTexCoords(const vec2_t* in); static PackedUnitVec Vec3PackUnitVec(const vec3_t* in); static GfxColor Vec4PackGfxColor(const vec4_t* in); diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.cpp index a78c1c26..2b5b4b17 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.cpp @@ -3,6 +3,8 @@ #include #include "ObjLoading.h" +#include "Csv/CsvStream.h" +#include "Game/IW4/CommonIW4.h" #include "Game/IW4/IW4.h" #include "Pool/GlobalAssetPool.h" @@ -15,3 +17,63 @@ void* AssetLoaderStringTable::CreateEmptyAsset(const std::string& assetName, Mem stringTable->name = memory->Dup(assetName.c_str()); return stringTable; } + +bool AssetLoaderStringTable::CanLoadFromRaw() const +{ + return true; +} + +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()) + return false; + + auto* stringTable = memory->Create(); + stringTable->name = memory->Dup(assetName.c_str()); + + std::vector> csvLines; + std::vector currentLine; + auto maxCols = 0u; + const CsvInputStream csv(*file.m_stream); + + while (csv.NextRow(currentLine)) + { + if (currentLine.size() > maxCols) + maxCols = currentLine.size(); + csvLines.emplace_back(std::move(currentLine)); + currentLine = std::vector(); + } + + stringTable->columnCount = static_cast(maxCols); + stringTable->rowCount = static_cast(csvLines.size()); + const auto cellCount = static_cast(stringTable->rowCount) * static_cast(stringTable->columnCount); + + if (cellCount) + { + stringTable->values = static_cast(memory->Alloc(sizeof(StringTableCell) * cellCount)); + + for (auto row = 0u; row < csvLines.size(); row++) + { + const auto& rowValues = csvLines[row]; + for (auto col = 0u; col < maxCols; col++) + { + auto& cell = stringTable->values[row * maxCols + col]; + if (col >= rowValues.size() || rowValues[col].empty()) + cell.string = ""; + else + cell.string = memory->Dup(rowValues[col].c_str()); + + cell.hash = Common::StringTable_HashString(cell.string); + } + } + } + else + { + stringTable->values = nullptr; + } + + manager->AddAsset(ASSET_TYPE_STRINGTABLE, assetName, stringTable); + + return true; +} diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.h index 4fb57ceb..79fee191 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStringTable.h @@ -10,5 +10,7 @@ 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, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderStringTable.cpp b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderStringTable.cpp index 81887a8c..986ce669 100644 --- a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderStringTable.cpp +++ b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderStringTable.cpp @@ -41,10 +41,11 @@ bool AssetLoaderStringTable::LoadFromRaw(const std::string& assetName, ISearchPa if (currentLine.size() > maxCols) maxCols = currentLine.size(); csvLines.emplace_back(std::move(currentLine)); + currentLine = std::vector(); } - stringTable->columnCount = maxCols; - stringTable->rowCount = csvLines.size(); + stringTable->columnCount = static_cast(maxCols); + stringTable->rowCount = static_cast(csvLines.size()); const auto cellCount = static_cast(stringTable->rowCount) * static_cast(stringTable->columnCount); if (cellCount) diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp index d8f17744..a1acde61 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderStringTable.cpp @@ -41,10 +41,11 @@ bool AssetLoaderStringTable::LoadFromRaw(const std::string& assetName, ISearchPa if (currentLine.size() > maxCols) maxCols = currentLine.size(); csvLines.emplace_back(std::move(currentLine)); + currentLine = std::vector(); } - stringTable->columnCount = maxCols; - stringTable->rowCount = csvLines.size(); + stringTable->columnCount = static_cast(maxCols); + stringTable->rowCount = static_cast(csvLines.size()); const auto cellCount = static_cast(stringTable->rowCount) * static_cast(stringTable->columnCount); if (cellCount) @@ -70,7 +71,6 @@ bool AssetLoaderStringTable::LoadFromRaw(const std::string& assetName, ISearchPa } } - std::sort(&stringTable->cellIndex[0], &stringTable->cellIndex[cellCount - 1], [stringTable, maxCols](const int16_t a, const int16_t b) { auto compareResult = stringTable->values[a].hash - stringTable->values[b].hash;