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:
parent
f96973f439
commit
e7910ac19f
@ -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())
|
||||
|
@ -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()
|
||||
|
@ -26,6 +26,10 @@ namespace Components
|
||||
|
||||
static int IgnoreEntityStub(const char* entity);
|
||||
|
||||
#ifdef DEBUG
|
||||
static void ExportMap(Game::GfxWorld* world);
|
||||
#endif
|
||||
|
||||
void ReallocateEntryPool();
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user