From 0492a87cbd6865d7b6040a44fe58955f5d6beddb Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 24 Jun 2021 16:59:03 +0200 Subject: [PATCH] fix t5 rawfile loader not compressing gsc and csc files as the loader expects it --- .../T5/AssetLoaders/AssetLoaderRawFile.cpp | 74 ++++++++++++++++++- .../Game/T5/AssetLoaders/AssetLoaderRawFile.h | 5 ++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp index 23b4574d..07ab8458 100644 --- a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp @@ -1,12 +1,17 @@ #include "AssetLoaderRawFile.h" #include +#include +#include +#include #include "Game/T5/T5.h" #include "Pool/GlobalAssetPool.h" using namespace T5; +namespace fs = std::filesystem; + void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) { auto* rawFile = memory->Create(); @@ -20,12 +25,60 @@ bool AssetLoaderRawFile::CanLoadFromRaw() const return true; } -bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const +bool AssetLoaderRawFile::LoadGsc(const SearchPathOpenFile& file, const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) { - const auto file = searchPath->Open(assetName); - if (!file.IsOpen()) + const auto uncompressedBuffer = std::make_unique(static_cast(file.m_length + 1)); + file.m_stream->read(uncompressedBuffer.get(), file.m_length); + if (file.m_stream->gcount() != file.m_length) return false; + uncompressedBuffer[static_cast(file.m_length)] = '\0'; + const auto compressionBufferSize = static_cast(file.m_length + 1 + sizeof(uint32_t) + sizeof(uint32_t) + COMPRESSED_BUFFER_SIZE_PADDING); + auto* compressedBuffer = static_cast(memory->Alloc(compressionBufferSize)); + + z_stream_s zs{}; + + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = static_cast(file.m_length + 1); + zs.avail_out = compressionBufferSize; + zs.next_in = reinterpret_cast(uncompressedBuffer.get()); + zs.next_out = reinterpret_cast(&compressedBuffer[sizeof(uint32_t) + sizeof(uint32_t)]); + + int ret = deflateInit(&zs, Z_DEFAULT_COMPRESSION); + + if (ret != Z_OK) + { + throw std::runtime_error("Initializing deflate failed"); + } + + ret = deflate(&zs, Z_FINISH); + + if (ret != Z_STREAM_END) + { + std::cout << "Deflate failed for loading gsc file \"" << assetName << "\"" << std::endl; + deflateEnd(&zs); + return false; + } + + const auto compressedSize = compressionBufferSize - zs.avail_out; + + reinterpret_cast(compressedBuffer)[0] = static_cast(file.m_length + 1); // outLen + reinterpret_cast(compressedBuffer)[1] = compressedSize; // inLen + + auto* rawFile = memory->Create(); + rawFile->name = memory->Dup(assetName.c_str()); + rawFile->len = static_cast(compressedSize + sizeof(uint32_t) + sizeof(uint32_t)); + rawFile->buffer = static_cast(compressedBuffer); + + manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile); + + return true; +} + +bool AssetLoaderRawFile::LoadDefault(const SearchPathOpenFile& file, const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) +{ auto* rawFile = memory->Create(); rawFile->name = memory->Dup(assetName.c_str()); rawFile->len = static_cast(file.m_length); @@ -41,3 +94,18 @@ bool AssetLoaderRawFile::LoadFromRaw(const std::string& assetName, ISearchPath* return true; } + +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()) + return false; + + const fs::path rawFilePath(assetName); + const auto extension = rawFilePath.extension().string(); + + if(extension == ".gsc" ||extension == ".csc") + return LoadGsc(file, assetName, searchPath, memory, manager); + + return LoadDefault(file, assetName, searchPath, memory, manager); +} diff --git a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.h index 150ab4ac..5a32e7a1 100644 --- a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.h +++ b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.h @@ -8,6 +8,11 @@ namespace T5 { class AssetLoaderRawFile final : public BasicAssetLoader { + static constexpr size_t COMPRESSED_BUFFER_SIZE_PADDING = 64; + + static bool LoadGsc(const SearchPathOpenFile& file, const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager); + static bool LoadDefault(const SearchPathOpenFile& file, const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager); + public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override;