From 4d37d37fd74854b44f1ae8685267b96866d55e53 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 8 May 2021 14:02:08 +0200 Subject: [PATCH] Add IW4 zone writing --- src/Linker/Game/IW4/ZoneCreatorIW4.cpp | 58 ++++++++++++++++++- src/Linker/Game/IW4/ZoneCreatorIW4.h | 2 + .../Game/IW4/ZoneWriterFactoryIW4.cpp | 17 +++++- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp index 92e9c5f0..a9ba22f5 100644 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.cpp +++ b/src/Linker/Game/IW4/ZoneCreatorIW4.cpp @@ -1,5 +1,8 @@ #include "ZoneCreatorIW4.h" +#include + +#include "ObjLoading.h" #include "Game/IW4/GameIW4.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)); } +std::vector ZoneCreator::CreateGdtList(ZoneCreationContext& context) +{ + std::vector 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& 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 { zone->m_pools = std::make_unique(zone, zone->m_priority); @@ -34,10 +64,32 @@ bool ZoneCreator::SupportsGame(const std::string& gameName) const std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const { auto zone = std::make_unique(context.m_zone_name, 0, &g_GameIW4); - zone->m_pools = std::make_unique(zone.get(), zone->m_priority); + CreateZoneAssetPools(zone.get()); - for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) - zone->m_pools->InitPoolDynamic(assetType); + for (const auto& assetEntry : context.m_definition->m_assets) + { + 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(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; } diff --git a/src/Linker/Game/IW4/ZoneCreatorIW4.h b/src/Linker/Game/IW4/ZoneCreatorIW4.h index 79288247..2906af3d 100644 --- a/src/Linker/Game/IW4/ZoneCreatorIW4.h +++ b/src/Linker/Game/IW4/ZoneCreatorIW4.h @@ -12,6 +12,8 @@ namespace IW4 std::unordered_map m_asset_types_by_name; void AddAssetTypeName(asset_type_t assetType, std::string name); + static std::vector CreateGdtList(ZoneCreationContext& context); + bool CreateIgnoredAssetMap(ZoneCreationContext& context, std::unordered_map& ignoredAssetMap) const; void CreateZoneAssetPools(Zone* zone) const; public: diff --git a/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp b/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp index ba60dc26..fd2eb02a 100644 --- a/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp +++ b/src/ZoneWriting/Game/IW4/ZoneWriterFactoryIW4.cpp @@ -1,18 +1,18 @@ #include "ZoneWriterFactoryIW4.h" -#include #include #include "ContentWriterIW4.h" -#include "Utils/ICapturedDataProvider.h" #include "Game/IW4/IW4.h" #include "Game/IW4/GameIW4.h" #include "Game/IW4/ZoneConstantsIW4.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 IW4; @@ -71,9 +71,22 @@ public: SetupBlocks(); + auto contentInMemory = std::make_unique(std::make_unique(), 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(CreateHeaderForParams(isSecure, false))); + m_writer->AddWritingStep(std::make_unique(std::make_unique())); + + // Start of the XFile struct + m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + m_writer->AddWritingStep(std::make_unique(m_zone)); + + // Start of the zone content + m_writer->AddWritingStep(std::make_unique(contentInMemoryPtr)); + // Return the fully setup zoneloader return std::move(m_writer); }