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"))
|
if (Flags::HasFlag("entries"))
|
||||||
{
|
{
|
||||||
OutputDebugStringA(Utils::String::VA("%s: %d: %s\n", FastFiles::Current().data(), type, name));
|
OutputDebugStringA(Utils::String::VA("%s: %d: %s\n", FastFiles::Current().data(), type, name));
|
||||||
@ -313,6 +318,7 @@ namespace Components
|
|||||||
// Store empty assets
|
// Store empty assets
|
||||||
Utils::Hook(0x5BB6EC, AssetHandler::StoreEmptyAssetStub, HOOK_CALL).Install()->Quick();
|
Utils::Hook(0x5BB6EC, AssetHandler::StoreEmptyAssetStub, HOOK_CALL).Install()->Quick();
|
||||||
|
|
||||||
|
// Log missing empty assets
|
||||||
QuickPatch::OnFrame([] ()
|
QuickPatch::OnFrame([] ()
|
||||||
{
|
{
|
||||||
if (Game::Sys_IsDatabaseReady() && Game::Sys_IsDatabaseReady2() && !AssetHandler::EmptyAssets.empty())
|
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_"));
|
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()
|
void Maps::ReallocateEntryPool()
|
||||||
{
|
{
|
||||||
Assert_Size(Game::XAssetEntry, 16);
|
Assert_Size(Game::XAssetEntry, 16);
|
||||||
@ -277,6 +365,29 @@ 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");
|
||||||
|
|
||||||
|
#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()
|
Maps::~Maps()
|
||||||
|
@ -26,6 +26,10 @@ namespace Components
|
|||||||
|
|
||||||
static int IgnoreEntityStub(const char* entity);
|
static int IgnoreEntityStub(const char* entity);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static void ExportMap(Game::GfxWorld* world);
|
||||||
|
#endif
|
||||||
|
|
||||||
void ReallocateEntryPool();
|
void ReallocateEntryPool();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1136,8 +1136,8 @@ namespace Components
|
|||||||
|
|
||||||
struct material339_s
|
struct material339_s
|
||||||
{
|
{
|
||||||
char drawSurfBegin[4]; // Probably wrong
|
char drawSurfBegin[8]; // 4
|
||||||
int surfaceTypeBits;
|
//int surfaceTypeBits;
|
||||||
const char *name;
|
const char *name;
|
||||||
char drawSurf[6];
|
char drawSurf[6];
|
||||||
char gameFlags;
|
char gameFlags;
|
||||||
@ -1163,20 +1163,16 @@ namespace Components
|
|||||||
material->gameFlags = material359.gameFlags;
|
material->gameFlags = material359.gameFlags;
|
||||||
|
|
||||||
// Probably wrong
|
// Probably wrong
|
||||||
material->surfaceTypeBits = material359.surfaceTypeBits;
|
material->surfaceTypeBits = 0;//material359.surfaceTypeBits;
|
||||||
|
|
||||||
// Pretty sure that's wrong
|
// 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[8] = material359.drawSurf[0];
|
||||||
material->drawSurf[5] = 0;
|
material->drawSurf[9] = material359.drawSurf[1];
|
||||||
material->drawSurf[6] = 0;
|
material->drawSurf[10] = material359.drawSurf[2];
|
||||||
|
material->drawSurf[11] = material359.drawSurf[3];
|
||||||
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];
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1256,6 +1252,9 @@ namespace Components
|
|||||||
// Change block for image load defs
|
// Change block for image load defs
|
||||||
Utils::Hook::Set<BYTE>(0x4D3224, ((Zones::ZoneVersion >= 332) ? 3 : 0));
|
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)
|
if (patch)
|
||||||
{
|
{
|
||||||
Zones::LoadFxElemDefArrayHook.Install();
|
Zones::LoadFxElemDefArrayHook.Install();
|
||||||
|
@ -2464,6 +2464,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
float mins[3];
|
float mins[3];
|
||||||
float maxs[3];
|
float maxs[3];
|
||||||
|
int pad;
|
||||||
unsigned __int16 childCount;
|
unsigned __int16 childCount;
|
||||||
unsigned __int16 surfaceCount;
|
unsigned __int16 surfaceCount;
|
||||||
unsigned __int16 startSurfIndex;
|
unsigned __int16 startSurfIndex;
|
||||||
@ -2507,7 +2508,7 @@ namespace Game
|
|||||||
char lightmapIndex;
|
char lightmapIndex;
|
||||||
char reflectionProbeIndex;
|
char reflectionProbeIndex;
|
||||||
char primaryLightIndex;
|
char primaryLightIndex;
|
||||||
bool castsSunShadow;
|
char castsSunShadow;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GfxCullGroup
|
struct GfxCullGroup
|
||||||
@ -2537,13 +2538,14 @@ namespace Game
|
|||||||
unsigned int staticSurfaceCount;
|
unsigned int staticSurfaceCount;
|
||||||
unsigned int litSurfsBegin;
|
unsigned int litSurfsBegin;
|
||||||
unsigned int litSurfsEnd;
|
unsigned int litSurfsEnd;
|
||||||
char unknown1[0x20];
|
char unknown1[0x24];
|
||||||
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;
|
GfxCullGroup *cullGroups; // actually GfxSurfaceBounds (24), but not important right now
|
||||||
GfxStaticModelDrawInst *smodelDrawInsts;
|
GfxStaticModelDrawInst *smodelDrawInsts;
|
||||||
GfxDrawSurf *surfaceMaterials;
|
GfxDrawSurf *surfaceMaterials;
|
||||||
unsigned int *surfaceCastsSunShadow;
|
unsigned int *surfaceCastsSunShadow;
|
||||||
@ -2757,18 +2759,16 @@ namespace Game
|
|||||||
GfxWorldVertexLayerData vld;
|
GfxWorldVertexLayerData vld;
|
||||||
int indexCount;
|
int indexCount;
|
||||||
unsigned __int16 *indices;
|
unsigned __int16 *indices;
|
||||||
void/*IDirect3DIndexBuffer9*/* indexBuffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct unknownGfxWorldStruct2
|
struct GfxSky
|
||||||
{
|
{
|
||||||
int unknownCount;
|
int skySurfCount;
|
||||||
int * unknownArray;
|
int * skyStartSurfs;
|
||||||
GfxImage * unknownImage;
|
GfxImage * skyImage;
|
||||||
int unknown;
|
int skySamplerState;
|
||||||
};
|
};
|
||||||
|
|
||||||
// That shit is wrong!
|
|
||||||
struct GfxWorld
|
struct GfxWorld
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -2776,12 +2776,12 @@ namespace Game
|
|||||||
int planeCount;
|
int planeCount;
|
||||||
int nodeCount;
|
int nodeCount;
|
||||||
int unknown2;
|
int unknown2;
|
||||||
unsigned int unknownCount1;
|
unsigned int skyCount;
|
||||||
unknownGfxWorldStruct2 * unknownStructs1; //Count = unknownCount1;
|
GfxSky* skies;
|
||||||
char unknown1[0x18];
|
char unknown1[0x18];
|
||||||
GfxWorldDpvsPlanes dpvsPlanes; //The following rely on the count in this
|
GfxWorldDpvsPlanes dpvsPlanes; //The following rely on the count in this
|
||||||
char *unknown4;
|
char *unknown4;
|
||||||
GfxAabbTree *aabbTree;
|
GfxAabbTree *aabbTree; // Actually GfxCellTree
|
||||||
GfxCell *cells;
|
GfxCell *cells;
|
||||||
GfxWorldDraw worldDraw;
|
GfxWorldDraw worldDraw;
|
||||||
GfxLightGrid lightGrid;
|
GfxLightGrid lightGrid;
|
||||||
@ -2801,17 +2801,73 @@ namespace Game
|
|||||||
char *primaryLightForModelDynEnt;
|
char *primaryLightForModelDynEnt;
|
||||||
GfxShadowGeometry *shadowGeom;
|
GfxShadowGeometry *shadowGeom;
|
||||||
GfxLightRegion *lightRegion;
|
GfxLightRegion *lightRegion;
|
||||||
|
|
||||||
|
char pad[68];
|
||||||
|
|
||||||
GfxWorldDpvsStatic dpvs;
|
GfxWorldDpvsStatic dpvs;
|
||||||
GfxWorldDpvsDynamic dpvsDyn;
|
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;
|
int unknown5;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
struct rgpStruct
|
||||||
static_assert(offsetof(GfxWorld, worldDraw) == 80, "");
|
{
|
||||||
#endif
|
int pad[2117];
|
||||||
|
GfxWorld* world;
|
||||||
|
};
|
||||||
|
|
||||||
union XAssetHeader
|
union XAssetHeader
|
||||||
{
|
{
|
||||||
|
@ -39,6 +39,12 @@
|
|||||||
#include <future>
|
#include <future>
|
||||||
#include <queue>
|
#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
|
// Submodules
|
||||||
// Ignore the warnings, it's no our code!
|
// Ignore the warnings, it's no our code!
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user