More map progress, add dumpmap command.

SE2Dev wants us to keep that code for us, so only in debug mode!
This commit is contained in:
momo5502 2016-10-08 20:51:00 +02:00
parent f96973f439
commit e7910ac19f
6 changed files with 214 additions and 32 deletions

View File

@ -132,6 +132,11 @@ namespace Components
}
}
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);
}
if (Flags::HasFlag("entries"))
{
OutputDebugStringA(Utils::String::VA("%s: %d: %s\n", FastFiles::Current().data(), type, name));
@ -313,6 +318,7 @@ namespace Components
// Store empty assets
Utils::Hook(0x5BB6EC, AssetHandler::StoreEmptyAssetStub, HOOK_CALL).Install()->Quick();
// Log missing empty assets
QuickPatch::OnFrame([] ()
{
if (Game::Sys_IsDatabaseReady() && Game::Sys_IsDatabaseReady2() && !AssetHandler::EmptyAssets.empty())

View File

@ -180,6 +180,94 @@ namespace Components
return (Utils::String::StartsWith(entity, "dyn_") || Utils::String::StartsWith(entity, "node_") || Utils::String::StartsWith(entity, "actor_"));
}
#ifdef DEBUG
// Credit to SE2Dev, as we shouldn't share the code, keep that in debug mode!
void Maps::ExportMap(Game::GfxWorld* world)
{
Utils::Memory::Allocator allocator;
std::string mtl;
mtl.append("# SE2Dev MTL File: \n");
mtl.append("# Material Count: 0");
std::string map;
map.append("# Generated by SE2Dev's D3DBSP Tool\n");
map.append(fmt::sprintf("o %s\n", world->baseName));
map.append(fmt::sprintf("mtllib %s.mtl\n", world->baseName));
for (unsigned int i = 0; i < world->worldDraw.vertexCount; i++)
{
// Y/Z need to be inverted
float x = world->worldDraw.vd.vertices[i].xyz[0];
float y = world->worldDraw.vd.vertices[i].xyz[2];
float z = world->worldDraw.vd.vertices[i].xyz[1];
map.append(fmt::sprintf("v %.6f %.6f %.6f\n", x,y, z));
}
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]));
}
int materialCount = 0;
Game::Material** materials = allocator.AllocateArray<Game::Material*>(world->dpvs.staticSurfaceCount);
for (unsigned int i = 0; i < world->dpvs.staticSurfaceCount; i++)
{
bool isNewMat = true;
for (int j = 0; j < materialCount; j++)
{
if (world->dpvs.surfaces[i].material == materials[j])
{
isNewMat = false;
break;
}
}
if (isNewMat)
{
materials[materialCount++] = world->dpvs.surfaces[i].material;
}
}
for (int m = 0; m < materialCount; m++)
{
std::string name = materials[m]->name;
auto pos = name.find_last_of("/");
if (pos != std::string::npos)
{
name = name.substr(pos + 1);
}
map.append(fmt::sprintf("usemtl %s\n", name.data()));
map.append("s off\n");
for (unsigned int i = 0; i < world->dpvs.staticSurfaceCount; i++)
{
if (world->dpvs.surfaces[i].material != materials[m])
continue;
int vertOffset = world->dpvs.surfaces[i].tris.firstVertex + 1;//+1 cus obj starts at 1
int indexOffset = world->dpvs.surfaces[i].tris.baseIndex;
for (unsigned short j = 0; j < world->dpvs.surfaces[i].tris.triCount; j++)
{
int a = world->worldDraw.indices[indexOffset + j * 3 + 0] + vertOffset;
int b = world->worldDraw.indices[indexOffset + j * 3 + 1] + vertOffset;
int c = world->worldDraw.indices[indexOffset + j * 3 + 2] + vertOffset;
map.append(fmt::sprintf("f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c));
}
}
}
Utils::IO::WriteFile(fmt::sprintf("raw/mapdump/%s.mtl", world->baseName), mtl);
Utils::IO::WriteFile(fmt::sprintf("raw/mapdump/%s.obj", world->baseName), map);
}
#endif
void Maps::ReallocateEntryPool()
{
Assert_Size(Game::XAssetEntry, 16);
@ -277,6 +365,29 @@ namespace Components
Maps::AddDependency("mp_cargoship_sh", "iw4x_dependencies_mp");
Maps::AddDependency("mp_firingrange", "iw4x_dependencies_mp");
Maps::AddDependency("mp_shipment_long", "iw4x_dependencies_mp");
#ifdef DEBUG
Command::Add("dumpmap", [] (Command::Params)
{
Game::GfxWorld* world = nullptr;
Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_GFX_MAP, [] (Game::XAssetHeader header, void* world)
{
*reinterpret_cast<Game::GfxWorld**>(world) = header.gfxMap;
}, &world, false);
if (world)
{
Maps::ExportMap(world);
Logger::Print("Map '%s' exported!\n", world->baseName);
}
else
{
Logger::Print("No map loaded, unable to dump anything!\n");
}
});
#endif
}
Maps::~Maps()

