mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-05-10 06:24:57 +00:00
Add IW3 zone writing
This commit is contained in:
parent
e6a10fb992
commit
687d1185a3
@ -1,5 +1,9 @@
|
|||||||
#include "ZoneCreatorIW3.h"
|
#include "ZoneCreatorIW3.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
#include "AssetLoading/AssetLoadingContext.h"
|
||||||
#include "Game/IW3/GameIW3.h"
|
#include "Game/IW3/GameIW3.h"
|
||||||
#include "Game/IW3/GameAssetPoolIW3.h"
|
#include "Game/IW3/GameAssetPoolIW3.h"
|
||||||
|
|
||||||
@ -18,6 +22,33 @@ void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
|
|||||||
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Gdt*> ZoneCreator::CreateGdtList(ZoneCreationContext& context)
|
||||||
|
{
|
||||||
|
std::vector<Gdt*> gdtList;
|
||||||
|
gdtList.reserve(context.m_gdt_files.size());
|
||||||
|
for (const auto& gdt : context.m_gdt_files)
|
||||||
|
gdtList.push_back(gdt.get());
|
||||||
|
|
||||||
|
return gdtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
|
||||||
|
{
|
||||||
|
for (const auto& ignoreEntry : context.m_ignored_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
||||||
{
|
{
|
||||||
zone->m_pools = std::make_unique<GameAssetPoolIW3>(zone, zone->m_priority);
|
zone->m_pools = std::make_unique<GameAssetPoolIW3>(zone, zone->m_priority);
|
||||||
@ -34,10 +65,32 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const
|
|||||||
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
||||||
{
|
{
|
||||||
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW3);
|
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW3);
|
||||||
zone->m_pools = std::make_unique<GameAssetPoolIW3>(zone.get(), zone->m_priority);
|
CreateZoneAssetPools(zone.get());
|
||||||
|
|
||||||
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
zone->m_pools->InitPoolDynamic(assetType);
|
{
|
||||||
|
if (!assetEntry.m_is_reference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
context.m_ignored_assets.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
|
||||||
|
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return zone;
|
return zone;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ namespace IW3
|
|||||||
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
||||||
|
|
||||||
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
||||||
|
static std::vector<Gdt*> CreateGdtList(ZoneCreationContext& context);
|
||||||
|
bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
|
||||||
void CreateZoneAssetPools(Zone* zone) const;
|
void CreateZoneAssetPools(Zone* zone) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "ObjContainer/IWD/IWD.h"
|
#include "ObjContainer/IWD/IWD.h"
|
||||||
#include "LinkerArgs.h"
|
#include "LinkerArgs.h"
|
||||||
#include "ZoneWriting.h"
|
#include "ZoneWriting.h"
|
||||||
|
#include "Game/IW3/ZoneCreatorIW3.h"
|
||||||
#include "ZoneCreation/ZoneCreationContext.h"
|
#include "ZoneCreation/ZoneCreationContext.h"
|
||||||
#include "ZoneCreation/IZoneCreator.h"
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
#include "Game/IW4/ZoneCreatorIW4.h"
|
#include "Game/IW4/ZoneCreatorIW4.h"
|
||||||
@ -30,6 +31,7 @@ namespace fs = std::filesystem;
|
|||||||
|
|
||||||
const IZoneCreator* const ZONE_CREATORS[]
|
const IZoneCreator* const ZONE_CREATORS[]
|
||||||
{
|
{
|
||||||
|
new IW3::ZoneCreator(),
|
||||||
new IW4::ZoneCreator(),
|
new IW4::ZoneCreator(),
|
||||||
new T6::ZoneCreator()
|
new T6::ZoneCreator()
|
||||||
};
|
};
|
||||||
|
@ -84,13 +84,13 @@ void ZoneDefinitionOutputStream::WriteEntry(const std::string& entryKey, const s
|
|||||||
{
|
{
|
||||||
m_stream << entryKey << ",";
|
m_stream << entryKey << ",";
|
||||||
|
|
||||||
if(entryValue.find('"') != std::string::npos
|
if (entryValue.find('"') != std::string::npos
|
||||||
|| entryValue.find("//") != std::string::npos)
|
|| entryValue.find("//") != std::string::npos)
|
||||||
{
|
{
|
||||||
m_stream << '"';
|
m_stream << '"';
|
||||||
for(const auto& c : entryValue)
|
for (const auto& c : entryValue)
|
||||||
{
|
{
|
||||||
switch(c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '"':
|
case '"':
|
||||||
m_stream << "\\\"";
|
m_stream << "\\\"";
|
||||||
@ -107,6 +107,10 @@ void ZoneDefinitionOutputStream::WriteEntry(const std::string& entryKey, const s
|
|||||||
}
|
}
|
||||||
m_stream << '"';
|
m_stream << '"';
|
||||||
}
|
}
|
||||||
|
else if (entryValue.empty())
|
||||||
|
{
|
||||||
|
m_stream << R"("")";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_stream << entryValue;
|
m_stream << entryValue;
|
||||||
|
@ -85,12 +85,6 @@ public:
|
|||||||
|
|
||||||
SetupBlock(zoneLoader);
|
SetupBlock(zoneLoader);
|
||||||
|
|
||||||
// Skip unknown 1 byte field that the game ignores as well
|
|
||||||
// zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(1));
|
|
||||||
|
|
||||||
// Skip timestamp
|
|
||||||
// zoneLoader->AddLoadingStep(std::make_unique<StepSkipBytes>(8));
|
|
||||||
|
|
||||||
zoneLoader->AddLoadingStep(std::make_unique<StepAddProcessor>(std::make_unique<ProcessorInflate>(ZoneConstants::AUTHED_CHUNK_SIZE)));
|
zoneLoader->AddLoadingStep(std::make_unique<StepAddProcessor>(std::make_unique<ProcessorInflate>(ZoneConstants::AUTHED_CHUNK_SIZE)));
|
||||||
|
|
||||||
// Start of the XFile struct
|
// Start of the XFile struct
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
#include "ZoneWriterFactoryIW3.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "ContentWriterIW3.h"
|
||||||
|
#include "Game/IW3/IW3.h"
|
||||||
|
#include "Game/IW3/GameIW3.h"
|
||||||
|
#include "Game/IW3/ZoneConstantsIW3.h"
|
||||||
|
#include "Writing/Processor/OutputProcessorDeflate.h"
|
||||||
|
#include "Writing/Steps/StepAddOutputProcessor.h"
|
||||||
|
#include "Writing/Steps/StepWriteXBlockSizes.h"
|
||||||
|
#include "Writing/Steps/StepWriteZoneContentToFile.h"
|
||||||
|
#include "Writing/Steps/StepWriteZoneContentToMemory.h"
|
||||||
|
#include "Writing/Steps/StepWriteZoneHeader.h"
|
||||||
|
#include "Writing/Steps/StepWriteZoneSizes.h"
|
||||||
|
|
||||||
|
using namespace IW3;
|
||||||
|
|
||||||
|
class ZoneWriterFactory::Impl
|
||||||
|
{
|
||||||
|
Zone* m_zone;
|
||||||
|
std::unique_ptr<ZoneWriter> m_writer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Impl(Zone* zone)
|
||||||
|
: m_zone(zone),
|
||||||
|
m_writer(std::make_unique<ZoneWriter>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupBlocks() const
|
||||||
|
{
|
||||||
|
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||||
|
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||||
|
m_writer->AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||||
|
|
||||||
|
#undef XBLOCK_DEF
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZoneHeader CreateHeaderForParams()
|
||||||
|
{
|
||||||
|
ZoneHeader header{};
|
||||||
|
header.m_version = ZoneConstants::ZONE_VERSION;
|
||||||
|
memcpy(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, sizeof(ZoneHeader::m_magic));
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ZoneWriter> CreateWriter()
|
||||||
|
{
|
||||||
|
SetupBlocks();
|
||||||
|
|
||||||
|
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(std::make_unique<ContentWriter>(), m_zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
||||||
|
auto* contentInMemoryPtr = contentInMemory.get();
|
||||||
|
m_writer->AddWritingStep(std::move(contentInMemory));
|
||||||
|
|
||||||
|
// Write zone header
|
||||||
|
m_writer->AddWritingStep(std::make_unique<StepWriteZoneHeader>(CreateHeaderForParams()));
|
||||||
|
|
||||||
|
m_writer->AddWritingStep(std::make_unique<StepAddOutputProcessor>(std::make_unique<OutputProcessorDeflate>()));
|
||||||
|
|
||||||
|
// Start of the XFile struct
|
||||||
|
m_writer->AddWritingStep(std::make_unique<StepWriteZoneSizes>(contentInMemoryPtr));
|
||||||
|
m_writer->AddWritingStep(std::make_unique<StepWriteXBlockSizes>(m_zone));
|
||||||
|
|
||||||
|
// Start of the zone content
|
||||||
|
m_writer->AddWritingStep(std::make_unique<StepWriteZoneContentToFile>(contentInMemoryPtr));
|
||||||
|
|
||||||
|
// Return the fully setup zoneloader
|
||||||
|
return std::move(m_writer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ZoneWriterFactory::SupportsZone(Zone* zone) const
|
||||||
|
{
|
||||||
|
return zone->m_game == &g_GameIW3;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(Zone* zone) const
|
||||||
|
{
|
||||||
|
Impl impl(zone);
|
||||||
|
return impl.CreateWriter();
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Writing/IZoneWriterFactory.h"
|
||||||
|
|
||||||
|
namespace IW3
|
||||||
|
{
|
||||||
|
class ZoneWriterFactory final : public IZoneWriterFactory
|
||||||
|
{
|
||||||
|
class Impl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
_NODISCARD bool SupportsZone(Zone* zone) const override;
|
||||||
|
_NODISCARD std::unique_ptr<ZoneWriter> CreateWriter(Zone* zone) const override;
|
||||||
|
};
|
||||||
|
}
|
138
src/ZoneWriting/Writing/Processor/OutputProcessorDeflate.cpp
Normal file
138
src/ZoneWriting/Writing/Processor/OutputProcessorDeflate.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#include "OutputProcessorDeflate.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
|
#include "Writing/WritingException.h"
|
||||||
|
|
||||||
|
class OutputProcessorDeflate::Impl
|
||||||
|
{
|
||||||
|
z_stream m_stream{};
|
||||||
|
OutputProcessorDeflate* m_base;
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> m_buffer;
|
||||||
|
size_t m_buffer_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Impl(OutputProcessorDeflate* baseClass, const size_t bufferSize)
|
||||||
|
: m_buffer(std::make_unique<uint8_t[]>(bufferSize)),
|
||||||
|
m_buffer_size(bufferSize)
|
||||||
|
{
|
||||||
|
m_base = baseClass;
|
||||||
|
|
||||||
|
m_stream.zalloc = Z_NULL;
|
||||||
|
m_stream.zfree = Z_NULL;
|
||||||
|
m_stream.opaque = Z_NULL;
|
||||||
|
m_stream.avail_in = 0;
|
||||||
|
m_stream.next_in = Z_NULL;
|
||||||
|
m_stream.next_out = m_buffer.get();
|
||||||
|
m_stream.avail_out = m_buffer_size;
|
||||||
|
|
||||||
|
const int ret = deflateInit(&m_stream, Z_DEFAULT_COMPRESSION);
|
||||||
|
|
||||||
|
if (ret != Z_OK)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Initializing deflate failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Impl()
|
||||||
|
{
|
||||||
|
deflateEnd(&m_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
Impl(const Impl& other) = delete;
|
||||||
|
Impl(Impl&& other) noexcept = default;
|
||||||
|
Impl& operator=(const Impl& other) = delete;
|
||||||
|
Impl& operator=(Impl&& other) noexcept = default;
|
||||||
|
|
||||||
|
void Write(const void* buffer, const size_t length)
|
||||||
|
{
|
||||||
|
m_stream.next_in = static_cast<const Bytef*>(buffer);
|
||||||
|
m_stream.avail_in = length;
|
||||||
|
|
||||||
|
while (m_stream.avail_in > 0)
|
||||||
|
{
|
||||||
|
if (m_stream.avail_out == 0)
|
||||||
|
{
|
||||||
|
m_base->m_base_stream->Write(m_buffer.get(), m_buffer_size);
|
||||||
|
m_stream.next_out = m_buffer.get();
|
||||||
|
m_stream.avail_out = m_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ret = deflate(&m_stream, Z_NO_FLUSH);
|
||||||
|
if (ret != Z_OK)
|
||||||
|
throw WritingException("Failed to deflate memory of zone.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Flush()
|
||||||
|
{
|
||||||
|
m_stream.avail_in = 0;
|
||||||
|
m_stream.next_in = Z_NULL;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
if (m_stream.avail_out < m_buffer_size)
|
||||||
|
{
|
||||||
|
m_base->m_base_stream->Write(m_buffer.get(), m_buffer_size - m_stream.avail_out);
|
||||||
|
m_stream.next_out = m_buffer.get();
|
||||||
|
m_stream.avail_out = m_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ret = deflate(&m_stream, Z_FINISH);
|
||||||
|
if(ret == Z_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ret != Z_STREAM_END)
|
||||||
|
throw WritingException("Failed to flush deflate memory of zone.");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_stream.avail_out < m_buffer_size)
|
||||||
|
{
|
||||||
|
m_base->m_base_stream->Write(m_buffer.get(), m_buffer_size - m_stream.avail_out);
|
||||||
|
m_stream.next_out = m_buffer.get();
|
||||||
|
m_stream.avail_out = m_buffer_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_NODISCARD int64_t Pos() const
|
||||||
|
{
|
||||||
|
return m_base->m_base_stream->Pos();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OutputProcessorDeflate::OutputProcessorDeflate()
|
||||||
|
: m_impl(new Impl(this, DEFAULT_BUFFER_SIZE))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputProcessorDeflate::OutputProcessorDeflate(const size_t bufferSize)
|
||||||
|
: m_impl(new Impl(this, bufferSize))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputProcessorDeflate::~OutputProcessorDeflate()
|
||||||
|
{
|
||||||
|
delete m_impl;
|
||||||
|
m_impl = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputProcessorDeflate::Write(const void* buffer, const size_t length)
|
||||||
|
{
|
||||||
|
m_impl->Write(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputProcessorDeflate::Flush()
|
||||||
|
{
|
||||||
|
m_impl->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t OutputProcessorDeflate::Pos()
|
||||||
|
{
|
||||||
|
return m_impl->Pos();
|
||||||
|
}
|
26
src/ZoneWriting/Writing/Processor/OutputProcessorDeflate.h
Normal file
26
src/ZoneWriting/Writing/Processor/OutputProcessorDeflate.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Writing/OutputStreamProcessor.h"
|
||||||
|
|
||||||
|
class OutputProcessorDeflate final : public OutputStreamProcessor
|
||||||
|
{
|
||||||
|
class Impl;
|
||||||
|
Impl* m_impl;
|
||||||
|
|
||||||
|
static constexpr size_t DEFAULT_BUFFER_SIZE = 0x40000;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OutputProcessorDeflate();
|
||||||
|
OutputProcessorDeflate(size_t bufferSize);
|
||||||
|
~OutputProcessorDeflate() override;
|
||||||
|
OutputProcessorDeflate(const OutputProcessorDeflate& other) = delete;
|
||||||
|
OutputProcessorDeflate(OutputProcessorDeflate&& other) noexcept = default;
|
||||||
|
OutputProcessorDeflate& operator=(const OutputProcessorDeflate& other) = delete;
|
||||||
|
OutputProcessorDeflate& operator=(OutputProcessorDeflate&& other) noexcept = default;
|
||||||
|
|
||||||
|
void Write(const void* buffer, size_t length) override;
|
||||||
|
void Flush() override;
|
||||||
|
int64_t Pos() override;
|
||||||
|
};
|
@ -1,11 +1,13 @@
|
|||||||
#include "ZoneWriting.h"
|
#include "ZoneWriting.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/ZoneWriterFactoryIW3.h"
|
||||||
#include "Game/IW4/ZoneWriterFactoryIW4.h"
|
#include "Game/IW4/ZoneWriterFactoryIW4.h"
|
||||||
#include "Game/T6/ZoneWriterFactoryT6.h"
|
#include "Game/T6/ZoneWriterFactoryT6.h"
|
||||||
#include "Writing/IZoneWriterFactory.h"
|
#include "Writing/IZoneWriterFactory.h"
|
||||||
|
|
||||||
IZoneWriterFactory* ZoneWriterFactories[]
|
IZoneWriterFactory* ZoneWriterFactories[]
|
||||||
{
|
{
|
||||||
|
new IW3::ZoneWriterFactory(),
|
||||||
new IW4::ZoneWriterFactory(),
|
new IW4::ZoneWriterFactory(),
|
||||||
new T6::ZoneWriterFactory()
|
new T6::ZoneWriterFactory()
|
||||||
};
|
};
|
||||||
@ -15,7 +17,7 @@ bool ZoneWriting::WriteZone(std::ostream& stream, Zone* zone)
|
|||||||
std::unique_ptr<ZoneWriter> zoneWriter;
|
std::unique_ptr<ZoneWriter> zoneWriter;
|
||||||
for (auto* factory : ZoneWriterFactories)
|
for (auto* factory : ZoneWriterFactories)
|
||||||
{
|
{
|
||||||
if(factory->SupportsZone(zone))
|
if (factory->SupportsZone(zone))
|
||||||
{
|
{
|
||||||
zoneWriter = factory->CreateWriter(zone);
|
zoneWriter = factory->CreateWriter(zone);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user