diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp index f94fdf65..6039c361 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp @@ -4,6 +4,9 @@ #include "Pool/GlobalAssetPool.h" #include +#include +#include +#include using namespace IW4; @@ -27,17 +30,50 @@ bool AssetLoaderRawFile::LoadFromRaw( if (!file.IsOpen()) return false; - auto* rawFile = memory->Create(); - rawFile->name = memory->Dup(assetName.c_str()); - rawFile->len = static_cast(file.m_length); - - auto* fileBuffer = static_cast(memory->Alloc(static_cast(file.m_length + 1))); - file.m_stream->read(fileBuffer, file.m_length); + const auto uncompressedBuffer = std::make_unique(static_cast(file.m_length)); + file.m_stream->read(uncompressedBuffer.get(), file.m_length); if (file.m_stream->gcount() != file.m_length) return false; - fileBuffer[rawFile->len] = '\0'; - rawFile->data.buffer = fileBuffer; + const auto compressionBufferSize = static_cast(file.m_length + 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); + zs.avail_out = compressionBufferSize; + zs.next_in = reinterpret_cast(uncompressedBuffer.get()); + zs.next_out = reinterpret_cast(compressedBuffer); + + 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::cerr << "Deflate failed for loading rawfile \"" << assetName << "\"\n"; + deflateEnd(&zs); + return false; + } + + const auto compressedSize = compressionBufferSize - zs.avail_out; + + auto* rawFile = memory->Create(); + rawFile->name = memory->Dup(assetName.c_str()); + rawFile->compressedLen = static_cast(compressedSize); + rawFile->len = static_cast(file.m_length); + rawFile->data.compressedBuffer = static_cast(compressedBuffer); + + deflateEnd(&zs); + manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile); return true; diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h index 2eab62fd..4d5a0b75 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h @@ -8,6 +8,8 @@ namespace IW4 { class AssetLoaderRawFile final : public BasicAssetLoader { + static constexpr size_t COMPRESSED_BUFFER_SIZE_PADDING = 64; + public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; diff --git a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp index a4a54e0d..428a0b9c 100644 --- a/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderRawFile.cpp @@ -59,7 +59,7 @@ bool AssetLoaderRawFile::LoadFromRaw( if (ret != Z_STREAM_END) { - std::cout << "Deflate failed for loading rawfile \"" << assetName << "\"\n"; + std::cerr << "Deflate failed for loading rawfile \"" << assetName << "\"\n"; deflateEnd(&zs); return false; } @@ -72,6 +72,8 @@ bool AssetLoaderRawFile::LoadFromRaw( rawFile->len = static_cast(file.m_length); rawFile->buffer = static_cast(compressedBuffer); + deflateEnd(&zs); + manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile); return true; diff --git a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp index b6857cd6..b4bc7b07 100644 --- a/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/T5/AssetLoaders/AssetLoaderRawFile.cpp @@ -58,7 +58,7 @@ bool AssetLoaderRawFile::LoadGsc( if (ret != Z_STREAM_END) { - std::cout << "Deflate failed for loading gsc file \"" << assetName << "\"\n"; + std::cerr << "Deflate failed for loading gsc file \"" << assetName << "\"\n"; deflateEnd(&zs); return false; } @@ -73,6 +73,8 @@ bool AssetLoaderRawFile::LoadGsc( rawFile->len = static_cast(compressedSize + sizeof(uint32_t) + sizeof(uint32_t)); rawFile->buffer = static_cast(compressedBuffer); + deflateEnd(&zs); + manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile); return true; diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp index fb531982..1c12dada 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp @@ -72,6 +72,8 @@ bool AssetLoaderRawFile::LoadAnimtree( rawFile->len = static_cast(compressedSize); rawFile->buffer = static_cast(compressedBuffer); + deflateEnd(&zs); + manager->AddAsset(ASSET_TYPE_RAWFILE, assetName, rawFile); return true;