From 5bda400acbd52d0af3f5329191d30e447e99c581 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 7 Feb 2020 20:55:10 +0100 Subject: [PATCH] ObjLoading: Add basis for Iwi loading --- src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 82 +++++++++++++++++------ src/ObjLoading/Game/T6/ObjLoaderT6.h | 4 +- src/ObjLoading/Image/IwiLoader.cpp | 24 +++++++ src/ObjLoading/Image/IwiLoader.h | 15 +++++ src/ObjLoading/ObjContainer/IPak/IPak.cpp | 2 + 5 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 src/ObjLoading/Image/IwiLoader.cpp create mode 100644 src/ObjLoading/Image/IwiLoader.h diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 0dab9b43..0bdf0433 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -3,6 +3,8 @@ #include "Game/T6/GameAssetPoolT6.h" #include "ObjContainer/IPak/IPak.h" #include "ObjLoading.h" +#include "Image/Texture.h" +#include "Image/IwiLoader.h" const int ObjLoaderT6::IPAK_READ_HASH = Com_HashKey("ipak_read", 64); const int ObjLoaderT6::GLOBAL_HASH = Com_HashKey("GLOBAL", 64); @@ -33,7 +35,7 @@ void ObjLoaderT6::LoadIPakForZone(ISearchPath* searchPath, const std::string& ip { if(ObjLoading::Configuration.Verbose) { - printf("Loading ipak '%s' for zone '%s'\n", ipakName.c_str(), zone->m_name.c_str()); + printf("Trying to load ipak '%s' for zone '%s'\n", ipakName.c_str(), zone->m_name.c_str()); } const std::string ipakFilename = ipakName + ".ipak"; @@ -46,6 +48,8 @@ void ObjLoaderT6::LoadIPakForZone(ISearchPath* searchPath, const std::string& ip if(ipak->Initialize()) { IPak::Repository.AddContainer(ipak, zone); + + printf("Found and loaded ipak '%s'.\n", ipakFilename.c_str()); } else { @@ -98,46 +102,80 @@ void ObjLoaderT6::UnloadContainersOfZone(Zone* zone) IPak::Repository.RemoveContainerReferences(zone); } -void ObjLoaderT6::LoadImageDataFromFile(T6::GfxImage* image, FileAPI::IFile* file, Zone* zone) +void ObjLoaderT6::LoadImageFromLoadDef(T6::GfxImage* image, Zone* zone) { + // TODO: Load Texture from LoadDef here +} + +void ObjLoaderT6::LoadImageFromIwi(T6::GfxImage* image, ISearchPath* searchPath, Zone* zone) +{ + Texture* loadedTexture = nullptr; + IwiLoader loader(zone->GetMemory()); + + const std::string imageFileName = "images/" + std::string(image->name) + ".iwi"; + auto* filePathImage = searchPath->Open(imageFileName); + + if (filePathImage != nullptr && filePathImage->IsOpen()) + { + loadedTexture = loader.LoadIwi(filePathImage); + + filePathImage->Close(); + delete filePathImage; + } + else if (image->streamedPartCount > 0) + { + for (auto* ipak : IPak::Repository) + { + auto* ipakEntry = ipak->GetEntryData(image->hash, image->streamedParts[0].hash); + + if (ipakEntry != nullptr && ipakEntry->IsOpen()) + { + loadedTexture = loader.LoadIwi(ipakEntry); + + ipakEntry->Close(); + delete ipakEntry; + } + } + } + + if(loadedTexture != nullptr) + { + image->texture.texture = loadedTexture; + } + else + { + printf("Could not find data for image \"%s\"\n", image->name); + } } void ObjLoaderT6::LoadImageData(ISearchPath* searchPath, Zone* zone) { auto* assetPoolT6 = dynamic_cast(zone->GetPools()); - if (assetPoolT6->m_image != nullptr) + if (assetPoolT6 && assetPoolT6->m_image != nullptr) { for (auto* imageEntry : *assetPoolT6->m_image) { auto* image = imageEntry->m_asset; - if(image->texture.loadDef && image->texture.loadDef->resourceSize > 0) + if(image->loadedSize > 0) { continue; } - std::string imageFileName = "images/" + std::string(image->name) + ".iwi"; - auto* filePathImage = searchPath->Open(imageFileName); - if(filePathImage != nullptr && filePathImage->IsOpen()) + // Do not load linked assets + if(image->name && image->name[0] == ',') { - LoadImageDataFromFile(image, filePathImage, zone); - filePathImage->Close(); - delete filePathImage; + continue; } - else if(image->streamedPartCount > 0) - { - for (auto* ipak : IPak::Repository) - { - auto* ipakEntry = ipak->GetEntryData(image->hash, image->streamedParts[0].hash); - if (ipakEntry != nullptr && ipakEntry->IsOpen()) - { - LoadImageDataFromFile(image, ipakEntry, zone); - ipakEntry->Close(); - delete ipakEntry; - } - } + if(image->texture.loadDef && image->texture.loadDef->resourceSize > 0) + { + LoadImageFromLoadDef(image, zone); + } + else + { + LoadImageFromIwi(image, searchPath, zone); } } } diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.h b/src/ObjLoading/Game/T6/ObjLoaderT6.h index 6d8b2d20..1a7d6a12 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.h +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.h @@ -12,7 +12,9 @@ class ObjLoaderT6 final : public IObjLoader static void LoadIPakForZone(ISearchPath* searchPath, const std::string& ipakName, Zone* zone); - static void LoadImageDataFromFile(T6::GfxImage* image, FileAPI::IFile* file, Zone* zone); + static void LoadImageFromIwiFile(T6::GfxImage* image, FileAPI::IFile* file, Zone* zone); + static void LoadImageFromIwi(T6::GfxImage* image, ISearchPath* searchPath, Zone* zone); + static void LoadImageFromLoadDef(T6::GfxImage* image, Zone* zone); static void LoadImageData(ISearchPath* searchPath, Zone* zone); public: diff --git a/src/ObjLoading/Image/IwiLoader.cpp b/src/ObjLoading/Image/IwiLoader.cpp new file mode 100644 index 00000000..400531bd --- /dev/null +++ b/src/ObjLoading/Image/IwiLoader.cpp @@ -0,0 +1,24 @@ +#include "IwiLoader.h" + +IwiLoader::IwiLoader(MemoryManager* memoryManager) +{ + m_memory_manager = memoryManager; +} + +Texture* IwiLoader::LoadIwi(FileAPI::IFile* file) +{ + struct + { + char tag[3]; + char version; + } iwiHeaderMeta{}; + + if (file->Read(&iwiHeaderMeta, sizeof iwiHeaderMeta, 1) != 1) + return nullptr; + + printf("Read IWI with version %i\n", iwiHeaderMeta.version); + + // TODO: Read iwi based on version + + return nullptr; +} diff --git a/src/ObjLoading/Image/IwiLoader.h b/src/ObjLoading/Image/IwiLoader.h new file mode 100644 index 00000000..97869e6c --- /dev/null +++ b/src/ObjLoading/Image/IwiLoader.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Utils/FileAPI.h" +#include "Utils/MemoryManager.h" +#include "Image/Texture.h" + +class IwiLoader +{ + MemoryManager* m_memory_manager; + +public: + explicit IwiLoader(MemoryManager* memoryManager); + + Texture* LoadIwi(FileAPI::IFile* file); +}; diff --git a/src/ObjLoading/ObjContainer/IPak/IPak.cpp b/src/ObjLoading/ObjContainer/IPak/IPak.cpp index d887d849..88a22c41 100644 --- a/src/ObjLoading/ObjContainer/IPak/IPak.cpp +++ b/src/ObjLoading/ObjContainer/IPak/IPak.cpp @@ -168,7 +168,9 @@ public: { if(entry.key.nameHash == nameHash && entry.key.dataHash == dataHash) { + // TODO: Implement ipak reader as IFile interface and use here __asm nop; + return nullptr; } }