View File

@ -26,6 +26,10 @@ namespace Components
static int IgnoreEntityStub(const char* entity);
#ifdef DEBUG
static void ExportMap(Game::GfxWorld* world);
#endif
void ReallocateEntryPool();
};
}

View File

@ -1136,8 +1136,8 @@ namespace Components
struct material339_s
{
char drawSurfBegin[4]; // Probably wrong
int surfaceTypeBits;
char drawSurfBegin[8]; // 4
//int surfaceTypeBits;
const char *name;
char drawSurf[6];
char gameFlags;
@ -1163,20 +1163,16 @@ namespace Components
material->gameFlags = material359.gameFlags;
// Probably wrong
material->surfaceTypeBits = material359.surfaceTypeBits;
material->surfaceTypeBits = 0;//material359.surfaceTypeBits;
// Pretty sure that's wrong
memcpy(material->drawSurf, material359.drawSurfBegin, 4);
// Actually, it's not
memcpy(material->drawSurf, material359.drawSurfBegin, 8);
material->drawSurf[4] = 0;
material->drawSurf[5] = 0;
material->drawSurf[6] = 0;
material->drawSurf[7] = material359.drawSurf[0];
material->drawSurf[8] = material359.drawSurf[1];
material->drawSurf[9] = material359.drawSurf[2];
material->drawSurf[10] = material359.drawSurf[3];
material->drawSurf[11] = material359.drawSurf[4];
material->drawSurf[8] = material359.drawSurf[0];
material->drawSurf[9] = material359.drawSurf[1];
material->drawSurf[10] = material359.drawSurf[2];
material->drawSurf[11] = material359.drawSurf[3];
return result;
}
@ -1256,6 +1252,9 @@ namespace Components
// Change block for image load defs
Utils::Hook::Set<BYTE>(0x4D3224, ((Zones::ZoneVersion >= 332) ? 3 : 0));
// This is needed if we want the original lightning on cargoship_sh, but original maps are darker
//Utils::Hook::Set<BYTE>(0x525333, 61);
if (patch)
{
Zones::LoadFxElemDefArrayHook.Install();

View File

@ -2464,6 +2464,7 @@ namespace Game
{
float mins[3];
float maxs[3];
int pad;
unsigned __int16 childCount;
unsigned __int16 surfaceCount;
unsigned __int16 startSurfIndex;
@ -2507,7 +2508,7 @@ namespace Game
char lightmapIndex;
char reflectionProbeIndex;
char primaryLightIndex;
bool castsSunShadow;
char castsSunShadow;
};
struct GfxCullGroup
@ -2537,13 +2538,14 @@ namespace Game
unsigned int staticSurfaceCount;
unsigned int litSurfsBegin;
unsigned int litSurfsEnd;
char unknown1[0x20];
char unknown1[0x24];
char *smodelVisData[3];
char *surfaceVisData[3];
unsigned __int16 *sortedSurfIndex;
GfxStaticModelInst *smodelInsts;
GfxSurface *surfaces;
GfxCullGroup *cullGroups;
GfxCullGroup *cullGroups; // actually GfxSurfaceBounds (24), but not important right now
GfxStaticModelDrawInst *smodelDrawInsts;
GfxDrawSurf *surfaceMaterials;
unsigned int *surfaceCastsSunShadow;
@ -2757,18 +2759,16 @@ namespace Game
GfxWorldVertexLayerData vld;
int indexCount;
unsigned __int16 *indices;
void/*IDirect3DIndexBuffer9*/* indexBuffer;
};
struct unknownGfxWorldStruct2
struct GfxSky
{
int unknownCount;
int * unknownArray;
GfxImage * unknownImage;
int unknown;
int skySurfCount;
int * skyStartSurfs;
GfxImage * skyImage;
int skySamplerState;
};
// That shit is wrong!
struct GfxWorld
{
const char *name;
@ -2776,12 +2776,12 @@ namespace Game
int planeCount;
int nodeCount;
int unknown2;
unsigned int unknownCount1;
unknownGfxWorldStruct2 * unknownStructs1; //Count = unknownCount1;
unsigned int skyCount;
GfxSky* skies;
char unknown1[0x18];
GfxWorldDpvsPlanes dpvsPlanes; //The following rely on the count in this
char *unknown4;
GfxAabbTree *aabbTree;
GfxAabbTree *aabbTree; // Actually GfxCellTree
GfxCell *cells;
GfxWorldDraw worldDraw;
GfxLightGrid lightGrid;
@ -2801,17 +2801,73 @@ namespace Game
char *primaryLightForModelDynEnt;
GfxShadowGeometry *shadowGeom;
GfxLightRegion *lightRegion;
char pad[68];
GfxWorldDpvsStatic dpvs;
GfxWorldDpvsDynamic dpvsDyn;
unsigned int unknownCount3;
char * unknown3; //Size = unknownCount2 * 0x38
char pad2[4];
unsigned int heroOnlyLightCount;
char * heroOnlyLight;
int unknown5;
};
struct GfxWorld_new
{
const char *name;
const char *baseName;
int planeCount;
int nodeCount;
int unknown2;
unsigned int skyCount;
GfxSky* skies;
char unknown1[0x18];
GfxWorldDpvsPlanes dpvsPlanes; //The following rely on the count in this
char *unknown4;
GfxAabbTree *aabbTree; // Actually GfxCellTree
GfxCell *cells;
GfxWorldDraw worldDraw;
GfxLightGrid lightGrid;
int modelCount;
GfxBrushModel *models;
float mins[3];
float maxs[3];
unsigned int checksum;
int materialMemoryCount;
MaterialMemory *materialMemory;
sunflare_t sun;
char whatIsThat[968];
unsigned int *cellCasterBits[2];
GfxSceneDynModel *sceneDynModel;
GfxSceneDynBrush *sceneDynBrush;
unsigned int *primaryLightEntityShadowVis;
unsigned int *primaryLightDynEntShadowVis[2];
char *primaryLightForModelDynEnt;
GfxShadowGeometry *shadowGeom;
GfxLightRegion *lightRegion;
char pad[68];
GfxWorldDpvsStatic dpvs;
GfxWorldDpvsDynamic dpvsDyn;
char pad2[4];
unsigned int heroOnlyLightCount;
char * heroOnlyLight;
int unknown5;
};
#pragma pack(pop)
#ifdef __cplusplus
static_assert(offsetof(GfxWorld, worldDraw) == 80, "");
#endif
struct rgpStruct
{
int pad[2117];
GfxWorld* world;
};
union XAssetHeader
{

View File

@ -39,6 +39,12 @@
#include <future>
#include <queue>
// Usefull for debugging
template <size_t S> class Sizer { };
#define BindNum(x, y) Sizer<x> y;
#define SizeOf(x, y) BindNum(sizeof(x), y)
#define OffsetOf(x, y, z) BindNum(offsetof(x, y), z)
// Submodules
// Ignore the warnings, it's no our code!
#pragma warning(push)