mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
Add AssetLoaders for linker that handle asset types for their specific game
This commit is contained in:
parent
792509d11d
commit
b360816190
12
src/Linker/AssetLoading/AssetLoadingContext.cpp
Normal file
12
src/Linker/AssetLoading/AssetLoadingContext.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "AssetLoadingContext.h"
|
||||
|
||||
AssetLoadingContext::AssetLoadingContext()
|
||||
: m_asset_search_path(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
AssetLoadingContext::AssetLoadingContext(std::string zoneName, ISearchPath* assetSearchPath)
|
||||
: m_asset_search_path(assetSearchPath),
|
||||
m_zone_name(std::move(zoneName))
|
||||
{
|
||||
}
|
19
src/Linker/AssetLoading/AssetLoadingContext.h
Normal file
19
src/Linker/AssetLoading/AssetLoadingContext.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "SearchPath/ISearchPath.h"
|
||||
#include "Obj/Gdt/Gdt.h"
|
||||
|
||||
class AssetLoadingContext
|
||||
{
|
||||
public:
|
||||
ISearchPath* m_asset_search_path;
|
||||
std::string m_zone_name;
|
||||
std::string m_game_name;
|
||||
std::vector<std::unique_ptr<Gdt>> m_gdt_files;
|
||||
|
||||
AssetLoadingContext();
|
||||
AssetLoadingContext(std::string zoneName, ISearchPath* assetSearchPath);
|
||||
};
|
20
src/Linker/AssetLoading/IAssetLoader.h
Normal file
20
src/Linker/AssetLoading/IAssetLoader.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "AssetLoadingContext.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
class IAssetLoader
|
||||
{
|
||||
public:
|
||||
IAssetLoader() = default;
|
||||
virtual ~IAssetLoader() = default;
|
||||
IAssetLoader(const IAssetLoader& other) = default;
|
||||
IAssetLoader(IAssetLoader&& other) noexcept = default;
|
||||
IAssetLoader& operator=(const IAssetLoader& other) = default;
|
||||
IAssetLoader& operator=(IAssetLoader&& other) noexcept = default;
|
||||
|
||||
_NODISCARD virtual bool SupportsGame(const std::string& gameName) const = 0;
|
||||
_NODISCARD virtual std::unique_ptr<Zone> CreateZoneForDefinition(AssetLoadingContext& context) const = 0;
|
||||
};
|
22
src/Linker/Game/IW4/AssetLoaderIW4.cpp
Normal file
22
src/Linker/Game/IW4/AssetLoaderIW4.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "AssetLoaderIW4.h"
|
||||
|
||||
#include "Game/IW4/GameIW4.h"
|
||||
#include "Game/IW4/GameAssetPoolIW4.h"
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
bool AssetLoader::SupportsGame(const std::string& gameName) const
|
||||
{
|
||||
return gameName == g_GameIW4.GetShortName();
|
||||
}
|
||||
|
||||
std::unique_ptr<Zone> AssetLoader::CreateZoneForDefinition(AssetLoadingContext& context) const
|
||||
{
|
||||
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);
|
||||
|
||||
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||
zone->m_pools->InitPoolDynamic(assetType);
|
||||
|
||||
return zone;
|
||||
}
|
12
src/Linker/Game/IW4/AssetLoaderIW4.h
Normal file
12
src/Linker/Game/IW4/AssetLoaderIW4.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/IAssetLoader.h"
|
||||
|
||||
namespace IW4
|
||||
{
|
||||
class AssetLoader final : public IAssetLoader
|
||||
{
|
||||
public:
|
||||
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(AssetLoadingContext& context) const override;
|
||||
};
|
||||
}
|
23
src/Linker/Game/T6/AssetLoaderT6.cpp
Normal file
23
src/Linker/Game/T6/AssetLoaderT6.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "AssetLoaderT6.h"
|
||||
|
||||
#include "Game/T6/T6.h"
|
||||
#include "Game/T6/GameT6.h"
|
||||
#include "Game/T6/GameAssetPoolT6.h"
|
||||
|
||||
using namespace T6;
|
||||
|
||||
bool AssetLoader::SupportsGame(const std::string& gameName) const
|
||||
{
|
||||
return gameName == g_GameT6.GetShortName();
|
||||
}
|
||||
|
||||
std::unique_ptr<Zone> AssetLoader::CreateZoneForDefinition(AssetLoadingContext& context) const
|
||||
{
|
||||
auto zone = std::make_unique<Zone>(context.m_zone_name, 0, &g_GameT6);
|
||||
zone->m_pools = std::make_unique<GameAssetPoolT6>(zone.get(), zone->m_priority);
|
||||
|
||||
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||
zone->m_pools->InitPoolDynamic(assetType);
|
||||
|
||||
return zone;
|
||||
}
|
12
src/Linker/Game/T6/AssetLoaderT6.h
Normal file
12
src/Linker/Game/T6/AssetLoaderT6.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "AssetLoading/IAssetLoader.h"
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class AssetLoader final : public IAssetLoader
|
||||
{
|
||||
public:
|
||||
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(AssetLoadingContext& context) const override;
|
||||
};
|
||||
}
|
@ -15,6 +15,10 @@
|
||||
#include "SearchPath/SearchPathFilesystem.h"
|
||||
#include "ObjContainer/IWD/IWD.h"
|
||||
#include "LinkerArgs.h"
|
||||
#include "AssetLoading/AssetLoadingContext.h"
|
||||
#include "AssetLoading/IAssetLoader.h"
|
||||
#include "Game/IW4/AssetLoaderIW4.h"
|
||||
#include "Game/T6/AssetLoaderT6.h"
|
||||
|
||||
#include "Utils/ObjFileStream.h"
|
||||
#include "Zone/AssetList/AssetList.h"
|
||||
@ -23,8 +27,17 @@
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const IAssetLoader* const ASSET_LOADERS[]
|
||||
{
|
||||
new IW4::AssetLoader(),
|
||||
new T6::AssetLoader()
|
||||
};
|
||||
|
||||
class Linker::Impl
|
||||
{
|
||||
static constexpr const char* METADATA_GAME = "game";
|
||||
static constexpr const char* METADATA_GDT = "gdt";
|
||||
|
||||
LinkerArgs m_args;
|
||||
std::vector<std::unique_ptr<ISearchPath>> m_loaded_zone_search_paths;
|
||||
SearchPaths m_asset_search_paths;
|
||||
@ -356,10 +369,91 @@ class Linker::Impl
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& zoneName, ZoneDefinition& zoneDefinition)
|
||||
static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& zoneName, const ZoneDefinition& zoneDefinition)
|
||||
{
|
||||
auto firstGameEntry = true;
|
||||
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata.equal_range(METADATA_GAME);
|
||||
for (auto i = rangeBegin; i != rangeEnd; ++i)
|
||||
{
|
||||
if (firstGameEntry)
|
||||
{
|
||||
gameName = i->second;
|
||||
firstGameEntry = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gameName != i->second)
|
||||
{
|
||||
std::cout << "Conflicting game names in zone \"" << zoneName << "\": " << gameName << " != " << i->second << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstGameEntry)
|
||||
{
|
||||
std::cout << "No game name was specified for zone \"" << zoneName << "\"" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadGdtFilesFromZoneDefinition(std::vector<std::unique_ptr<Gdt>>& gdtList, const std::string& zoneName, const ZoneDefinition& zoneDefinition, ISearchPath* gdtSearchPath)
|
||||
{
|
||||
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata.equal_range(METADATA_GDT);
|
||||
for (auto i = rangeBegin; i != rangeEnd; ++i)
|
||||
{
|
||||
const auto gdtFile = gdtSearchPath->Open(i->second + ".gdt");
|
||||
if(!gdtFile)
|
||||
{
|
||||
std::cout << "Failed to open file for gdt \"" << i->second << "\"" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GdtReader gdtReader(*gdtFile);
|
||||
auto gdt = std::make_unique<Gdt>();
|
||||
if(!gdtReader.Read(*gdt))
|
||||
{
|
||||
std::cout << "Failed to read gdt file \"" << i->second << "\"" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
gdtList.emplace_back(std::move(gdt));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& zoneName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath) const
|
||||
{
|
||||
auto context = std::make_unique<AssetLoadingContext>(zoneName, assetSearchPath);
|
||||
if (!GetGameNameFromZoneDefinition(context->m_game_name, zoneName, zoneDefinition))
|
||||
return nullptr;
|
||||
if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneName, zoneDefinition, gdtSearchPath))
|
||||
return nullptr;
|
||||
|
||||
for(const auto* assetLoader : ASSET_LOADERS)
|
||||
{
|
||||
if(assetLoader->SupportsGame(context->m_game_name))
|
||||
return assetLoader->CreateZoneForDefinition(*context);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool WriteZoneToFile(Zone* zone)
|
||||
{
|
||||
fs::path zoneFilePath(m_args.GetOutputFolderPathForZone(zone->m_name));
|
||||
zoneFilePath.append(zone->m_name + ".ff");
|
||||
|
||||
std::ifstream stream(zoneFilePath);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
|
||||
stream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildZone(const std::string& zoneName)
|
||||
{
|
||||
@ -374,7 +468,10 @@ class Linker::Impl
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto zone = CreateZoneForDefinition(zoneName, *zoneDefinition);
|
||||
const auto zone = CreateZoneForDefinition(zoneName, *zoneDefinition, &assetSearchPaths, &gdtSearchPaths);
|
||||
auto result = zone != nullptr;
|
||||
if (zone)
|
||||
result = WriteZoneToFile(zone.get());
|
||||
|
||||
for(const auto& loadedSearchPath : m_loaded_zone_search_paths)
|
||||
{
|
||||
@ -382,7 +479,7 @@ class Linker::Impl
|
||||
}
|
||||
m_loaded_zone_search_paths.clear();
|
||||
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -20,5 +20,5 @@ SequenceZoneDefinitionMetaData::SequenceZoneDefinitionMetaData()
|
||||
|
||||
void SequenceZoneDefinitionMetaData::ProcessMatch(ZoneDefinition* state, SequenceResult<SimpleParserValue>& result) const
|
||||
{
|
||||
state->m_metadata[result.NextCapture(CAPTURE_KEY).IdentifierValue()] = result.NextCapture(CAPTURE_VALUE).IdentifierValue();
|
||||
state->m_metadata.insert(std::make_pair(result.NextCapture(CAPTURE_KEY).IdentifierValue(), result.NextCapture(CAPTURE_VALUE).IdentifierValue()));
|
||||
}
|
||||
|
@ -16,10 +16,7 @@ void ZoneDefinition::Include(ZoneDefinition& definitionToInclude)
|
||||
{
|
||||
for(const auto& [key, value] : definitionToInclude.m_metadata)
|
||||
{
|
||||
if(m_metadata.find(key) == m_metadata.end())
|
||||
{
|
||||
m_metadata.emplace(std::make_pair(key, value));
|
||||
}
|
||||
m_metadata.emplace(std::make_pair(key, value));
|
||||
}
|
||||
|
||||
for(const auto& ignore : definitionToInclude.m_ignores)
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
class ZoneDefinition
|
||||
{
|
||||
public:
|
||||
std::unordered_map<std::string, std::string> m_metadata;
|
||||
std::unordered_multimap<std::string, std::string> m_metadata;
|
||||
std::vector<std::string> m_includes;
|
||||
std::vector<std::string> m_ignores;
|
||||
std::vector<ZoneDefinitionEntry> m_assets;
|
||||
|
Loading…
x
Reference in New Issue
Block a user