From 896c3b70688dacd8a192098e227a2f49a059fd53 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 22 Dec 2016 02:48:00 +0100 Subject: [PATCH] [ZoneBuilder] Correctly write GfxImages --- .../Modules/AssetInterfaces/IGfxImage.cpp | 18 +++++----- src/Components/Modules/Maps.cpp | 2 +- src/Components/Modules/ZoneBuilder.cpp | 36 +++++++++++++++++-- src/Components/Modules/ZoneBuilder.hpp | 6 ++++ src/Components/Modules/Zones.cpp | 2 +- src/Game/Structs.hpp | 28 +++++++++++---- 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/Components/Modules/AssetInterfaces/IGfxImage.cpp b/src/Components/Modules/AssetInterfaces/IGfxImage.cpp index 6933759a..a6709810 100644 --- a/src/Components/Modules/AssetInterfaces/IGfxImage.cpp +++ b/src/Components/Modules/AssetInterfaces/IGfxImage.cpp @@ -40,7 +40,7 @@ namespace Assets const Game::GfxImageFileHeader* iwiHeader = reinterpret_cast(iwiBuffer.data()); - image->mapType = 3; + image->mapType = Game::MAPTYPE_2D; image->dataLen1 = iwiHeader->fileSizeForPicmip[0] - 32; image->dataLen2 = iwiHeader->fileSizeForPicmip[0] - 32; @@ -52,7 +52,7 @@ namespace Assets std::memcpy(image->loadDef->dimensions, iwiHeader->dimensions, 6); image->loadDef->flags = 0; - image->loadDef->mipLevels = 0; + image->loadDef->levelCount = 0; switch (iwiHeader->format) { @@ -93,6 +93,7 @@ namespace Assets void IGfxImage::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { AssertSize(Game::GfxImage, 32); + AssertSize(Game::MapType, 1); Utils::Stream* buffer = builder->getBuffer(); Game::GfxImage* asset = header.image; @@ -109,21 +110,18 @@ namespace Assets buffer->pushBlock(Game::XFILE_BLOCK_TEMP); - if (asset->texture) + if (asset->loadDef) { buffer->align(Utils::Stream::ALIGN_4); Game::GfxImageLoadDef* destTexture = buffer->dest(); - buffer->save(asset->loadDef, 16); + buffer->save(asset->loadDef, 16, 1); - builder->incrementExternalSize(asset->loadDef->dataSize); + builder->incrementExternalSize(asset->loadDef->resourceSize); - // Zero the size! - destTexture->dataSize = 0; - - if (destTexture->dataSize > 0) + if (destTexture->resourceSize > 0) { - buffer->save(asset->loadDef->data, asset->loadDef->dataSize); + buffer->save(asset->loadDef->data, asset->loadDef->resourceSize); } Utils::Stream::ClearPointer(&dest->loadDef); diff --git a/src/Components/Modules/Maps.cpp b/src/Components/Modules/Maps.cpp index 25da9e99..a67f5462 100644 --- a/src/Components/Modules/Maps.cpp +++ b/src/Components/Modules/Maps.cpp @@ -377,7 +377,7 @@ namespace Components } std::string _name = fmt::sprintf("raw/mapdump/%s/textures/%s.png", world->baseName, image->name); - D3DXSaveTextureToFile(std::wstring(_name.begin(), _name.end()).data(), D3DXIFF_PNG, image->texture, NULL); + D3DXSaveTextureToFile(std::wstring(_name.begin(), _name.end()).data(), D3DXIFF_PNG, image->map, NULL); mtl.append(fmt::sprintf("\nnewmtl %s\n", name.data())); mtl.append("Ka 1.0000 1.0000 1.0000\n"); diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 6795a95f..6355cb1b 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -2,6 +2,8 @@ namespace Components { + Utils::Memory::Allocator ZoneBuilder::MemAllocator; + std::string ZoneBuilder::TraceZone; std::vector> ZoneBuilder::TraceAssets; @@ -316,7 +318,7 @@ namespace Components this->buffer.enterCriticalSection(); Game::XFile* header = reinterpret_cast(this->buffer.data()); header->size = this->buffer.length() - sizeof(Game::XFile); // Write correct data size - header->externalSize = 0;//this->externalSize; // This actually stores how much external data has to be loaded. It's used to calculate the loadscreen progress + header->externalSize = this->externalSize; // This actually stores how much external data has to be loaded. It's used to calculate the loadscreen progress // Write stream sizes for (int i = 0; i < Game::MAX_XFILE_COUNT; ++i) @@ -486,6 +488,25 @@ namespace Components return AssetTrace; } + int ZoneBuilder::StoreTexture(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image) + { + size_t size = 16 + (*loadDef)->resourceSize; + void* data = ZoneBuilder::MemAllocator.allocate(size); + std::memcpy(data, *loadDef, size); + + image->loadDef = reinterpret_cast(data); + + return 0; + } + + void ZoneBuilder::ReleaseTexture(Game::XAssetHeader header) + { + if (header.image && header.image->loadDef) + { + ZoneBuilder::MemAllocator.free(header.image->loadDef); + } + } + ZoneBuilder::ZoneBuilder() { AssertSize(Game::XFileHeader, 21); @@ -497,7 +518,13 @@ namespace Components if (ZoneBuilder::IsEnabled()) { // Prevent loading textures (preserves loaddef) - Utils::Hook::Set(0x51F4E0, 0xC3); + //Utils::Hook::Set(Game::Load_Texture, 0xC3); + + // Store the loaddef + Utils::Hook(Game::Load_Texture, StoreTexture, HOOK_JUMP).install()->quick(); + + // Release the loaddef + Game::DB_ReleaseXAssetHandlers[Game::XAssetType::ASSET_TYPE_IMAGE] = ZoneBuilder::ReleaseTexture; //r_loadForrenderer = 0 Utils::Hook::Set(0x519DDF, 0); @@ -620,4 +647,9 @@ namespace Components }); } } + + ZoneBuilder::~ZoneBuilder() + { + assert(ZoneBuilder::MemAllocator.empty()); + } } diff --git a/src/Components/Modules/ZoneBuilder.hpp b/src/Components/Modules/ZoneBuilder.hpp index 207e6c24..7a164bc6 100644 --- a/src/Components/Modules/ZoneBuilder.hpp +++ b/src/Components/Modules/ZoneBuilder.hpp @@ -75,6 +75,7 @@ namespace Components }; ZoneBuilder(); + ~ZoneBuilder(); #if defined(DEBUG) || defined(FORCE_UNIT_TESTS) const char* getName() { return "ZoneBuilder"; }; @@ -87,5 +88,10 @@ namespace Components static void BeginAssetTrace(std::string zone); static std::vector> EndAssetTrace(); + + private: + static Utils::Memory::Allocator MemAllocator; + static int StoreTexture(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image); + static void ReleaseTexture(Game::XAssetHeader header); }; } diff --git a/src/Components/Modules/Zones.cpp b/src/Components/Modules/Zones.cpp index 34493123..ad64f4c6 100644 --- a/src/Components/Modules/Zones.cpp +++ b/src/Components/Modules/Zones.cpp @@ -1167,7 +1167,7 @@ namespace Components struct { Game::GfxImageLoadDef* texture; - char mapType; + Game::MapType mapType; char semantic; char category; char flags; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index b8611108..f369ed64 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -285,27 +285,41 @@ namespace Game int fileSizeForPicmip[4]; }; - struct GfxImageLoadDef // actually a IDirect3DTexture* but this is easier + struct __declspec(align(4)) GfxImageLoadDef { - char mipLevels; + char levelCount; char flags; - short dimensions[3]; - int format; // usually the compression Magic - int dataSize; // set to zero to load from IWD + __int16 dimensions[3]; + int format; + int resourceSize; char data[1]; }; + enum MapType : char + { + MAPTYPE_NONE = 0x0, + MAPTYPE_INVALID1 = 0x1, + MAPTYPE_INVALID2 = 0x2, + MAPTYPE_2D = 0x3, + MAPTYPE_3D = 0x4, + MAPTYPE_CUBE = 0x5, + MAPTYPE_COUNT = 0x6, + }; + struct GfxImage { union { GfxImageLoadDef* loadDef; #ifdef __cplusplus - IDirect3DTexture9* texture; + IDirect3DBaseTexture9 *basemap; + IDirect3DTexture9 *map; + IDirect3DVolumeTexture9 *volmap; + IDirect3DCubeTexture9 *cubemap; #endif }; - char mapType; // 5 is cube, 4 is 3d, 3 is 2d + MapType mapType; char semantic; char category; char flags;