diff --git a/src/Linker/Game/T6/ZoneCreatorT6.cpp b/src/Linker/Game/T6/ZoneCreatorT6.cpp index c8b24fd3..970e1551 100644 --- a/src/Linker/Game/T6/ZoneCreatorT6.cpp +++ b/src/Linker/Game/T6/ZoneCreatorT6.cpp @@ -11,7 +11,7 @@ using namespace T6; ZoneCreator::ZoneCreator() { - for(auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) + for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++) { AddAssetTypeName(assetType, GameAssetPoolT6::AssetTypeNameByType(assetType)); } @@ -22,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)); } +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); @@ -40,19 +67,22 @@ std::unique_ptr ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& auto zone = std::make_unique(context.m_zone_name, 0, &g_GameT6); CreateZoneAssetPools(zone.get()); - std::vector gdtList; - gdtList.reserve(context.m_gdt_files.size()); - for (const auto& gdt : context.m_gdt_files) - gdtList.push_back(gdt.get()); - const auto assetLoadingContext = std::make_unique(zone.get(), context.m_asset_search_path, std::move(gdtList)); - - for(const auto& assetEntry : context.m_definition->m_assets) + for (const auto& assetEntry : context.m_definition->m_assets) { - if (assetEntry.m_is_reference) + 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()) + if (foundAssetTypeEntry == m_asset_types_by_name.end()) { std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"" << std::endl; return nullptr; diff --git a/src/Linker/Game/T6/ZoneCreatorT6.h b/src/Linker/Game/T6/ZoneCreatorT6.h index ac6f7d6a..139549c3 100644 --- a/src/Linker/Game/T6/ZoneCreatorT6.h +++ b/src/Linker/Game/T6/ZoneCreatorT6.h @@ -12,6 +12,8 @@ namespace T6 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/Linker/Linker.cpp b/src/Linker/Linker.cpp index fdda3553..a6d67d11 100644 --- a/src/Linker/Linker.cpp +++ b/src/Linker/Linker.cpp @@ -71,7 +71,7 @@ class Linker::Impl ObjLoading::UnloadIWDsInSearchPath(searchPath); } - + SearchPaths GetAssetSearchPathsForZone(const std::string& zoneName) { SearchPaths searchPathsForZone; @@ -105,7 +105,7 @@ class Linker::Impl return searchPathsForZone; } - + SearchPaths GetGdtSearchPathsForZone(const std::string& zoneName) { SearchPaths searchPathsForZone; @@ -131,7 +131,7 @@ class Linker::Impl return searchPathsForZone; } - + SearchPaths GetSourceSearchPathsForZone(const std::string& zoneName) { SearchPaths searchPathsForZone; @@ -152,7 +152,7 @@ class Linker::Impl searchPathsForZone.CommitSearchPath(std::make_unique(searchPathStr)); } - + searchPathsForZone.IncludeSearchPath(&m_source_search_paths); return searchPathsForZone; @@ -170,12 +170,12 @@ class Linker::Impl if (!fs::is_directory(absolutePath)) { - if(m_args.m_verbose) + if (m_args.m_verbose) std::cout << "Adding asset search path (Not found): " << absolutePath.string() << std::endl; continue; } - if(m_args.m_verbose) + if (m_args.m_verbose) std::cout << "Adding asset search path: " << absolutePath.string() << std::endl; auto searchPath = std::make_unique(absolutePath.string()); @@ -229,11 +229,11 @@ class Linker::Impl for (const auto& include : zoneDefinition.m_includes) toIncludeQueue.emplace_back(include); - while(!toIncludeQueue.empty()) + while (!toIncludeQueue.empty()) { const auto& source = toIncludeQueue.front(); - if(sourceNames.find(source) == sourceNames.end()) + if (sourceNames.find(source) == sourceNames.end()) { sourceNames.emplace(source); @@ -319,9 +319,9 @@ class Linker::Impl { const auto zoneDefinition = ReadZoneDefinition(zoneName, sourceSearchPath); - if(zoneDefinition) + if (zoneDefinition) { - for(const auto& entry : zoneDefinition->m_assets) + for (const auto& entry : zoneDefinition->m_assets) { assetList.emplace_back(entry.m_asset_type, entry.m_asset_name); } @@ -332,39 +332,28 @@ class Linker::Impl return false; } - bool ProcessZoneDefinitionIgnores(const std::string& zoneName, ZoneDefinition& zoneDefinition, ISearchPath* sourceSearchPath) const + bool ProcessZoneDefinitionIgnores(const std::string& zoneName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const { - if (zoneDefinition.m_ignores.empty()) + if (context.m_definition->m_ignores.empty()) return true; std::map> zoneDefinitionAssetsByName; - for (auto& entry : zoneDefinition.m_assets) + for (auto& entry : context.m_definition->m_assets) { zoneDefinitionAssetsByName.try_emplace(entry.m_asset_name, entry); } - for(const auto& ignore : zoneDefinition.m_ignores) + for (const auto& ignore : context.m_definition->m_ignores) { - if(ignore == zoneName) + if (ignore == zoneName) continue; std::vector assetList; - if(!ReadAssetList(ignore, assetList, sourceSearchPath)) + if (!ReadAssetList(ignore, context.m_ignored_assets, sourceSearchPath)) { std::cout << "Failed to read asset listing for ignoring assets of zone \"" << ignore << "\"." << std::endl; return false; } - - for(const auto& assetListEntry : assetList) - { - const auto foundAsset = zoneDefinitionAssetsByName.find(assetListEntry.m_name); - - if(foundAsset != zoneDefinitionAssetsByName.end() - && foundAsset->second.get().m_asset_type == assetListEntry.m_type) - { - foundAsset->second.get().m_is_reference = true; - } - } } return true; } @@ -405,7 +394,7 @@ class Linker::Impl for (auto i = rangeBegin; i != rangeEnd; ++i) { const auto gdtFile = gdtSearchPath->Open(i->second + ".gdt"); - if(!gdtFile.IsOpen()) + if (!gdtFile.IsOpen()) { std::cout << "Failed to open file for gdt \"" << i->second << "\"" << std::endl; return false; @@ -413,7 +402,7 @@ class Linker::Impl GdtReader gdtReader(*gdtFile.m_stream); auto gdt = std::make_unique(); - if(!gdtReader.Read(*gdt)) + if (!gdtReader.Read(*gdt)) { std::cout << "Failed to read gdt file \"" << i->second << "\"" << std::endl; return false; @@ -425,17 +414,20 @@ class Linker::Impl return true; } - std::unique_ptr CreateZoneForDefinition(const std::string& zoneName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath) const + std::unique_ptr CreateZoneForDefinition(const std::string& zoneName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath, + ISearchPath* sourceSearchPath) const { auto context = std::make_unique(zoneName, assetSearchPath, &zoneDefinition); + if (!ProcessZoneDefinitionIgnores(zoneName, *context, sourceSearchPath)) + return nullptr; 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 : ZONE_CREATORS) + + for (const auto* assetLoader : ZONE_CREATORS) { - if(assetLoader->SupportsGame(context->m_game_name)) + if (assetLoader->SupportsGame(context->m_game_name)) return assetLoader->CreateZoneForDefinition(*context); } @@ -457,7 +449,7 @@ class Linker::Impl stream.close(); return true; } - + bool BuildZone(const std::string& zoneName) { auto assetSearchPaths = GetAssetSearchPathsForZone(zoneName); @@ -465,23 +457,20 @@ class Linker::Impl auto sourceSearchPaths = GetSourceSearchPathsForZone(zoneName); const auto zoneDefinition = ReadZoneDefinition(zoneName, &sourceSearchPaths); - if (!zoneDefinition - || !ProcessZoneDefinitionIgnores(zoneName, *zoneDefinition, &sourceSearchPaths)) - { + if (!zoneDefinition) return false; - } - const auto zone = CreateZoneForDefinition(zoneName, *zoneDefinition, &assetSearchPaths, &gdtSearchPaths); + const auto zone = CreateZoneForDefinition(zoneName, *zoneDefinition, &assetSearchPaths, &gdtSearchPaths, &sourceSearchPaths); auto result = zone != nullptr; if (zone) result = WriteZoneToFile(zone.get()); - for(const auto& loadedSearchPath : m_loaded_zone_search_paths) + for (const auto& loadedSearchPath : m_loaded_zone_search_paths) { UnloadSearchPath(loadedSearchPath.get()); } m_loaded_zone_search_paths.clear(); - + return result; } diff --git a/src/Linker/ZoneCreation/ZoneCreationContext.h b/src/Linker/ZoneCreation/ZoneCreationContext.h index 8169909f..d03ccbde 100644 --- a/src/Linker/ZoneCreation/ZoneCreationContext.h +++ b/src/Linker/ZoneCreation/ZoneCreationContext.h @@ -2,9 +2,11 @@ #include #include #include +#include #include "SearchPath/ISearchPath.h" #include "Obj/Gdt/Gdt.h" +#include "Zone/AssetList/AssetList.h" #include "Zone/Definition/ZoneDefinition.h" class ZoneCreationContext @@ -15,6 +17,7 @@ public: ISearchPath* m_asset_search_path; ZoneDefinition* m_definition; std::vector> m_gdt_files; + std::vector m_ignored_assets; ZoneCreationContext(); ZoneCreationContext(std::string zoneName, ISearchPath* assetSearchPath, ZoneDefinition* definition); diff --git a/src/ObjLoading/AssetLoading/AssetLoadingContext.cpp b/src/ObjLoading/AssetLoading/AssetLoadingContext.cpp index a17a79ed..07e01968 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingContext.cpp +++ b/src/ObjLoading/AssetLoading/AssetLoadingContext.cpp @@ -10,12 +10,12 @@ AssetLoadingContext::AssetLoadingContext(Zone* zone, ISearchPath* rawSearchPath, void AssetLoadingContext::BuildGdtEntryCache() { - for(auto* gdt : m_gdt_files) + for (auto* gdt : m_gdt_files) { - for(const auto& entry : gdt->m_entries) + for (const auto& entry : gdt->m_entries) { auto gdfMapEntry = m_entries_by_gdf_and_by_name.find(entry->m_gdf_name); - if(gdfMapEntry == m_entries_by_gdf_and_by_name.end()) + if (gdfMapEntry == m_entries_by_gdf_and_by_name.end()) { std::unordered_map entryMap; entryMap.emplace(std::make_pair(entry->m_name, entry.get())); diff --git a/src/ObjLoading/AssetLoading/AssetLoadingContext.h b/src/ObjLoading/AssetLoading/AssetLoadingContext.h index 26bc0bfe..81de5683 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingContext.h +++ b/src/ObjLoading/AssetLoading/AssetLoadingContext.h @@ -17,6 +17,7 @@ public: Zone* const m_zone; ISearchPath* const m_raw_search_path; const std::vector m_gdt_files; + std::unordered_map m_ignored_asset_map; AssetLoadingContext(Zone* zone, ISearchPath* rawSearchPath, std::vector gdtFiles); GdtEntry* GetGdtEntryByGdfAndName(const std::string& gdfName, const std::string& entryName) override; diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp index 01ae0d13..39e43f76 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp +++ b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp @@ -20,54 +20,95 @@ void AssetLoadingManager::AddAsset(const asset_type_t assetType, const std::stri std::cout << "Failed to add asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\" to pool: \"" << assetName << "\"" << std::endl; } +XAssetInfoGeneric* AssetLoadingManager::LoadIgnoredDependency(const asset_type_t assetType, const std::string& assetName, IAssetLoader* loader) +{ + auto* alreadyLoadedAsset = m_context.m_zone->m_pools->GetAsset(assetType, assetName); + if (alreadyLoadedAsset) + return alreadyLoadedAsset; + + auto* linkAsset = loader->CreateEmptyAsset(assetName, m_context.m_zone->GetMemory()); + if (linkAsset) + { + std::vector dependencies; + AddAsset(assetType, assetName, linkAsset, dependencies); + auto* lastDependency = m_last_dependency_loaded; + m_last_dependency_loaded = nullptr; + return lastDependency; + } + + auto* existingAsset = loader->LoadFromGlobalAssetPools(assetName); + if (existingAsset) + { + std::vector dependencies; + AddAsset(existingAsset->m_type, existingAsset->m_name, existingAsset->m_ptr, dependencies); + auto* lastDependency = m_last_dependency_loaded; + m_last_dependency_loaded = nullptr; + return lastDependency; + } + + std::cout << "Failed to create empty asset for type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\"" << std::endl; + return nullptr; +} + +XAssetInfoGeneric* AssetLoadingManager::LoadAssetDependency(const asset_type_t assetType, const std::string& assetName, IAssetLoader* loader) +{ + if (loader->CanLoadFromGdt() && loader->LoadFromGdt(assetName, &m_context, m_context.m_zone->GetMemory(), this)) + { + auto* lastDependency = m_last_dependency_loaded; + m_last_dependency_loaded = nullptr; + return lastDependency; + } + + if (loader->CanLoadFromRaw() && loader->LoadFromRaw(assetName, m_context.m_raw_search_path, m_context.m_zone->GetMemory(), this)) + { + auto* lastDependency = m_last_dependency_loaded; + m_last_dependency_loaded = nullptr; + return lastDependency; + } + + auto* existingAsset = loader->LoadFromGlobalAssetPools(assetName); + if (existingAsset) + { + std::vector dependencies; + for (const auto* dependency : existingAsset->m_dependencies) + { + auto* newDependency = LoadDependency(dependency->m_type, dependency->m_name); + if (newDependency) + dependencies.push_back(newDependency); + else + return nullptr; + } + + AddAsset(existingAsset->m_type, existingAsset->m_name, existingAsset->m_ptr, dependencies); + auto* lastDependency = m_last_dependency_loaded; + m_last_dependency_loaded = nullptr; + return lastDependency; + } + + std::cout << "Failed to load asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\": \"" << assetName << "\"" << std::endl; + return nullptr; +} + XAssetInfoGeneric* AssetLoadingManager::LoadDependency(const asset_type_t assetType, const std::string& assetName) { - auto* existingAsset = m_context.m_zone->m_pools->GetAsset(assetType, assetName); - if (existingAsset) - return existingAsset; + auto* alreadyLoadedAsset = m_context.m_zone->m_pools->GetAsset(assetType, assetName); + if (alreadyLoadedAsset) + return alreadyLoadedAsset; const auto loader = m_asset_loaders_by_type.find(assetType); if (loader != m_asset_loaders_by_type.end()) { - if (loader->second->CanLoadFromGdt() && loader->second->LoadFromGdt(assetName, &m_context, m_context.m_zone->GetMemory(), this)) + const auto ignoreEntry = m_context.m_ignored_asset_map.find(assetName); + if(ignoreEntry != m_context.m_ignored_asset_map.end() && ignoreEntry->second == assetType) { - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; + const auto linkAssetName = ',' + assetName; + + return LoadIgnoredDependency(assetType, linkAssetName, loader->second.get()); } - if (loader->second->CanLoadFromRaw() && loader->second->LoadFromRaw(assetName, m_context.m_raw_search_path, m_context.m_zone->GetMemory(), this)) - { - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - auto* existingAsset = loader->second->LoadFromGlobalAssetPools(assetName); - if(existingAsset) - { - std::vector dependencies; - for (const auto* dependency : existingAsset->m_dependencies) - { - auto* newDependency = LoadDependency(dependency->m_type, dependency->m_name); - if (newDependency) - dependencies.push_back(newDependency); - else - return nullptr; - } - - AddAsset(existingAsset->m_type, existingAsset->m_name, existingAsset->m_ptr, dependencies); - auto* lastDependency = m_last_dependency_loaded; - m_last_dependency_loaded = nullptr; - return lastDependency; - } - - std::cout << "Failed to load asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\": \"" << assetName << "\"" << std::endl; - } - else - { - std::cout << "Failed to find loader for asset type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\"" << std::endl; + return LoadAssetDependency(assetType, assetName, loader->second.get()); } + std::cout << "Failed to find loader for asset type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\"" << std::endl; return nullptr; } diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.h b/src/ObjLoading/AssetLoading/AssetLoadingManager.h index d6bcb2c2..547d04ac 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.h +++ b/src/ObjLoading/AssetLoading/AssetLoadingManager.h @@ -11,6 +11,9 @@ class AssetLoadingManager final : public IAssetLoadingManager AssetLoadingContext& m_context; XAssetInfoGeneric* m_last_dependency_loaded; + XAssetInfoGeneric* LoadIgnoredDependency(asset_type_t assetType, const std::string& assetName, IAssetLoader* loader); + XAssetInfoGeneric* LoadAssetDependency(asset_type_t assetType, const std::string& assetName, IAssetLoader* loader); + public: AssetLoadingManager(const std::unordered_map>& assetLoadersByType, AssetLoadingContext& context); diff --git a/src/ObjLoading/AssetLoading/IAssetLoader.h b/src/ObjLoading/AssetLoading/IAssetLoader.h index a2a9749f..0a05b719 100644 --- a/src/ObjLoading/AssetLoading/IAssetLoader.h +++ b/src/ObjLoading/AssetLoading/IAssetLoader.h @@ -20,6 +20,12 @@ public: _NODISCARD virtual asset_type_t GetHandlingAssetType() const = 0; _NODISCARD virtual XAssetInfoGeneric* LoadFromGlobalAssetPools(const std::string& assetName) const = 0; + _NODISCARD virtual void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) + { + // TODO: Make this pure virtual + return nullptr; + } + _NODISCARD virtual bool CanLoadFromGdt() const { return false; diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp index 839c6d6a..9e81d6a7 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.cpp @@ -1,10 +1,20 @@ #include "AssetLoaderRawFile.h" +#include + #include "Game/IW4/IW4.h" #include "Pool/GlobalAssetPool.h" using namespace IW4; +void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + auto* rawFile = memory->Create(); + memset(rawFile, 0, sizeof(RawFile)); + rawFile->name = memory->Dup(assetName.c_str()); + return rawFile; +} + bool AssetLoaderRawFile::CanLoadFromRaw() const { return true; diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h index 5027064c..b5bc195d 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderRawFile.h @@ -9,6 +9,7 @@ namespace IW4 class AssetLoaderRawFile final : public BasicAssetLoader { public: + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; }; diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp index 2a3d7246..6786f993 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.cpp @@ -1,10 +1,20 @@ #include "AssetLoaderRawFile.h" +#include + #include "Game/T6/T6.h" #include "Pool/GlobalAssetPool.h" using namespace T6; +void* AssetLoaderRawFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + auto* rawFile = memory->Create(); + memset(rawFile, 0, sizeof(RawFile)); + rawFile->name = memory->Dup(assetName.c_str()); + return rawFile; +} + bool AssetLoaderRawFile::CanLoadFromRaw() const { return true; diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h index 7c6b11a9..1e9ce61c 100644 --- a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderRawFile.h @@ -9,6 +9,7 @@ namespace T6 class AssetLoaderRawFile final : public BasicAssetLoader { public: + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) const override; };