Fix techniques (ZoneBuilder) and fully dump gfxworlds with enable-dxsdk flag

This commit is contained in:
momo5502 2016-10-09 12:02:17 +02:00
parent bec37fb830
commit ad18adc187
11 changed files with 96 additions and 25 deletions

View File

@ -21,3 +21,4 @@
| `--disable-node-log` | Disable debugging messages for Nodes in Debug builds. | | `--disable-node-log` | Disable debugging messages for Nodes in Debug builds. |
| `--disable-base128` | Disable base128 encoding for minidumps. | | `--disable-base128` | Disable base128 encoding for minidumps. |
| `--no-new-structure` | Do not use new virtual path structure (separating headers and source files). | | `--no-new-structure` | Do not use new virtual path structure (separating headers and source files). |
| `--enable-dxsdk` | Enable DirectX SDK (required for GfxMap exporting). |

View File

@ -83,6 +83,11 @@ newoption {
description = "Disable base128 encoding for minidumps." description = "Disable base128 encoding for minidumps."
} }
newoption {
trigger = "enable-dxsdk",
description = "Enable DirectX SDK (required for GfxMap exporting)."
}
newaction { newaction {
trigger = "version", trigger = "version",
description = "Returns the version string for the current commit of the source code.", description = "Returns the version string for the current commit of the source code.",
@ -334,6 +339,12 @@ workspace "iw4x"
defines { "DISABLE_BASE128" } defines { "DISABLE_BASE128" }
end end
if _OPTIONS["enable-dxsdk"] then
defines { "ENABLE_DXSDK" }
includedirs { "%DXSDK_DIR%Include" }
libdirs { "%DXSDK_DIR%Lib/x86" }
end
-- Pre-compiled header -- Pre-compiled header
pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives
pchsource "src/STDInclude.cpp" -- real path pchsource "src/STDInclude.cpp" -- real path

View File

@ -134,7 +134,7 @@ namespace Components
if (type == 5 && name == "wc/codo_ui_viewer_black_decal3"s) if (type == 5 && name == "wc/codo_ui_viewer_black_decal3"s)
{ {
std::memcpy(&asset->material->gameFlags, &(*reinterpret_cast<Game::Material**>(0xA7FFE8))->gameFlags, sizeof(Game::Material) - 4); asset->material->sortKey = 0xE;
} }
if (Flags::HasFlag("entries")) if (Flags::HasFlag("entries"))

View File

@ -19,8 +19,8 @@ namespace Assets
image->category = 0; image->category = 0;
image->cardMemory = 0; image->cardMemory = 0;
image->texture = builder->GetAllocator()->Allocate<Game::GfxImageLoadDef>(); image->loadDef = builder->GetAllocator()->Allocate<Game::GfxImageLoadDef>();
if (!image->texture) if (!image->loadDef)
{ {
Components::Logger::Error("Failed to allocate GfxImageLoadDef structure!"); Components::Logger::Error("Failed to allocate GfxImageLoadDef structure!");
return; return;
@ -48,39 +48,39 @@ namespace Assets
return; return;
} }
std::memcpy(image->texture->dimensions, iwiHeader->dimensions, 6); std::memcpy(image->loadDef->dimensions, iwiHeader->dimensions, 6);
image->texture->flags = 0; image->loadDef->flags = 0;
image->texture->mipLevels = 0; image->loadDef->mipLevels = 0;
switch (iwiHeader->format) switch (iwiHeader->format)
{ {
case Game::IWI_COMPRESSION::IWI_ARGB: case Game::IWI_COMPRESSION::IWI_ARGB:
{ {
image->texture->format = 21; image->loadDef->format = 21;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_RGB8: case Game::IWI_COMPRESSION::IWI_RGB8:
{ {
image->texture->format = 20; image->loadDef->format = 20;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_DXT1: case Game::IWI_COMPRESSION::IWI_DXT1:
{ {
image->texture->format = 0x31545844; image->loadDef->format = 0x31545844;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_DXT3: case Game::IWI_COMPRESSION::IWI_DXT3:
{ {
image->texture->format = 0x33545844; image->loadDef->format = 0x33545844;
break; break;
} }
case Game::IWI_COMPRESSION::IWI_DXT5: case Game::IWI_COMPRESSION::IWI_DXT5:
{ {
image->texture->format = 0x35545844; image->loadDef->format = 0x35545844;
break; break;
} }
} }

View File

@ -74,13 +74,15 @@ namespace Assets
buffer->Save(technique, 8); buffer->Save(technique, 8);
// Save_MaterialPassArray // Save_MaterialPassArray
Game::MaterialPass* destPasses = buffer->Dest<Game::MaterialPass>();
buffer->SaveArray(technique->passes, technique->numPasses);
for (short j = 0; j < technique->numPasses; ++j) for (short j = 0; j < technique->numPasses; ++j)
{ {
Assert_Size(Game::MaterialPass, 20); Assert_Size(Game::MaterialPass, 20);
Game::MaterialPass* destPass = buffer->Dest<Game::MaterialPass>(); Game::MaterialPass* destPass = &destPasses[j];
Game::MaterialPass* pass = &technique->passes[j]; Game::MaterialPass* pass = &technique->passes[j];
buffer->Save(pass);
if (pass->vertexDecl) if (pass->vertexDecl)
{ {

View File

@ -180,21 +180,26 @@ namespace Components
return (Utils::String::StartsWith(entity, "dyn_") || Utils::String::StartsWith(entity, "node_") || Utils::String::StartsWith(entity, "actor_")); return (Utils::String::StartsWith(entity, "dyn_") || Utils::String::StartsWith(entity, "node_") || Utils::String::StartsWith(entity, "actor_"));
} }
#ifdef DEBUG #if defined(DEBUG) && defined(ENABLE_DXSDK)
// Credit to SE2Dev, as we shouldn't share the code, keep that in debug mode! // Credit to SE2Dev, as we shouldn't share the code, keep that in debug mode!
void Maps::ExportMap(Game::GfxWorld* world) void Maps::ExportMap(Game::GfxWorld* world)
{ {
Utils::Memory::Allocator allocator; Utils::Memory::Allocator allocator;
if (!world) return;
Logger::Print("Exporting '%s'...\n", world->baseName);
std::string mtl; std::string mtl;
mtl.append("# SE2Dev MTL File: \n"); mtl.append("# IW4x MTL File\n");
mtl.append("# Material Count: 0"); mtl.append("# Credit to SE2Dev for his D3DBSP Tool\n");
std::string map; std::string map;
map.append("# Generated by SE2Dev's D3DBSP Tool\n"); map.append("# Generated by IW4x\n");
map.append("# Credit to SE2Dev for his D3DBSP Tool\n");
map.append(fmt::sprintf("o %s\n", world->baseName)); map.append(fmt::sprintf("o %s\n", world->baseName));
map.append(fmt::sprintf("mtllib %s.mtl\n", world->baseName)); map.append(fmt::sprintf("mtllib %s.mtl\n", world->baseName));
Logger::Print("Writing vertices...\n");
for (unsigned int i = 0; i < world->worldDraw.vertexCount; i++) for (unsigned int i = 0; i < world->worldDraw.vertexCount; i++)
{ {
// Y/Z need to be inverted // Y/Z need to be inverted
@ -205,11 +210,13 @@ namespace Components
map.append(fmt::sprintf("v %.6f %.6f %.6f\n", x,y, z)); map.append(fmt::sprintf("v %.6f %.6f %.6f\n", x,y, z));
} }
Logger::Print("Writing texture coordinates...\n");
for (unsigned int i = 0; i < world->worldDraw.vertexCount; i++) for (unsigned int i = 0; i < world->worldDraw.vertexCount; i++)
{ {
map.append(fmt::sprintf("vt %.6f %.6f\n", world->worldDraw.vd.vertices[i].texCoord[0], world->worldDraw.vd.vertices[i].texCoord[1])); map.append(fmt::sprintf("vt %.6f %.6f\n", world->worldDraw.vd.vertices[i].texCoord[0], world->worldDraw.vd.vertices[i].texCoord[1]));
} }
Logger::Print("Searching materials...\n");
int materialCount = 0; int materialCount = 0;
Game::Material** materials = allocator.AllocateArray<Game::Material*>(world->dpvs.staticSurfaceCount); Game::Material** materials = allocator.AllocateArray<Game::Material*>(world->dpvs.staticSurfaceCount);
@ -232,6 +239,10 @@ namespace Components
} }
} }
Utils::IO::CreateDirectory(fmt::sprintf("raw/mapdump/%s/textures", world->baseName));
mtl.append(fmt::sprintf("# Material Count: %d\n", materialCount));
Logger::Print("Exporting materials and faces...\n");
for (int m = 0; m < materialCount; m++) for (int m = 0; m < materialCount; m++)
{ {
std::string name = materials[m]->name; std::string name = materials[m]->name;
@ -245,6 +256,29 @@ namespace Components
map.append(fmt::sprintf("usemtl %s\n", name.data())); map.append(fmt::sprintf("usemtl %s\n", name.data()));
map.append("s off\n"); map.append("s off\n");
Game::GfxImage* image = materials[m]->textureTable[0].info.image;
for (char l = 0; l < materials[m]->textureCount; ++l)
{
if (materials[m]->textureTable[l].nameStart == 'c')
{
if (materials[m]->textureTable[l].nameEnd == 'p')
{
image = materials[m]->textureTable[l].info.image; // Hopefully our colorMap
}
}
}
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);
mtl.append(fmt::sprintf("newmtl %s\n", name.data()));
mtl.append("Ka 1.0000 1.0000 1.0000\n");
mtl.append("Kd 1.0000 1.0000 1.0000\n");
mtl.append("illum 1\n");
mtl.append(fmt::sprintf("map_Ka textures/%s.png\n", image->name));
mtl.append(fmt::sprintf("map_Kd textures/%s.png\n", image->name));
for (unsigned int i = 0; i < world->dpvs.staticSurfaceCount; i++) for (unsigned int i = 0; i < world->dpvs.staticSurfaceCount; i++)
{ {
if (world->dpvs.surfaces[i].material != materials[m]) if (world->dpvs.surfaces[i].material != materials[m])
@ -263,8 +297,9 @@ namespace Components
} }
} }
Utils::IO::WriteFile(fmt::sprintf("raw/mapdump/%s.mtl", world->baseName), mtl); Logger::Print("Writing final files...\n");
Utils::IO::WriteFile(fmt::sprintf("raw/mapdump/%s.obj", world->baseName), map); Utils::IO::WriteFile(fmt::sprintf("raw/mapdump/%s/%s.mtl", world->baseName, world->baseName), mtl);
Utils::IO::WriteFile(fmt::sprintf("raw/mapdump/%s/%s.obj", world->baseName, world->baseName), map);
} }
#endif #endif
@ -365,12 +400,18 @@ namespace Components
Maps::AddDependency("mp_cargoship_sh", "iw4x_dependencies_mp"); Maps::AddDependency("mp_cargoship_sh", "iw4x_dependencies_mp");
Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp"); Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp");
Maps::AddDependency("mp_shipment_long", "iw4x_dependencies_mp"); Maps::AddDependency("mp_shipment_long", "iw4x_dependencies_mp");
Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp");
#ifdef DEBUG #if defined(DEBUG) && defined(ENABLE_DXSDK)
Command::Add("dumpmap", [] (Command::Params) Command::Add("dumpmap", [] (Command::Params)
{ {
Game::GfxWorld* world = nullptr; if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())
{
Logger::Print("DirectX needs to be enabled, please start a client to use this command!\n");
return;
}
Game::GfxWorld* world = nullptr;
Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_GFX_MAP, [] (Game::XAssetHeader header, void* world) Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_GFX_MAP, [] (Game::XAssetHeader header, void* world)
{ {
*reinterpret_cast<Game::GfxWorld**>(world) = header.gfxMap; *reinterpret_cast<Game::GfxWorld**>(world) = header.gfxMap;
@ -386,7 +427,6 @@ namespace Components
Logger::Print("No map loaded, unable to dump anything!\n"); Logger::Print("No map loaded, unable to dump anything!\n");
} }
}); });
#endif #endif
} }

View File

@ -26,7 +26,7 @@ namespace Components
static int IgnoreEntityStub(const char* entity); static int IgnoreEntityStub(const char* entity);
#ifdef DEBUG #if defined(DEBUG) && defined(ENABLE_DXSDK)
static void ExportMap(Game::GfxWorld* world); static void ExportMap(Game::GfxWorld* world);
#endif #endif

View File

@ -108,6 +108,8 @@ namespace Game
Load_XStringCustom_t Load_XStringCustom = (Load_XStringCustom_t)0x4E0DD0; Load_XStringCustom_t Load_XStringCustom = (Load_XStringCustom_t)0x4E0DD0;
Load_FxEffectDefHandle_t Load_FxEffectDefHandle = (Load_FxEffectDefHandle_t)0x4D9B90; Load_FxEffectDefHandle_t Load_FxEffectDefHandle = (Load_FxEffectDefHandle_t)0x4D9B90;
Load_FxElemDef_t Load_FxElemDef = (Load_FxElemDef_t)0x45AD90; Load_FxElemDef_t Load_FxElemDef = (Load_FxElemDef_t)0x45AD90;
Load_Texture_t Load_Texture = (Load_Texture_t)0x51F4E0;
Load_GfxTextureLoad_t Load_GfxTextureLoad = (Load_GfxTextureLoad_t)0x4D3210;
Load_SndAliasCustom_t Load_SndAliasCustom = (Load_SndAliasCustom_t)0x49B6B0; Load_SndAliasCustom_t Load_SndAliasCustom = (Load_SndAliasCustom_t)0x49B6B0;
Load_MaterialHandle_t Load_MaterialHandle = (Load_MaterialHandle_t)0x403960; Load_MaterialHandle_t Load_MaterialHandle = (Load_MaterialHandle_t)0x403960;
Load_PhysCollmapPtr_t Load_PhysCollmapPtr = (Load_PhysCollmapPtr_t)0x47E990; Load_PhysCollmapPtr_t Load_PhysCollmapPtr = (Load_PhysCollmapPtr_t)0x47E990;

View File

@ -260,6 +260,12 @@ namespace Game
typedef void(__cdecl *Load_FxElemDef_t)(bool atStreamStart); typedef void(__cdecl *Load_FxElemDef_t)(bool atStreamStart);
extern Load_FxElemDef_t Load_FxElemDef; extern Load_FxElemDef_t Load_FxElemDef;
typedef void(__cdecl *Load_GfxTextureLoad_t)(bool atStreamStart);
extern Load_GfxTextureLoad_t Load_GfxTextureLoad;
typedef int(__cdecl *Load_Texture_t)(GfxImageLoadDef **loadDef, GfxImage *image);
extern Load_Texture_t Load_Texture;
typedef void(__cdecl * Load_SndAliasCustom_t)(snd_alias_list_t** var); typedef void(__cdecl * Load_SndAliasCustom_t)(snd_alias_list_t** var);
extern Load_SndAliasCustom_t Load_SndAliasCustom; extern Load_SndAliasCustom_t Load_SndAliasCustom;

View File

@ -216,7 +216,12 @@ namespace Game
struct GfxImage struct GfxImage
{ {
GfxImageLoadDef * /*Direct3DTexture9**/ texture; union
{
GfxImageLoadDef* loadDef;
IDirect3DTexture9* texture;
};
char mapType; // 5 is cube, 4 is 3d, 3 is 2d char mapType; // 5 is cube, 4 is 3d, 3 is 2d
char semantic; char semantic;
char category; char category;
@ -2509,7 +2514,6 @@ namespace Game
char *smodelVisData[3]; char *smodelVisData[3];
char *surfaceVisData[3]; char *surfaceVisData[3];
unsigned __int16 *sortedSurfIndex; unsigned __int16 *sortedSurfIndex;
GfxStaticModelInst *smodelInsts; GfxStaticModelInst *smodelInsts;
GfxSurface *surfaces; GfxSurface *surfaces;
GfxCullGroup *cullGroups; // actually GfxSurfaceBounds (24), but not important right now GfxCullGroup *cullGroups; // actually GfxSurfaceBounds (24), but not important right now

View File

@ -39,6 +39,11 @@
#include <future> #include <future>
#include <queue> #include <queue>
#ifdef ENABLE_DXSDK
#include <D3dx9tex.h>
#pragma comment(lib, "D3dx9.lib")
#endif
// Usefull for debugging // Usefull for debugging
template <size_t S> class Sizer { }; template <size_t S> class Sizer { };
#define BindNum(x, y) Sizer<x> y; #define BindNum(x, y) Sizer<x> y;