#options GAME (IW3, IW4, IW5, T5, T6) #filename "Game/" + GAME + "/Image/ImageLoaderEmbedded" + GAME + ".cpp" #if GAME == "IW3" #define FEATURE_IW3 #elif GAME == "IW4" #define FEATURE_IW4 #elif GAME == "IW5" #define FEATURE_IW5 #elif GAME == "T5" #define FEATURE_T5 #elif GAME == "T6" #define FEATURE_T6 #endif #if defined(FEATURE_IW3) #define IWI_NS iwi6 #define FLAG_CUBE IMG_FLAG_CUBEMAP #define FLAG_3D IMG_FLAG_VOLMAP #elif defined(FEATURE_IW4) || defined(FEATURE_IW5) #define IWI_NS iwi8 #define FLAG_CUBE IMG_FLAG_MAPTYPE_CUBE #define FLAG_3D IMG_FLAG_MAPTYPE_3D #elif defined(FEATURE_T5) #define IWI_NS iwi13 #define FLAG_CUBE IMG_FLAG_CUBEMAP #define FLAG_3D IMG_FLAG_VOLMAP #elif defined(FEATURE_T6) #define IWI_NS iwi27 #define FLAG_CUBE IMG_FLAG_CUBEMAP #define FLAG_3D IMG_FLAG_VOLMAP #endif // This file was templated. // See ImageLoaderEmbedded.cpp.template. // Do not modify, changes will be lost. #set LOADER_HEADER "\"ImageLoaderEmbedded" + GAME + ".h\"" #include LOADER_HEADER #set COMMON_HEADER "\"Game/" + GAME + "/Common" + GAME + ".h\"" #include COMMON_HEADER #include "Image/DdsLoader.h" #include "Image/ImageCommon.h" #include "Image/IwiTypes.h" #include "Utils/Logging/Log.h" #include using namespace GAME; using namespace image; namespace { #set LOADER_CLASS "ImageLoader" + GAME class LOADER_CLASS final : public AssetCreator { public: LOADER_CLASS(MemoryManager& memory, ISearchPath& searchPath) : m_memory(memory), m_search_path(searchPath) { } AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override { // Do not load any GfxImages from raw for now that are not loaded // TODO: Load iwis and add streaming info to asset if (assetName.empty() || assetName[0] != '*') return AssetCreationResult::NoAction(); const auto file = m_search_path.Open(image::GetFileNameForAsset(assetName, ".dds")); if (!file.IsOpen()) return AssetCreationResult::NoAction(); const auto texture = image::LoadDds(*file.m_stream); if (!texture) { con::error("Failed to load dds file for image asset \"{}\"", assetName); return AssetCreationResult::Failure(); } auto* image = m_memory.Alloc(); image->name = m_memory.Dup(assetName.c_str()); image->picmip.platform[0] = 0; image->picmip.platform[1] = 0; image->noPicmip = !texture->HasMipMaps(); image->semantic = TS_FUNCTION; image->track = 0; image->cardMemory.platform[0] = 0; image->cardMemory.platform[1] = 0; image->width = static_cast(texture->GetWidth()); image->height = static_cast(texture->GetHeight()); image->depth = static_cast(texture->GetDepth()); image->category = IMG_CATEGORY_AUTO_GENERATED; #ifndef FEATURE_IW5 image->delayLoadPixels = false; #endif switch (texture->GetTextureType()) { case TextureType::T_2D: image->mapType = MAPTYPE_2D; break; case TextureType::T_3D: image->mapType = MAPTYPE_3D; break; case TextureType::T_CUBE: image->mapType = MAPTYPE_CUBE; break; default: image->mapType = MAPTYPE_NONE; break; } const auto mipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1; const auto faceCount = texture->GetFaceCount(); auto dataSize = 0uz; for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) dataSize += texture->GetSizeOfMipLevel(mipLevel) * faceCount; auto* loadDef = static_cast(m_memory.AllocRaw(offsetof(GfxImageLoadDef, data) + dataSize)); image->texture.loadDef = loadDef; loadDef->levelCount = static_cast(mipCount); loadDef->flags = 0; if (!texture->HasMipMaps()) loadDef->flags |= IWI_NS::IMG_FLAG_NOMIPMAPS; if (texture->GetTextureType() == TextureType::T_CUBE) loadDef->flags |= IWI_NS::FLAG_CUBE; if (texture->GetTextureType() == TextureType::T_3D) loadDef->flags |= IWI_NS::FLAG_3D; #if defined(FEATURE_IW3) loadDef->dimensions[0] = image->width; loadDef->dimensions[1] = image->height; loadDef->dimensions[2] = image->depth; #endif #if defined(FEATURE_T6) loadDef->format = static_cast(texture->GetFormat()->GetDxgiFormat()); #else loadDef->format = static_cast(texture->GetFormat()->GetD3DFormat()); #endif loadDef->resourceSize = static_cast(dataSize); char* currentDataBuffer = loadDef->data; for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) { const auto mipSize = texture->GetSizeOfMipLevel(mipLevel); for (auto face = 0; face < faceCount; face++) { memcpy(currentDataBuffer, texture->GetBufferForMipLevel(mipLevel, face), mipSize); currentDataBuffer += mipSize; } } return AssetCreationResult::Success(context.AddAsset(assetName, image)); } MemoryManager& m_memory; ISearchPath& m_search_path; }; } // namespace namespace image { #set LOADER_METHOD "CreateLoaderEmbedded" + GAME std::unique_ptr> LOADER_METHOD(MemoryManager& memory, ISearchPath& searchPath) { return std::make_unique(memory, searchPath); } } // namespace image