[ZoneBuilder] Correctly write GfxImages

This commit is contained in:
momo5502 2016-12-22 02:48:00 +01:00
parent 33754f40aa
commit 896c3b7068
6 changed files with 71 additions and 21 deletions

View File

@ -40,7 +40,7 @@ namespace Assets
const Game::GfxImageFileHeader* iwiHeader = reinterpret_cast<const Game::GfxImageFileHeader*>(iwiBuffer.data()); const Game::GfxImageFileHeader* iwiHeader = reinterpret_cast<const Game::GfxImageFileHeader*>(iwiBuffer.data());
image->mapType = 3; image->mapType = Game::MAPTYPE_2D;
image->dataLen1 = iwiHeader->fileSizeForPicmip[0] - 32; image->dataLen1 = iwiHeader->fileSizeForPicmip[0] - 32;
image->dataLen2 = iwiHeader->fileSizeForPicmip[0] - 32; image->dataLen2 = iwiHeader->fileSizeForPicmip[0] - 32;
@ -52,7 +52,7 @@ namespace Assets
std::memcpy(image->loadDef->dimensions, iwiHeader->dimensions, 6); std::memcpy(image->loadDef->dimensions, iwiHeader->dimensions, 6);
image->loadDef->flags = 0; image->loadDef->flags = 0;
image->loadDef->mipLevels = 0; image->loadDef->levelCount = 0;
switch (iwiHeader->format) switch (iwiHeader->format)
{ {
@ -93,6 +93,7 @@ namespace Assets
void IGfxImage::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) void IGfxImage::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{ {
AssertSize(Game::GfxImage, 32); AssertSize(Game::GfxImage, 32);
AssertSize(Game::MapType, 1);
Utils::Stream* buffer = builder->getBuffer(); Utils::Stream* buffer = builder->getBuffer();
Game::GfxImage* asset = header.image; Game::GfxImage* asset = header.image;
@ -109,21 +110,18 @@ namespace Assets
buffer->pushBlock(Game::XFILE_BLOCK_TEMP); buffer->pushBlock(Game::XFILE_BLOCK_TEMP);
if (asset->texture) if (asset->loadDef)
{ {
buffer->align(Utils::Stream::ALIGN_4); buffer->align(Utils::Stream::ALIGN_4);
Game::GfxImageLoadDef* destTexture = buffer->dest<Game::GfxImageLoadDef>(); Game::GfxImageLoadDef* destTexture = buffer->dest<Game::GfxImageLoadDef>();
buffer->save(asset->loadDef, 16); buffer->save(asset->loadDef, 16, 1);
builder->incrementExternalSize(asset->loadDef->dataSize); builder->incrementExternalSize(asset->loadDef->resourceSize);
// Zero the size! if (destTexture->resourceSize > 0)
destTexture->dataSize = 0;
if (destTexture->dataSize > 0)
{ {
buffer->save(asset->loadDef->data, asset->loadDef->dataSize); buffer->save(asset->loadDef->data, asset->loadDef->resourceSize);
} }
Utils::Stream::ClearPointer(&dest->loadDef); Utils::Stream::ClearPointer(&dest->loadDef);

View File

@ -377,7 +377,7 @@ namespace Components
} }
std::string _name = fmt::sprintf("raw/mapdump/%s/textures/%s.png", world->baseName, image->name); 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(fmt::sprintf("\nnewmtl %s\n", name.data()));
mtl.append("Ka 1.0000 1.0000 1.0000\n"); mtl.append("Ka 1.0000 1.0000 1.0000\n");

View File

@ -2,6 +2,8 @@
namespace Components namespace Components
{ {
Utils::Memory::Allocator ZoneBuilder::MemAllocator;
std::string ZoneBuilder::TraceZone; std::string ZoneBuilder::TraceZone;
std::vector<std::pair<Game::XAssetType, std::string>> ZoneBuilder::TraceAssets; std::vector<std::pair<Game::XAssetType, std::string>> ZoneBuilder::TraceAssets;
@ -316,7 +318,7 @@ namespace Components
this->buffer.enterCriticalSection(); this->buffer.enterCriticalSection();
Game::XFile* header = reinterpret_cast<Game::XFile*>(this->buffer.data()); Game::XFile* header = reinterpret_cast<Game::XFile*>(this->buffer.data());
header->size = this->buffer.length() - sizeof(Game::XFile); // Write correct data size 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 // Write stream sizes
for (int i = 0; i < Game::MAX_XFILE_COUNT; ++i) for (int i = 0; i < Game::MAX_XFILE_COUNT; ++i)
@ -486,6 +488,25 @@ namespace Components
return AssetTrace; 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<Game::GfxImageLoadDef *>(data);
return 0;
}
void ZoneBuilder::ReleaseTexture(Game::XAssetHeader header)
{
if (header.image && header.image->loadDef)
{
ZoneBuilder::MemAllocator.free(header.image->loadDef);
}
}
ZoneBuilder::ZoneBuilder() ZoneBuilder::ZoneBuilder()
{ {
AssertSize(Game::XFileHeader, 21); AssertSize(Game::XFileHeader, 21);
@ -497,7 +518,13 @@ namespace Components
if (ZoneBuilder::IsEnabled()) if (ZoneBuilder::IsEnabled())
{ {
// Prevent loading textures (preserves loaddef) // Prevent loading textures (preserves loaddef)
Utils::Hook::Set<BYTE>(0x51F4E0, 0xC3); //Utils::Hook::Set<BYTE>(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 //r_loadForrenderer = 0
Utils::Hook::Set<BYTE>(0x519DDF, 0); Utils::Hook::Set<BYTE>(0x519DDF, 0);
@ -620,4 +647,9 @@ namespace Components
}); });
} }
} }
ZoneBuilder::~ZoneBuilder()
{
assert(ZoneBuilder::MemAllocator.empty());
}
} }

