Add IW4 zone writing

This commit is contained in:
Jan 2021-05-08 14:02:08 +02:00
parent 843b861b1b
commit 4d37d37fd7
3 changed files with 72 additions and 5 deletions

View File

@ -1,5 +1,8 @@
#include "ZoneCreatorIW4.h" #include "ZoneCreatorIW4.h"
#include <iostream>
#include "ObjLoading.h"
#include "Game/IW4/GameIW4.h" #include "Game/IW4/GameIW4.h"
#include "Game/IW4/GameAssetPoolIW4.h" #include "Game/IW4/GameAssetPoolIW4.h"
@ -18,6 +21,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<GameAssetPoolIW4>(zone, zone->m_priority); zone->m_pools = std::make_unique<GameAssetPoolIW4>(zone, zone->m_priority);
@ -34,10 +64,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_GameIW4); auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameIW4);
zone->m_pools = std::make_unique<GameAssetPoolIW4>(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;
} }

View File

@ -12,6 +12,8 @@ namespace IW4
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:

View File

@ -1,18 +1,18 @@
#include "ZoneWriterFactoryIW4.h" #include "ZoneWriterFactoryIW4.h"
#include <cassert>
#include <cstring> #include <cstring>
#include "ContentWriterIW4.h" #include "ContentWriterIW4.h"
#include "Utils/ICapturedDataProvider.h"
#include "Game/IW4/IW4.h" #include "Game/IW4/IW4.h"
#include "Game/IW4/GameIW4.h" #include "Game/IW4/GameIW4.h"
#include "Game/IW4/ZoneConstantsIW4.h" #include "Game/IW4/ZoneConstantsIW4.h"
#include "Writing/Processor/OutputProcessorDeflate.h"
#include "Writing/Steps/StepAddOutputProcessor.h" #include "Writing/Steps/StepAddOutputProcessor.h"
#include "Writing/Steps/StepWriteXBlockSizes.h" #include "Writing/Steps/StepWriteXBlockSizes.h"
#include "Writing/Steps/StepWriteZoneContentToFile.h" #include "Writing/Steps/StepWriteZoneContentToFile.h"
#include "Writing/Steps/StepWriteZoneContentToMemory.h" #include "Writing/Steps/StepWriteZoneContentToMemory.h"
#include "Writing/Steps/StepWriteZoneHeader.h" #include "Writing/Steps/StepWriteZoneHeader.h"
#include "Writing/Steps/StepWriteZoneSizes.h"
using namespace IW4; using namespace IW4;
@ -71,9 +71,22 @@ public:
SetupBlocks(); 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 // Write zone header
m_writer->AddWritingStep(std::make_unique<StepWriteZoneHeader>(CreateHeaderForParams(isSecure, false))); m_writer->AddWritingStep(std::make_unique<StepWriteZoneHeader>(CreateHeaderForParams(isSecure, false)));
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 the fully setup zoneloader
return std::move(m_writer); return std::move(m_writer);
} }