View File

@ -75,6 +75,7 @@ namespace Components
}; };
ZoneBuilder(); ZoneBuilder();
~ZoneBuilder();
#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) #if defined(DEBUG) || defined(FORCE_UNIT_TESTS)
const char* getName() { return "ZoneBuilder"; }; const char* getName() { return "ZoneBuilder"; };
@ -87,5 +88,10 @@ namespace Components
static void BeginAssetTrace(std::string zone); static void BeginAssetTrace(std::string zone);
static std::vector<std::pair<Game::XAssetType, std::string>> EndAssetTrace(); static std::vector<std::pair<Game::XAssetType, std::string>> EndAssetTrace();
private:
static Utils::Memory::Allocator MemAllocator;
static int StoreTexture(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image);
static void ReleaseTexture(Game::XAssetHeader header);
}; };
} }

View File

@ -1167,7 +1167,7 @@ namespace Components
struct struct
{ {
Game::GfxImageLoadDef* texture; Game::GfxImageLoadDef* texture;
char mapType; Game::MapType mapType;
char semantic; char semantic;
char category; char category;
char flags; char flags;

View File

@ -285,27 +285,41 @@ namespace Game
int fileSizeForPicmip[4]; int fileSizeForPicmip[4];
}; };
struct GfxImageLoadDef // actually a IDirect3DTexture* but this is easier struct __declspec(align(4)) GfxImageLoadDef
{ {
char mipLevels; char levelCount;
char flags; char flags;
short dimensions[3]; __int16 dimensions[3];
int format; // usually the compression Magic int format;
int dataSize; // set to zero to load from IWD int resourceSize;
char data[1]; 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 struct GfxImage
{ {
union union
{ {
GfxImageLoadDef* loadDef; GfxImageLoadDef* loadDef;
#ifdef __cplusplus #ifdef __cplusplus
IDirect3DTexture9* texture; IDirect3DBaseTexture9 *basemap;
IDirect3DTexture9 *map;
IDirect3DVolumeTexture9 *volmap;
IDirect3DCubeTexture9 *cubemap;
#endif #endif
}; };
char mapType; // 5 is cube, 4 is 3d, 3 is 2d MapType mapType;
char semantic; char semantic;
char category; char category;
char flags; char flags;